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