ldb-samba: Reenable recursive search
[obnox/samba/samba-obnox.git] / source4 / dsdb / samdb / ldb_modules / util.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4
5    Copyright (C) Andrew Tridgell 2009
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
7    Copyright (C) Matthieu Patou <mat@matws.net> 2011
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "ldb.h"
25 #include "ldb_module.h"
26 #include "librpc/ndr/libndr.h"
27 #include "dsdb/samdb/ldb_modules/util.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "dsdb/common/util.h"
30 #include "libcli/security/security.h"
31
32 /*
33   search for attrs on one DN, in the modules below
34  */
35 int dsdb_module_search_dn(struct ldb_module *module,
36                           TALLOC_CTX *mem_ctx,
37                           struct ldb_result **_res,
38                           struct ldb_dn *basedn,
39                           const char * const *attrs,
40                           uint32_t dsdb_flags,
41                           struct ldb_request *parent)
42 {
43         int ret;
44         struct ldb_request *req;
45         TALLOC_CTX *tmp_ctx;
46         struct ldb_result *res;
47
48         tmp_ctx = talloc_new(mem_ctx);
49
50         res = talloc_zero(tmp_ctx, struct ldb_result);
51         if (!res) {
52                 talloc_free(tmp_ctx);
53                 return ldb_oom(ldb_module_get_ctx(module));
54         }
55
56         ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx,
57                                    basedn,
58                                    LDB_SCOPE_BASE,
59                                    NULL,
60                                    attrs,
61                                    NULL,
62                                    res,
63                                    ldb_search_default_callback,
64                                    parent);
65         LDB_REQ_SET_LOCATION(req);
66         if (ret != LDB_SUCCESS) {
67                 talloc_free(tmp_ctx);
68                 return ret;
69         }
70
71         ret = dsdb_request_add_controls(req, dsdb_flags);
72         if (ret != LDB_SUCCESS) {
73                 talloc_free(tmp_ctx);
74                 return ret;
75         }
76
77         if (dsdb_flags & DSDB_FLAG_TRUSTED) {
78                 ldb_req_mark_trusted(req);
79         }
80
81         /* Run the new request */
82         if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) {
83                 ret = ldb_next_request(module, req);
84         } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
85                 ret = ldb_request(ldb_module_get_ctx(module), req);
86         } else {
87                 const struct ldb_module_ops *ops = ldb_module_get_ops(module);
88                 SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE);
89                 ret = ops->search(module, req);
90         }
91         if (ret == LDB_SUCCESS) {
92                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
93         }
94
95         if (ret != LDB_SUCCESS) {
96                 talloc_free(tmp_ctx);
97                 return ret;
98         }
99
100         if (res->count != 1) {
101                 /* we may be reading a DB that does not have the 'check base on search' option... */
102                 ret = LDB_ERR_NO_SUCH_OBJECT;
103                 ldb_asprintf_errstring(ldb_module_get_ctx(module), 
104                                        "dsdb_module_search_dn: did not find base dn %s (%d results)", 
105                                        ldb_dn_get_linearized(basedn), res->count);
106         } else {
107                 *_res = talloc_steal(mem_ctx, res);
108         }
109         talloc_free(tmp_ctx);
110         return ret;
111 }
112
113 int dsdb_module_search_tree(struct ldb_module *module,
114                        TALLOC_CTX *mem_ctx,
115                        struct ldb_result **_res,
116                        struct ldb_dn *basedn,
117                        enum ldb_scope scope,
118                        struct ldb_parse_tree *tree,
119                        const char * const *attrs,
120                        int dsdb_flags,
121                        struct ldb_request *parent)
122 {
123         int ret;
124         struct ldb_request *req;
125         TALLOC_CTX *tmp_ctx;
126         struct ldb_result *res;
127
128         tmp_ctx = talloc_new(mem_ctx);
129
130         /* cross-partitions searches with a basedn break multi-domain support */
131         SMB_ASSERT(basedn == NULL || (dsdb_flags & DSDB_SEARCH_SEARCH_ALL_PARTITIONS) == 0);
132
133         res = talloc_zero(tmp_ctx, struct ldb_result);
134         if (!res) {
135                 talloc_free(tmp_ctx);
136                 return ldb_oom(ldb_module_get_ctx(module));
137         }
138
139         ret = ldb_build_search_req_ex(&req, ldb_module_get_ctx(module), tmp_ctx,
140                                    basedn,
141                                    scope,
142                                    tree,
143                                    attrs,
144                                    NULL,
145                                    res,
146                                    ldb_search_default_callback,
147                                    parent);
148         LDB_REQ_SET_LOCATION(req);
149         if (ret != LDB_SUCCESS) {
150                 talloc_free(tmp_ctx);
151                 return ret;
152         }
153
154         ret = dsdb_request_add_controls(req, dsdb_flags);
155         if (ret != LDB_SUCCESS) {
156                 talloc_free(tmp_ctx);
157                 return ret;
158         }
159
160         if (dsdb_flags & DSDB_FLAG_TRUSTED) {
161                 ldb_req_mark_trusted(req);
162         }
163
164         if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) {
165                 ret = ldb_next_request(module, req);
166         } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
167                 ret = ldb_request(ldb_module_get_ctx(module), req);
168         } else {
169                 const struct ldb_module_ops *ops = ldb_module_get_ops(module);
170                 SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE);
171                 ret = ops->search(module, req);
172         }
173         if (ret == LDB_SUCCESS) {
174                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
175         }
176
177         if (dsdb_flags & DSDB_SEARCH_ONE_ONLY) {
178                 if (res->count == 0) {
179                         talloc_free(tmp_ctx);
180                         ldb_reset_err_string(ldb_module_get_ctx(module));
181                         return LDB_ERR_NO_SUCH_OBJECT;
182                 }
183                 if (res->count != 1) {
184                         talloc_free(tmp_ctx);
185                         ldb_reset_err_string(ldb_module_get_ctx(module));
186                         return LDB_ERR_CONSTRAINT_VIOLATION;
187                 }
188         }
189
190         talloc_free(req);
191         if (ret == LDB_SUCCESS) {
192                 *_res = talloc_steal(mem_ctx, res);
193         }
194         talloc_free(tmp_ctx);
195         return ret;
196 }
197
198 /*
199   search for attrs in the modules below
200  */
201 int dsdb_module_search(struct ldb_module *module,
202                        TALLOC_CTX *mem_ctx,
203                        struct ldb_result **_res,
204                        struct ldb_dn *basedn, enum ldb_scope scope,
205                        const char * const *attrs,
206                        int dsdb_flags,
207                        struct ldb_request *parent,
208                        const char *format, ...) _PRINTF_ATTRIBUTE(9, 10)
209 {
210         int ret;
211         TALLOC_CTX *tmp_ctx;
212         va_list ap;
213         char *expression;
214         struct ldb_parse_tree *tree;
215
216         /* cross-partitions searches with a basedn break multi-domain support */
217         SMB_ASSERT(basedn == NULL || (dsdb_flags & DSDB_SEARCH_SEARCH_ALL_PARTITIONS) == 0);
218
219         tmp_ctx = talloc_new(mem_ctx);
220
221         if (format) {
222                 va_start(ap, format);
223                 expression = talloc_vasprintf(tmp_ctx, format, ap);
224                 va_end(ap);
225
226                 if (!expression) {
227                         talloc_free(tmp_ctx);
228                         return ldb_oom(ldb_module_get_ctx(module));
229                 }
230         } else {
231                 expression = NULL;
232         }
233
234         tree = ldb_parse_tree(tmp_ctx, expression);
235         if (tree == NULL) {
236                 talloc_free(tmp_ctx);
237                 ldb_set_errstring(ldb_module_get_ctx(module),
238                                 "Unable to parse search expression");
239                 return LDB_ERR_OPERATIONS_ERROR;
240         }
241
242         ret = dsdb_module_search_tree(module,
243                        mem_ctx,
244                        _res,
245                        basedn,
246                        scope,
247                        tree,
248                        attrs,
249                        dsdb_flags,
250                        parent);
251
252         talloc_free(tmp_ctx);
253         return ret;
254 }
255
256 /*
257   find a DN given a GUID. This searches across all partitions
258  */
259 int dsdb_module_dn_by_guid(struct ldb_module *module, TALLOC_CTX *mem_ctx,
260                            const struct GUID *guid, struct ldb_dn **dn,
261                            struct ldb_request *parent)
262 {
263         struct ldb_result *res;
264         const char *attrs[] = { NULL };
265         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
266         int ret;
267
268         ret = dsdb_module_search(module, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
269                                  attrs,
270                                  DSDB_FLAG_NEXT_MODULE |
271                                  DSDB_SEARCH_SHOW_RECYCLED |
272                                  DSDB_SEARCH_SEARCH_ALL_PARTITIONS |
273                                  DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT,
274                                  parent,
275                                  "objectGUID=%s", GUID_string(tmp_ctx, guid));
276         if (ret != LDB_SUCCESS) {
277                 talloc_free(tmp_ctx);
278                 return ret;
279         }
280         if (res->count == 0) {
281                 talloc_free(tmp_ctx);
282                 return LDB_ERR_NO_SUCH_OBJECT;
283         }
284         if (res->count != 1) {
285                 ldb_asprintf_errstring(ldb_module_get_ctx(module), "More than one object found matching objectGUID %s\n",
286                                        GUID_string(tmp_ctx, guid));
287                 talloc_free(tmp_ctx);
288                 return LDB_ERR_OPERATIONS_ERROR;
289         }
290
291         *dn = talloc_steal(mem_ctx, res->msgs[0]->dn);
292
293         talloc_free(tmp_ctx);
294         return LDB_SUCCESS;
295 }
296
297 /*
298   find a GUID given a DN.
299  */
300 int dsdb_module_guid_by_dn(struct ldb_module *module, struct ldb_dn *dn, struct GUID *guid,
301                            struct ldb_request *parent)
302 {
303         const char *attrs[] = { NULL };
304         struct ldb_result *res;
305         TALLOC_CTX *tmp_ctx = talloc_new(module);
306         int ret;
307         NTSTATUS status;
308
309         ret = dsdb_module_search_dn(module, tmp_ctx, &res, dn, attrs,
310                                     DSDB_FLAG_NEXT_MODULE |
311                                     DSDB_SEARCH_SHOW_RECYCLED |
312                                     DSDB_SEARCH_SHOW_EXTENDED_DN,
313                                     parent);
314         if (ret != LDB_SUCCESS) {
315                 ldb_asprintf_errstring(ldb_module_get_ctx(module), "Failed to find GUID for %s",
316                                        ldb_dn_get_linearized(dn));
317                 talloc_free(tmp_ctx);
318                 return ret;
319         }
320
321         status = dsdb_get_extended_dn_guid(res->msgs[0]->dn, guid, "GUID");
322         if (!NT_STATUS_IS_OK(status)) {
323                 talloc_free(tmp_ctx);
324                 return ldb_operr(ldb_module_get_ctx(module));
325         }
326
327         talloc_free(tmp_ctx);
328         return LDB_SUCCESS;
329 }
330
331
332 /*
333   a ldb_extended request operating on modules below the
334   current module
335
336   Note that this does not automatically start a transaction. If you
337   need a transaction the caller needs to start it as needed.
338  */
339 int dsdb_module_extended(struct ldb_module *module,
340                          TALLOC_CTX *mem_ctx,
341                          struct ldb_result **_res,
342                          const char* oid, void* data,
343                          uint32_t dsdb_flags,
344                          struct ldb_request *parent)
345 {
346         struct ldb_request *req;
347         int ret;
348         struct ldb_context *ldb = ldb_module_get_ctx(module);
349         TALLOC_CTX *tmp_ctx = talloc_new(module);
350         struct ldb_result *res;
351
352         if (_res != NULL) {
353                 (*_res) = NULL;
354         }
355
356         res = talloc_zero(tmp_ctx, struct ldb_result);
357         if (!res) {
358                 talloc_free(tmp_ctx);
359                 return ldb_oom(ldb_module_get_ctx(module));
360         }
361
362         ret = ldb_build_extended_req(&req, ldb,
363                         tmp_ctx,
364                         oid,
365                         data,
366                         NULL,
367                         res, ldb_extended_default_callback,
368                         parent);
369
370         LDB_REQ_SET_LOCATION(req);
371         if (ret != LDB_SUCCESS) {
372                 talloc_free(tmp_ctx);
373                 return ret;
374         }
375
376         ret = dsdb_request_add_controls(req, dsdb_flags);
377         if (ret != LDB_SUCCESS) {
378                 talloc_free(tmp_ctx);
379                 return ret;
380         }
381
382         if (dsdb_flags & DSDB_FLAG_TRUSTED) {
383                 ldb_req_mark_trusted(req);
384         }
385
386         /* Run the new request */
387         if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) {
388                 ret = ldb_next_request(module, req);
389         } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
390                 ret = ldb_request(ldb_module_get_ctx(module), req);
391         } else {
392                 const struct ldb_module_ops *ops = ldb_module_get_ops(module);
393                 SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE);
394                 ret = ops->extended(module, req);
395         }
396         if (ret == LDB_SUCCESS) {
397                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
398         }
399
400         if (_res != NULL && ret == LDB_SUCCESS) {
401                 (*_res) = talloc_steal(mem_ctx, res);
402         }
403
404         talloc_free(tmp_ctx);
405         return ret;
406 }
407
408
409 /*
410   a ldb_modify request operating on modules below the
411   current module
412  */
413 int dsdb_module_modify(struct ldb_module *module,
414                        const struct ldb_message *message,
415                        uint32_t dsdb_flags,
416                        struct ldb_request *parent)
417 {
418         struct ldb_request *mod_req;
419         int ret;
420         struct ldb_context *ldb = ldb_module_get_ctx(module);
421         TALLOC_CTX *tmp_ctx = talloc_new(module);
422         struct ldb_result *res;
423
424         res = talloc_zero(tmp_ctx, struct ldb_result);
425         if (!res) {
426                 talloc_free(tmp_ctx);
427                 return ldb_oom(ldb_module_get_ctx(module));
428         }
429
430         ret = ldb_build_mod_req(&mod_req, ldb, tmp_ctx,
431                                 message,
432                                 NULL,
433                                 res,
434                                 ldb_modify_default_callback,
435                                 parent);
436         LDB_REQ_SET_LOCATION(mod_req);
437         if (ret != LDB_SUCCESS) {
438                 talloc_free(tmp_ctx);
439                 return ret;
440         }
441
442         ret = dsdb_request_add_controls(mod_req, dsdb_flags);
443         if (ret != LDB_SUCCESS) {
444                 talloc_free(tmp_ctx);
445                 return ret;
446         }
447
448         if (dsdb_flags & DSDB_FLAG_TRUSTED) {
449                 ldb_req_mark_trusted(mod_req);
450         }
451
452         /* Run the new request */
453         if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) {
454                 ret = ldb_next_request(module, mod_req);
455         } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
456                 ret = ldb_request(ldb_module_get_ctx(module), mod_req);
457         } else {
458                 const struct ldb_module_ops *ops = ldb_module_get_ops(module);
459                 SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE);
460                 ret = ops->modify(module, mod_req);
461         }
462         if (ret == LDB_SUCCESS) {
463                 ret = ldb_wait(mod_req->handle, LDB_WAIT_ALL);
464         }
465
466         talloc_free(tmp_ctx);
467         return ret;
468 }
469
470
471
472 /*
473   a ldb_rename request operating on modules below the
474   current module
475  */
476 int dsdb_module_rename(struct ldb_module *module,
477                        struct ldb_dn *olddn, struct ldb_dn *newdn,
478                        uint32_t dsdb_flags,
479                        struct ldb_request *parent)
480 {
481         struct ldb_request *req;
482         int ret;
483         struct ldb_context *ldb = ldb_module_get_ctx(module);
484         TALLOC_CTX *tmp_ctx = talloc_new(module);
485         struct ldb_result *res;
486
487         res = talloc_zero(tmp_ctx, struct ldb_result);
488         if (!res) {
489                 talloc_free(tmp_ctx);
490                 return ldb_oom(ldb_module_get_ctx(module));
491         }
492
493         ret = ldb_build_rename_req(&req, ldb, tmp_ctx,
494                                    olddn,
495                                    newdn,
496                                    NULL,
497                                    res,
498                                    ldb_modify_default_callback,
499                                    parent);
500         LDB_REQ_SET_LOCATION(req);
501         if (ret != LDB_SUCCESS) {
502                 talloc_free(tmp_ctx);
503                 return ret;
504         }
505
506         ret = dsdb_request_add_controls(req, dsdb_flags);
507         if (ret != LDB_SUCCESS) {
508                 talloc_free(tmp_ctx);
509                 return ret;
510         }
511
512         if (dsdb_flags & DSDB_FLAG_TRUSTED) {
513                 ldb_req_mark_trusted(req);
514         }
515
516         /* Run the new request */
517         if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) {
518                 ret = ldb_next_request(module, req);
519         } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
520                 ret = ldb_request(ldb_module_get_ctx(module), req);
521         } else {
522                 const struct ldb_module_ops *ops = ldb_module_get_ops(module);
523                 SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE);
524                 ret = ops->rename(module, req);
525         }
526         if (ret == LDB_SUCCESS) {
527                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
528         }
529
530         talloc_free(tmp_ctx);
531         return ret;
532 }
533
534 /*
535   a ldb_add request operating on modules below the
536   current module
537  */
538 int dsdb_module_add(struct ldb_module *module,
539                     const struct ldb_message *message,
540                     uint32_t dsdb_flags,
541                     struct ldb_request *parent)
542 {
543         struct ldb_request *req;
544         int ret;
545         struct ldb_context *ldb = ldb_module_get_ctx(module);
546         TALLOC_CTX *tmp_ctx = talloc_new(module);
547         struct ldb_result *res;
548
549         res = talloc_zero(tmp_ctx, struct ldb_result);
550         if (!res) {
551                 talloc_free(tmp_ctx);
552                 return ldb_oom(ldb_module_get_ctx(module));
553         }
554
555         ret = ldb_build_add_req(&req, ldb, tmp_ctx,
556                                 message,
557                                 NULL,
558                                 res,
559                                 ldb_modify_default_callback,
560                                 parent);
561         LDB_REQ_SET_LOCATION(req);
562         if (ret != LDB_SUCCESS) {
563                 talloc_free(tmp_ctx);
564                 return ret;
565         }
566
567         ret = dsdb_request_add_controls(req, dsdb_flags);
568         if (ret != LDB_SUCCESS) {
569                 talloc_free(tmp_ctx);
570                 return ret;
571         }
572
573         if (dsdb_flags & DSDB_FLAG_TRUSTED) {
574                 ldb_req_mark_trusted(req);
575         }
576
577         /* Run the new request */
578         if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) {
579                 ret = ldb_next_request(module, req);
580         } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
581                 ret = ldb_request(ldb_module_get_ctx(module), req);
582         } else {
583                 const struct ldb_module_ops *ops = ldb_module_get_ops(module);
584                 SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE);
585                 ret = ops->add(module, req);
586         }
587         if (ret == LDB_SUCCESS) {
588                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
589         }
590
591         talloc_free(tmp_ctx);
592         return ret;
593 }
594
595 /*
596   a ldb_delete request operating on modules below the
597   current module
598  */
599 int dsdb_module_del(struct ldb_module *module,
600                     struct ldb_dn *dn,
601                     uint32_t dsdb_flags,
602                     struct ldb_request *parent)
603 {
604         struct ldb_request *req;
605         int ret;
606         struct ldb_context *ldb = ldb_module_get_ctx(module);
607         TALLOC_CTX *tmp_ctx = talloc_new(module);
608         struct ldb_result *res;
609
610         res = talloc_zero(tmp_ctx, struct ldb_result);
611         if (!res) {
612                 talloc_free(tmp_ctx);
613                 return ldb_oom(ldb);
614         }
615
616         ret = ldb_build_del_req(&req, ldb, tmp_ctx,
617                                 dn,
618                                 NULL,
619                                 res,
620                                 ldb_modify_default_callback,
621                                 parent);
622         LDB_REQ_SET_LOCATION(req);
623         if (ret != LDB_SUCCESS) {
624                 talloc_free(tmp_ctx);
625                 return ret;
626         }
627
628         ret = dsdb_request_add_controls(req, dsdb_flags);
629         if (ret != LDB_SUCCESS) {
630                 talloc_free(tmp_ctx);
631                 return ret;
632         }
633
634         if (dsdb_flags & DSDB_FLAG_TRUSTED) {
635                 ldb_req_mark_trusted(req);
636         }
637
638         /* Run the new request */
639         if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) {
640                 ret = ldb_next_request(module, req);
641         } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
642                 ret = ldb_request(ldb_module_get_ctx(module), req);
643         } else {
644                 const struct ldb_module_ops *ops = ldb_module_get_ops(module);
645                 SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE);
646                 ret = ops->del(module, req);
647         }
648         if (ret == LDB_SUCCESS) {
649                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
650         }
651
652         talloc_free(tmp_ctx);
653         return ret;
654 }
655
656 /*
657   check if a single valued link has multiple non-deleted values
658
659   This is needed when we will be using the RELAX control to stop
660   ldb_tdb from checking single valued links
661  */
662 int dsdb_check_single_valued_link(const struct dsdb_attribute *attr,
663                                   const struct ldb_message_element *el)
664 {
665         bool found_active = false;
666         unsigned int i;
667
668         if (!(attr->ldb_schema_attribute->flags & LDB_ATTR_FLAG_SINGLE_VALUE) ||
669             el->num_values < 2) {
670                 return LDB_SUCCESS;
671         }
672
673         for (i=0; i<el->num_values; i++) {
674                 if (!dsdb_dn_is_deleted_val(&el->values[i])) {
675                         if (found_active) {
676                                 return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
677                         }
678                         found_active = true;
679                 }
680         }
681
682         return LDB_SUCCESS;
683 }
684
685 /*
686   check if an optional feature is enabled on our own NTDS DN
687
688   Note that features can be marked as enabled in more than one
689   place. For example, the recyclebin feature is marked as enabled both
690   on the CN=Partitions,CN=Configurration object and on the NTDS DN of
691   each DC in the forest. It seems likely that it is the job of the KCC
692   to propogate between the two
693  */
694 int dsdb_check_optional_feature(struct ldb_module *module, struct GUID op_feature_guid, bool *feature_enabled)
695 {
696         TALLOC_CTX *tmp_ctx;
697         struct ldb_context *ldb = ldb_module_get_ctx(module);
698         struct ldb_result *res;
699         struct ldb_dn *search_dn;
700         struct GUID search_guid;
701         const char *attrs[] = {"msDS-EnabledFeature", NULL};
702         int ret;
703         unsigned int i;
704         struct ldb_message_element *el;
705         struct ldb_dn *feature_dn;
706
707         tmp_ctx = talloc_new(ldb);
708
709         feature_dn = samdb_ntds_settings_dn(ldb_module_get_ctx(module), tmp_ctx);
710         if (feature_dn == NULL) {
711                 talloc_free(tmp_ctx);
712                 return ldb_operr(ldb_module_get_ctx(module));
713         }
714
715         *feature_enabled = false;
716
717         ret = dsdb_module_search_dn(module, tmp_ctx, &res, feature_dn, attrs, DSDB_FLAG_NEXT_MODULE, NULL);
718         if (ret != LDB_SUCCESS) {
719                 ldb_asprintf_errstring(ldb,
720                                 "Could not find the feature object - dn: %s\n",
721                                 ldb_dn_get_linearized(feature_dn));
722                 talloc_free(tmp_ctx);
723                 return LDB_ERR_OPERATIONS_ERROR;
724         }
725         if (res->msgs[0]->num_elements > 0) {
726                 const char *attrs2[] = {"msDS-OptionalFeatureGUID", NULL};
727
728                 el = ldb_msg_find_element(res->msgs[0],"msDS-EnabledFeature");
729
730                 for (i=0; i<el->num_values; i++) {
731                         search_dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &el->values[i]);
732
733                         ret = dsdb_module_search_dn(module, tmp_ctx, &res,
734                                                     search_dn, attrs2, DSDB_FLAG_NEXT_MODULE, NULL);
735                         if (ret != LDB_SUCCESS) {
736                                 ldb_asprintf_errstring(ldb,
737                                                 "Could no find object dn: %s\n",
738                                                 ldb_dn_get_linearized(search_dn));
739                                 talloc_free(tmp_ctx);
740                                 return LDB_ERR_OPERATIONS_ERROR;
741                         }
742
743                         search_guid = samdb_result_guid(res->msgs[0], "msDS-OptionalFeatureGUID");
744
745                         if (GUID_equal(&search_guid, &op_feature_guid)) {
746                                 *feature_enabled = true;
747                                 break;
748                         }
749                 }
750         }
751         talloc_free(tmp_ctx);
752         return LDB_SUCCESS;
753 }
754
755 /*
756   find the NTDS GUID from a computers DN record
757  */
758 int dsdb_module_find_ntdsguid_for_computer(struct ldb_module *module,
759                                            TALLOC_CTX *mem_ctx,
760                                            struct ldb_dn *computer_dn,
761                                            struct GUID *ntds_guid,
762                                            struct ldb_request *parent)
763 {
764         int ret;
765         struct ldb_dn *dn;
766
767         *ntds_guid = GUID_zero();
768
769         ret = dsdb_module_reference_dn(module, mem_ctx, computer_dn,
770                                        "serverReferenceBL", &dn, parent);
771         if (ret != LDB_SUCCESS) {
772                 return ret;
773         }
774
775         if (!ldb_dn_add_child_fmt(dn, "CN=NTDS Settings")) {
776                 talloc_free(dn);
777                 return LDB_ERR_OPERATIONS_ERROR;
778         }
779
780         ret = dsdb_module_guid_by_dn(module, dn, ntds_guid, parent);
781         talloc_free(dn);
782         return ret;
783 }
784
785 /*
786   find a 'reference' DN that points at another object
787   (eg. serverReference, rIDManagerReference etc)
788  */
789 int dsdb_module_reference_dn(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_dn *base,
790                              const char *attribute, struct ldb_dn **dn, struct ldb_request *parent)
791 {
792         const char *attrs[2];
793         struct ldb_result *res;
794         int ret;
795
796         attrs[0] = attribute;
797         attrs[1] = NULL;
798
799         ret = dsdb_module_search_dn(module, mem_ctx, &res, base, attrs,
800                                     DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_EXTENDED_DN, parent);
801         if (ret != LDB_SUCCESS) {
802                 return ret;
803         }
804
805         *dn = ldb_msg_find_attr_as_dn(ldb_module_get_ctx(module),
806                                       mem_ctx, res->msgs[0], attribute);
807         if (!*dn) {
808                 ldb_reset_err_string(ldb_module_get_ctx(module));
809                 talloc_free(res);
810                 return LDB_ERR_NO_SUCH_ATTRIBUTE;
811         }
812
813         talloc_free(res);
814         return LDB_SUCCESS;
815 }
816
817 /*
818   find the RID Manager$ DN via the rIDManagerReference attribute in the
819   base DN
820  */
821 int dsdb_module_rid_manager_dn(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_dn **dn,
822                                struct ldb_request *parent)
823 {
824         return dsdb_module_reference_dn(module, mem_ctx,
825                                         ldb_get_default_basedn(ldb_module_get_ctx(module)),
826                                         "rIDManagerReference", dn, parent);
827 }
828
829 /*
830   used to chain to the callers callback
831  */
832 int dsdb_next_callback(struct ldb_request *req, struct ldb_reply *ares)
833 {
834         struct ldb_request *up_req = talloc_get_type(req->context, struct ldb_request);
835
836         talloc_steal(up_req, req);
837         return up_req->callback(up_req, ares);
838 }
839
840 /*
841   load the uSNHighest and the uSNUrgent attributes from the @REPLCHANGED
842   object for a partition
843  */
844 int dsdb_module_load_partition_usn(struct ldb_module *module, struct ldb_dn *dn,
845                                    uint64_t *uSN, uint64_t *urgent_uSN, struct ldb_request *parent)
846 {
847         struct ldb_context *ldb = ldb_module_get_ctx(module);
848         struct ldb_request *req;
849         int ret;
850         TALLOC_CTX *tmp_ctx = talloc_new(module);
851         struct dsdb_control_current_partition *p_ctrl;
852         struct ldb_result *res;
853
854         res = talloc_zero(tmp_ctx, struct ldb_result);
855         if (!res) {
856                 talloc_free(tmp_ctx);
857                 return ldb_module_oom(module);
858         }
859
860         ret = ldb_build_search_req(&req, ldb, tmp_ctx,
861                                    ldb_dn_new(tmp_ctx, ldb, "@REPLCHANGED"),
862                                    LDB_SCOPE_BASE,
863                                    NULL, NULL,
864                                    NULL,
865                                    res, ldb_search_default_callback,
866                                    parent);
867         LDB_REQ_SET_LOCATION(req);
868         if (ret != LDB_SUCCESS) {
869                 talloc_free(tmp_ctx);
870                 return ret;
871         }
872
873         p_ctrl = talloc(req, struct dsdb_control_current_partition);
874         if (p_ctrl == NULL) {
875                 talloc_free(tmp_ctx);
876                 return ldb_module_oom(module);
877         }
878         p_ctrl->version = DSDB_CONTROL_CURRENT_PARTITION_VERSION;
879         p_ctrl->dn = dn;
880
881
882         ret = ldb_request_add_control(req,
883                                       DSDB_CONTROL_CURRENT_PARTITION_OID,
884                                       false, p_ctrl);
885         if (ret != LDB_SUCCESS) {
886                 talloc_free(tmp_ctx);
887                 return ret;
888         }
889
890         /* Run the new request */
891         ret = ldb_next_request(module, req);
892
893         if (ret == LDB_SUCCESS) {
894                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
895         }
896
897         if (ret == LDB_ERR_NO_SUCH_OBJECT || ret == LDB_ERR_INVALID_DN_SYNTAX) {
898                 /* it hasn't been created yet, which means
899                    an implicit value of zero */
900                 *uSN = 0;
901                 talloc_free(tmp_ctx);
902                 ldb_reset_err_string(ldb);
903                 return LDB_SUCCESS;
904         }
905
906         if (ret != LDB_SUCCESS) {
907                 talloc_free(tmp_ctx);
908                 return ret;
909         }
910
911         if (res->count != 1) {
912                 *uSN = 0;
913                 if (urgent_uSN) {
914                         *urgent_uSN = 0;
915                 }
916         } else {
917                 *uSN = ldb_msg_find_attr_as_uint64(res->msgs[0], "uSNHighest", 0);
918                 if (urgent_uSN) {
919                         *urgent_uSN = ldb_msg_find_attr_as_uint64(res->msgs[0], "uSNUrgent", 0);
920                 }
921         }
922
923         talloc_free(tmp_ctx);
924
925         return LDB_SUCCESS;
926 }
927
928 /*
929   save uSNHighest and uSNUrgent attributes in the @REPLCHANGED object for a
930   partition
931  */
932 int dsdb_module_save_partition_usn(struct ldb_module *module, struct ldb_dn *dn,
933                                    uint64_t uSN, uint64_t urgent_uSN,
934                                    struct ldb_request *parent)
935 {
936         struct ldb_context *ldb = ldb_module_get_ctx(module);
937         struct ldb_request *req;
938         struct ldb_message *msg;
939         struct dsdb_control_current_partition *p_ctrl;
940         int ret;
941         struct ldb_result *res;
942
943         msg = ldb_msg_new(module);
944         if (msg == NULL) {
945                 return ldb_module_oom(module);
946         }
947
948         msg->dn = ldb_dn_new(msg, ldb, "@REPLCHANGED");
949         if (msg->dn == NULL) {
950                 talloc_free(msg);
951                 return ldb_operr(ldb_module_get_ctx(module));
952         }
953
954         res = talloc_zero(msg, struct ldb_result);
955         if (!res) {
956                 talloc_free(msg);
957                 return ldb_module_oom(module);
958         }
959
960         ret = samdb_msg_add_uint64(ldb, msg, msg, "uSNHighest", uSN);
961         if (ret != LDB_SUCCESS) {
962                 talloc_free(msg);
963                 return ret;
964         }
965         msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
966
967         /* urgent_uSN is optional so may not be stored */
968         if (urgent_uSN) {
969                 ret = samdb_msg_add_uint64(ldb, msg, msg, "uSNUrgent",
970                                            urgent_uSN);
971                 if (ret != LDB_SUCCESS) {
972                         talloc_free(msg);
973                         return ret;
974                 }
975                 msg->elements[1].flags = LDB_FLAG_MOD_REPLACE;
976         }
977
978
979         p_ctrl = talloc(msg, struct dsdb_control_current_partition);
980         if (p_ctrl == NULL) {
981                 talloc_free(msg);
982                 return ldb_oom(ldb);
983         }
984         p_ctrl->version = DSDB_CONTROL_CURRENT_PARTITION_VERSION;
985         p_ctrl->dn = dn;
986         ret = ldb_build_mod_req(&req, ldb, msg,
987                                 msg,
988                                 NULL,
989                                 res,
990                                 ldb_modify_default_callback,
991                                 parent);
992         LDB_REQ_SET_LOCATION(req);
993 again:
994         if (ret != LDB_SUCCESS) {
995                 talloc_free(msg);
996                 return ret;
997         }
998
999         ret = ldb_request_add_control(req,
1000                                       DSDB_CONTROL_CURRENT_PARTITION_OID,
1001                                       false, p_ctrl);
1002         if (ret != LDB_SUCCESS) {
1003                 talloc_free(msg);
1004                 return ret;
1005         }
1006
1007         /* Run the new request */
1008         ret = ldb_next_request(module, req);
1009
1010         if (ret == LDB_SUCCESS) {
1011                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1012         }
1013         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
1014                 ret = ldb_build_add_req(&req, ldb, msg,
1015                                         msg,
1016                                         NULL,
1017                                         res,
1018                                         ldb_modify_default_callback,
1019                                         parent);
1020                 LDB_REQ_SET_LOCATION(req);
1021                 goto again;
1022         }
1023
1024         talloc_free(msg);
1025
1026         return ret;
1027 }
1028
1029 bool dsdb_module_am_system(struct ldb_module *module)
1030 {
1031         struct ldb_context *ldb = ldb_module_get_ctx(module);
1032         struct auth_session_info *session_info
1033                 = talloc_get_type(ldb_get_opaque(ldb, "sessionInfo"), struct auth_session_info);
1034         return security_session_user_level(session_info, NULL) == SECURITY_SYSTEM;
1035 }
1036
1037 bool dsdb_module_am_administrator(struct ldb_module *module)
1038 {
1039         struct ldb_context *ldb = ldb_module_get_ctx(module);
1040         struct auth_session_info *session_info
1041                 = talloc_get_type(ldb_get_opaque(ldb, "sessionInfo"), struct auth_session_info);
1042         return security_session_user_level(session_info, NULL) == SECURITY_ADMINISTRATOR;
1043 }
1044
1045 /*
1046   check if the recyclebin is enabled
1047  */
1048 int dsdb_recyclebin_enabled(struct ldb_module *module, bool *enabled)
1049 {
1050         struct ldb_context *ldb = ldb_module_get_ctx(module);
1051         struct GUID recyclebin_guid;
1052         int ret;
1053
1054         GUID_from_string(DS_GUID_FEATURE_RECYCLE_BIN, &recyclebin_guid);
1055
1056         ret = dsdb_check_optional_feature(module, recyclebin_guid, enabled);
1057         if (ret != LDB_SUCCESS) {
1058                 ldb_asprintf_errstring(ldb, "Could not verify if Recycle Bin is enabled \n");
1059                 return LDB_ERR_UNWILLING_TO_PERFORM;
1060         }
1061
1062         return LDB_SUCCESS;
1063 }
1064
1065 int dsdb_msg_constrainted_update_int32(struct ldb_module *module,
1066                                        struct ldb_message *msg,
1067                                        const char *attr,
1068                                        const int32_t *old_val,
1069                                        const int32_t *new_val)
1070 {
1071         struct ldb_message_element *el;
1072         int ret;
1073         char *vstring;
1074
1075         if (old_val) {
1076                 ret = ldb_msg_add_empty(msg, attr, LDB_FLAG_MOD_DELETE, &el);
1077                 if (ret != LDB_SUCCESS) {
1078                         return ret;
1079                 }
1080                 el->num_values = 1;
1081                 el->values = talloc_array(msg, struct ldb_val, el->num_values);
1082                 if (!el->values) {
1083                         return ldb_module_oom(module);
1084                 }
1085                 vstring = talloc_asprintf(el->values, "%ld", (long)*old_val);
1086                 if (!vstring) {
1087                         return ldb_module_oom(module);
1088                 }
1089                 *el->values = data_blob_string_const(vstring);
1090         }
1091
1092         if (new_val) {
1093                 ret = ldb_msg_add_empty(msg, attr, LDB_FLAG_MOD_ADD, &el);
1094                 if (ret != LDB_SUCCESS) {
1095                         return ret;
1096                 }
1097                 el->num_values = 1;
1098                 el->values = talloc_array(msg, struct ldb_val, el->num_values);
1099                 if (!el->values) {
1100                         return ldb_module_oom(module);
1101                 }
1102                 vstring = talloc_asprintf(el->values, "%ld", (long)*new_val);
1103                 if (!vstring) {
1104                         return ldb_module_oom(module);
1105                 }
1106                 *el->values = data_blob_string_const(vstring);
1107         }
1108
1109         return LDB_SUCCESS;
1110 }
1111
1112 int dsdb_msg_constrainted_update_uint32(struct ldb_module *module,
1113                                         struct ldb_message *msg,
1114                                         const char *attr,
1115                                         const uint32_t *old_val,
1116                                         const uint32_t *new_val)
1117 {
1118         return dsdb_msg_constrainted_update_int32(module, msg, attr,
1119                                                   (const int32_t *)old_val,
1120                                                   (const int32_t *)new_val);
1121 }
1122
1123 int dsdb_msg_constrainted_update_int64(struct ldb_module *module,
1124                                        struct ldb_message *msg,
1125                                        const char *attr,
1126                                        const int64_t *old_val,
1127                                        const int64_t *new_val)
1128 {
1129         struct ldb_message_element *el;
1130         int ret;
1131         char *vstring;
1132
1133         if (old_val) {
1134                 ret = ldb_msg_add_empty(msg, attr, LDB_FLAG_MOD_DELETE, &el);
1135                 if (ret != LDB_SUCCESS) {
1136                         return ret;
1137                 }
1138                 el->num_values = 1;
1139                 el->values = talloc_array(msg, struct ldb_val, el->num_values);
1140                 if (!el->values) {
1141                         return ldb_module_oom(module);
1142                 }
1143                 vstring = talloc_asprintf(el->values, "%lld", (long long)*old_val);
1144                 if (!vstring) {
1145                         return ldb_module_oom(module);
1146                 }
1147                 *el->values = data_blob_string_const(vstring);
1148         }
1149
1150         if (new_val) {
1151                 ret = ldb_msg_add_empty(msg, attr, LDB_FLAG_MOD_ADD, &el);
1152                 if (ret != LDB_SUCCESS) {
1153                         return ret;
1154                 }
1155                 el->num_values = 1;
1156                 el->values = talloc_array(msg, struct ldb_val, el->num_values);
1157                 if (!el->values) {
1158                         return ldb_module_oom(module);
1159                 }
1160                 vstring = talloc_asprintf(el->values, "%lld", (long long)*new_val);
1161                 if (!vstring) {
1162                         return ldb_module_oom(module);
1163                 }
1164                 *el->values = data_blob_string_const(vstring);
1165         }
1166
1167         return LDB_SUCCESS;
1168 }
1169
1170 int dsdb_msg_constrainted_update_uint64(struct ldb_module *module,
1171                                         struct ldb_message *msg,
1172                                         const char *attr,
1173                                         const uint64_t *old_val,
1174                                         const uint64_t *new_val)
1175 {
1176         return dsdb_msg_constrainted_update_int64(module, msg, attr,
1177                                                   (const int64_t *)old_val,
1178                                                   (const int64_t *)new_val);
1179 }
1180
1181 /*
1182   update an int32 attribute safely via a constrained delete/add
1183  */
1184 int dsdb_module_constrainted_update_int32(struct ldb_module *module,
1185                                           struct ldb_dn *dn,
1186                                           const char *attr,
1187                                           const int32_t *old_val,
1188                                           const int32_t *new_val,
1189                                           struct ldb_request *parent)
1190 {
1191         struct ldb_message *msg;
1192         int ret;
1193
1194         msg = ldb_msg_new(module);
1195         if (msg == NULL) {
1196                 return ldb_module_oom(module);
1197         }
1198         msg->dn = dn;
1199
1200         ret = dsdb_msg_constrainted_update_int32(module,
1201                                                  msg, attr,
1202                                                  old_val,
1203                                                  new_val);
1204         if (ret != LDB_SUCCESS) {
1205                 talloc_free(msg);
1206                 return ret;
1207         }
1208
1209         ret = dsdb_module_modify(module, msg, DSDB_FLAG_NEXT_MODULE, parent);
1210         talloc_free(msg);
1211         return ret;
1212 }
1213
1214 int dsdb_module_constrainted_update_uint32(struct ldb_module *module,
1215                                            struct ldb_dn *dn,
1216                                            const char *attr,
1217                                            const uint32_t *old_val,
1218                                            const uint32_t *new_val,
1219                                            struct ldb_request *parent)
1220 {
1221         return dsdb_module_constrainted_update_int32(module, dn, attr,
1222                                                      (const int32_t *)old_val,
1223                                                      (const int32_t *)new_val, parent);
1224 }
1225
1226 /*
1227   update an int64 attribute safely via a constrained delete/add
1228  */
1229 int dsdb_module_constrainted_update_int64(struct ldb_module *module,
1230                                           struct ldb_dn *dn,
1231                                           const char *attr,
1232                                           const int64_t *old_val,
1233                                           const int64_t *new_val,
1234                                           struct ldb_request *parent)
1235 {
1236         struct ldb_message *msg;
1237         int ret;
1238
1239         msg = ldb_msg_new(module);
1240         if (msg == NULL) {
1241                 return ldb_module_oom(module);
1242         }
1243         msg->dn = dn;
1244
1245         ret = dsdb_msg_constrainted_update_int64(module,
1246                                                  msg, attr,
1247                                                  old_val,
1248                                                  new_val);
1249         if (ret != LDB_SUCCESS) {
1250                 talloc_free(msg);
1251                 return ret;
1252         }
1253
1254         ret = dsdb_module_modify(module, msg, DSDB_FLAG_NEXT_MODULE, parent);
1255         talloc_free(msg);
1256         return ret;
1257 }
1258
1259 int dsdb_module_constrainted_update_uint64(struct ldb_module *module,
1260                                            struct ldb_dn *dn,
1261                                            const char *attr,
1262                                            const uint64_t *old_val,
1263                                            const uint64_t *new_val,
1264                                            struct ldb_request *parent)
1265 {
1266         return dsdb_module_constrainted_update_int64(module, dn, attr,
1267                                                      (const int64_t *)old_val,
1268                                                      (const int64_t *)new_val,
1269                                                      parent);
1270 }
1271
1272
1273 const struct ldb_val *dsdb_module_find_dsheuristics(struct ldb_module *module,
1274                                                     TALLOC_CTX *mem_ctx, struct ldb_request *parent)
1275 {
1276         int ret;
1277         struct ldb_dn *new_dn;
1278         struct ldb_context *ldb = ldb_module_get_ctx(module);
1279         static const char *attrs[] = { "dSHeuristics", NULL };
1280         struct ldb_result *res;
1281
1282         new_dn = ldb_dn_copy(mem_ctx, ldb_get_config_basedn(ldb));
1283         if (!ldb_dn_add_child_fmt(new_dn,
1284                                    "CN=Directory Service,CN=Windows NT,CN=Services")) {
1285                 talloc_free(new_dn);
1286                 return NULL;
1287         }
1288         ret = dsdb_module_search_dn(module, mem_ctx, &res,
1289                                     new_dn,
1290                                     attrs,
1291                                     DSDB_FLAG_NEXT_MODULE,
1292                                     parent);
1293         if (ret == LDB_SUCCESS && res->count == 1) {
1294                 talloc_free(new_dn);
1295                 return ldb_msg_find_ldb_val(res->msgs[0],
1296                                             "dSHeuristics");
1297         }
1298         talloc_free(new_dn);
1299         return NULL;
1300 }
1301
1302 bool dsdb_block_anonymous_ops(struct ldb_module *module, struct ldb_request *parent)
1303 {
1304         TALLOC_CTX *tmp_ctx = talloc_new(module);
1305         bool result;
1306         const struct ldb_val *hr_val = dsdb_module_find_dsheuristics(module,
1307                                                                      tmp_ctx, parent);
1308         if (hr_val == NULL || hr_val->length < DS_HR_BLOCK_ANONYMOUS_OPS) {
1309                 result = true;
1310         } else if (hr_val->data[DS_HR_BLOCK_ANONYMOUS_OPS -1] == '2') {
1311                 result = false;
1312         } else {
1313                 result = true;
1314         }
1315
1316         talloc_free(tmp_ctx);
1317         return result;
1318 }
1319
1320 bool dsdb_user_password_support(struct ldb_module *module,
1321                                 TALLOC_CTX *mem_ctx,
1322                                 struct ldb_request *parent)
1323 {
1324         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1325         bool result;
1326         const struct ldb_val *hr_val = dsdb_module_find_dsheuristics(module,
1327                                                                      tmp_ctx,
1328                                                                      parent);
1329         if (hr_val == NULL || hr_val->length < DS_HR_USER_PASSWORD_SUPPORT) {
1330                 result = false;
1331         } else if ((hr_val->data[DS_HR_USER_PASSWORD_SUPPORT -1] == '2') ||
1332                    (hr_val->data[DS_HR_USER_PASSWORD_SUPPORT -1] == '0')) {
1333                 result = false;
1334         } else {
1335                 result = true;
1336         }
1337
1338         talloc_free(tmp_ctx);
1339         return result;
1340 }
1341
1342 /*
1343   show the chain of requests, useful for debugging async requests
1344  */
1345 void dsdb_req_chain_debug(struct ldb_request *req, int level)
1346 {
1347         char *s = ldb_module_call_chain(req, req);
1348         DEBUG(level, ("%s\n", s));
1349         talloc_free(s);
1350 }
1351
1352 /*
1353  * Gets back a single-valued attribute by the rules of the DSDB triggers when
1354  * performing a modify operation.
1355  *
1356  * In order that the constraint checking by the "objectclass_attrs" LDB module
1357  * does work properly, the change request should remain similar or only be
1358  * enhanced (no other modifications as deletions, variations).
1359  */
1360 struct ldb_message_element *dsdb_get_single_valued_attr(const struct ldb_message *msg,
1361                                                         const char *attr_name,
1362                                                         enum ldb_request_type operation)
1363 {
1364         struct ldb_message_element *el = NULL;
1365         unsigned int i;
1366
1367         /* We've to walk over all modification entries and consider the last
1368          * non-delete one which belongs to "attr_name".
1369          *
1370          * If "el" is NULL afterwards then that means there was no interesting
1371          * change entry. */
1372         for (i = 0; i < msg->num_elements; i++) {
1373                 if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) {
1374                         if ((operation == LDB_MODIFY) &&
1375                             (LDB_FLAG_MOD_TYPE(msg->elements[i].flags)
1376                                                 == LDB_FLAG_MOD_DELETE)) {
1377                                 continue;
1378                         }
1379                         el = &msg->elements[i];
1380                 }
1381         }
1382
1383         return el;
1384 }
1385
1386 /*
1387  * This function determines the (last) structural or 88 object class of a passed
1388  * "objectClass" attribute - per MS-ADTS 3.1.1.1.4 this is the last value.
1389  * Without schema this does not work and hence NULL is returned.
1390  */
1391 const struct dsdb_class *dsdb_get_last_structural_class(const struct dsdb_schema *schema,
1392                                                         const struct ldb_message_element *element)
1393 {
1394         const struct dsdb_class *last_class;
1395
1396         if (schema == NULL) {
1397                 return NULL;
1398         }
1399
1400         if (element->num_values == 0) {
1401                 return NULL;
1402         }
1403
1404         last_class = dsdb_class_by_lDAPDisplayName_ldb_val(schema,
1405                                                            &element->values[element->num_values-1]);
1406         if (last_class == NULL) {
1407                 return NULL;
1408         }
1409         if (last_class->objectClassCategory > 1) {
1410                 return NULL;
1411         }
1412
1413         return last_class;
1414 }
1415
1416 const struct dsdb_class *dsdb_get_structural_oc_from_msg(const struct dsdb_schema *schema,
1417                                                          const struct ldb_message *msg)
1418 {
1419         struct ldb_message_element *oc_el;
1420
1421         oc_el = ldb_msg_find_element(msg, "objectClass");
1422         if (!oc_el) {
1423                 return NULL;
1424         }
1425
1426         return dsdb_get_last_structural_class(schema, oc_el);
1427 }
1428
1429 /* Fix the DN so that the relative attribute names are in upper case so that the DN:
1430    cn=Adminstrator,cn=users,dc=samba,dc=example,dc=com becomes
1431    CN=Adminstrator,CN=users,DC=samba,DC=example,DC=com
1432 */
1433 int dsdb_fix_dn_rdncase(struct ldb_context *ldb, struct ldb_dn *dn)
1434 {
1435         int i, ret;
1436         char *upper_rdn_attr;
1437
1438         for (i=0; i < ldb_dn_get_comp_num(dn); i++) {
1439                 /* We need the attribute name in upper case */
1440                 upper_rdn_attr = strupper_talloc(dn,
1441                                                  ldb_dn_get_component_name(dn, i));
1442                 if (!upper_rdn_attr) {
1443                         return ldb_oom(ldb);
1444                 }
1445                 ret = ldb_dn_set_component(dn, i, upper_rdn_attr,
1446                                            *ldb_dn_get_component_val(dn, i));
1447                 talloc_free(upper_rdn_attr);
1448                 if (ret != LDB_SUCCESS) {
1449                         return ret;
1450                 }
1451         }
1452         return LDB_SUCCESS;
1453 }
1454
1455 /**
1456  * Make most specific objectCategory for the objectClass of passed object
1457  * NOTE: In this implementation we count that it is called on already
1458  * verified objectClass attribute value. See objectclass.c thorough
1459  * implementation for all the magic that involves
1460  *
1461  * @param ldb   ldb context
1462  * @param schema cached schema for ldb. We may get it, but it is very time consuming.
1463  *                      Hence leave the responsibility to the caller.
1464  * @param obj   AD object to determint objectCategory for
1465  * @param mem_ctx Memory context - usually it is obj actually
1466  * @param pobjectcategory location to store found objectCategory
1467  *
1468  * @return LDB_SUCCESS or error including out of memory error
1469  */
1470 int dsdb_make_object_category(struct ldb_context *ldb, const struct dsdb_schema *schema,
1471                               struct ldb_message *obj,
1472                               TALLOC_CTX *mem_ctx, const char **pobjectcategory)
1473 {
1474         const struct dsdb_class                 *objectclass;
1475         struct ldb_message_element              *objectclass_element;
1476         struct dsdb_extended_dn_store_format    *dn_format;
1477
1478         objectclass_element = ldb_msg_find_element(obj, "objectClass");
1479         if (!objectclass_element) {
1480                 ldb_asprintf_errstring(ldb, "dsdb: Cannot add %s, no objectclass specified!",
1481                                        ldb_dn_get_linearized(obj->dn));
1482                 return LDB_ERR_OBJECT_CLASS_VIOLATION;
1483         }
1484         if (objectclass_element->num_values == 0) {
1485                 ldb_asprintf_errstring(ldb, "dsdb: Cannot add %s, at least one (structural) objectclass has to be specified!",
1486                                        ldb_dn_get_linearized(obj->dn));
1487                 return LDB_ERR_CONSTRAINT_VIOLATION;
1488         }
1489
1490         /*
1491          * Get the new top-most structural object class and check for
1492          * unrelated structural classes
1493          */
1494         objectclass = dsdb_get_last_structural_class(schema,
1495                                                      objectclass_element);
1496         if (objectclass == NULL) {
1497                 ldb_asprintf_errstring(ldb,
1498                                        "Failed to find a structural class for %s",
1499                                        ldb_dn_get_linearized(obj->dn));
1500                 return LDB_ERR_UNWILLING_TO_PERFORM;
1501         }
1502
1503         dn_format = talloc_get_type(ldb_get_opaque(ldb, DSDB_EXTENDED_DN_STORE_FORMAT_OPAQUE_NAME),
1504                                     struct dsdb_extended_dn_store_format);
1505         if (dn_format && dn_format->store_extended_dn_in_ldb == false) {
1506                 /* Strip off extended components */
1507                 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb,
1508                                                objectclass->defaultObjectCategory);
1509                 *pobjectcategory = ldb_dn_alloc_linearized(mem_ctx, dn);
1510                 talloc_free(dn);
1511         } else {
1512                 *pobjectcategory = talloc_strdup(mem_ctx, objectclass->defaultObjectCategory);
1513         }
1514
1515         if (*pobjectcategory == NULL) {
1516                 return ldb_oom(ldb);
1517         }
1518
1519         return LDB_SUCCESS;
1520 }