s4:dsdb: Factor out a function to remove all password related attributes
[cs/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 #undef strcasecmp
33
34 /*
35   search for attrs on one DN, in the modules below
36  */
37 int dsdb_module_search_dn(struct ldb_module *module,
38                           TALLOC_CTX *mem_ctx,
39                           struct ldb_result **_res,
40                           struct ldb_dn *basedn,
41                           const char * const *attrs,
42                           uint32_t dsdb_flags,
43                           struct ldb_request *parent)
44 {
45         int ret;
46         struct ldb_request *req;
47         TALLOC_CTX *tmp_ctx;
48         struct ldb_result *res;
49
50         tmp_ctx = talloc_new(mem_ctx);
51         if (tmp_ctx == NULL) {
52                 return ldb_oom(ldb_module_get_ctx(module));
53         }
54
55         res = talloc_zero(tmp_ctx, struct ldb_result);
56         if (!res) {
57                 talloc_free(tmp_ctx);
58                 return ldb_oom(ldb_module_get_ctx(module));
59         }
60
61         ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx,
62                                    basedn,
63                                    LDB_SCOPE_BASE,
64                                    NULL,
65                                    attrs,
66                                    NULL,
67                                    res,
68                                    ldb_search_default_callback,
69                                    parent);
70         LDB_REQ_SET_LOCATION(req);
71         if (ret != LDB_SUCCESS) {
72                 talloc_free(tmp_ctx);
73                 return ret;
74         }
75
76         ret = dsdb_request_add_controls(req, dsdb_flags);
77         if (ret != LDB_SUCCESS) {
78                 talloc_free(tmp_ctx);
79                 return ret;
80         }
81
82         if (dsdb_flags & DSDB_FLAG_TRUSTED) {
83                 ldb_req_mark_trusted(req);
84         }
85
86         /* Run the new request */
87         if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) {
88                 ret = ldb_next_request(module, req);
89         } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
90                 ret = ldb_request(ldb_module_get_ctx(module), req);
91         } else {
92                 const struct ldb_module_ops *ops = ldb_module_get_ops(module);
93                 SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE);
94                 ret = ops->search(module, req);
95         }
96         if (ret == LDB_SUCCESS) {
97                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
98         }
99
100         if (ret != LDB_SUCCESS) {
101                 talloc_free(tmp_ctx);
102                 return ret;
103         }
104
105         if (res->count != 1) {
106                 /* we may be reading a DB that does not have the 'check base on search' option... */
107                 ret = LDB_ERR_NO_SUCH_OBJECT;
108                 ldb_asprintf_errstring(ldb_module_get_ctx(module),
109                                        "dsdb_module_search_dn: did not find base dn %s (%d results)",
110                                        ldb_dn_get_linearized(basedn), res->count);
111         } else {
112                 *_res = talloc_steal(mem_ctx, res);
113         }
114         talloc_free(tmp_ctx);
115         return ret;
116 }
117
118 int dsdb_module_search_tree(struct ldb_module *module,
119                        TALLOC_CTX *mem_ctx,
120                        struct ldb_result **_res,
121                        struct ldb_dn *basedn,
122                        enum ldb_scope scope,
123                        struct ldb_parse_tree *tree,
124                        const char * const *attrs,
125                        int dsdb_flags,
126                        struct ldb_request *parent)
127 {
128         int ret;
129         struct ldb_request *req;
130         TALLOC_CTX *tmp_ctx;
131         struct ldb_result *res;
132
133         tmp_ctx = talloc_new(mem_ctx);
134         if (tmp_ctx == NULL) {
135                 return ldb_oom(ldb_module_get_ctx(module));
136         }
137
138         /* cross-partitions searches with a basedn break multi-domain support */
139         SMB_ASSERT(basedn == NULL || (dsdb_flags & DSDB_SEARCH_SEARCH_ALL_PARTITIONS) == 0);
140
141         res = talloc_zero(tmp_ctx, struct ldb_result);
142         if (!res) {
143                 talloc_free(tmp_ctx);
144                 return ldb_oom(ldb_module_get_ctx(module));
145         }
146
147         ret = ldb_build_search_req_ex(&req, ldb_module_get_ctx(module), tmp_ctx,
148                                    basedn,
149                                    scope,
150                                    tree,
151                                    attrs,
152                                    NULL,
153                                    res,
154                                    ldb_search_default_callback,
155                                    parent);
156         LDB_REQ_SET_LOCATION(req);
157         if (ret != LDB_SUCCESS) {
158                 talloc_free(tmp_ctx);
159                 return ret;
160         }
161
162         ret = dsdb_request_add_controls(req, dsdb_flags);
163         if (ret != LDB_SUCCESS) {
164                 talloc_free(tmp_ctx);
165                 return ret;
166         }
167
168         if (dsdb_flags & DSDB_FLAG_TRUSTED) {
169                 ldb_req_mark_trusted(req);
170         }
171
172         if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) {
173                 ret = ldb_next_request(module, req);
174         } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
175                 ret = ldb_request(ldb_module_get_ctx(module), req);
176         } else {
177                 const struct ldb_module_ops *ops = ldb_module_get_ops(module);
178                 SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE);
179                 ret = ops->search(module, req);
180         }
181         if (ret == LDB_SUCCESS) {
182                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
183         }
184
185         if (dsdb_flags & DSDB_SEARCH_ONE_ONLY) {
186                 if (res->count == 0) {
187                         talloc_free(tmp_ctx);
188                         return ldb_error(ldb_module_get_ctx(module), LDB_ERR_NO_SUCH_OBJECT, __func__);
189                 }
190                 if (res->count != 1) {
191                         talloc_free(tmp_ctx);
192                         ldb_reset_err_string(ldb_module_get_ctx(module));
193                         return LDB_ERR_CONSTRAINT_VIOLATION;
194                 }
195         }
196
197         talloc_free(req);
198         if (ret == LDB_SUCCESS) {
199                 *_res = talloc_steal(mem_ctx, res);
200         }
201         talloc_free(tmp_ctx);
202         return ret;
203 }
204
205 /*
206   search for attrs in the modules below
207  */
208 int dsdb_module_search(struct ldb_module *module,
209                        TALLOC_CTX *mem_ctx,
210                        struct ldb_result **_res,
211                        struct ldb_dn *basedn, enum ldb_scope scope,
212                        const char * const *attrs,
213                        int dsdb_flags,
214                        struct ldb_request *parent,
215                        const char *format, ...) _PRINTF_ATTRIBUTE(9, 10)
216 {
217         int ret;
218         TALLOC_CTX *tmp_ctx;
219         va_list ap;
220         char *expression;
221         struct ldb_parse_tree *tree;
222
223         /* cross-partitions searches with a basedn break multi-domain support */
224         SMB_ASSERT(basedn == NULL || (dsdb_flags & DSDB_SEARCH_SEARCH_ALL_PARTITIONS) == 0);
225
226         tmp_ctx = talloc_new(mem_ctx);
227         if (tmp_ctx == NULL) {
228                 return ldb_oom(ldb_module_get_ctx(module));
229         }
230
231         if (format) {
232                 va_start(ap, format);
233                 expression = talloc_vasprintf(tmp_ctx, format, ap);
234                 va_end(ap);
235
236                 if (!expression) {
237                         talloc_free(tmp_ctx);
238                         return ldb_oom(ldb_module_get_ctx(module));
239                 }
240         } else {
241                 expression = NULL;
242         }
243
244         tree = ldb_parse_tree(tmp_ctx, expression);
245         if (tree == NULL) {
246                 talloc_free(tmp_ctx);
247                 ldb_set_errstring(ldb_module_get_ctx(module),
248                                 "Unable to parse search expression");
249                 return LDB_ERR_OPERATIONS_ERROR;
250         }
251
252         ret = dsdb_module_search_tree(module,
253                        mem_ctx,
254                        _res,
255                        basedn,
256                        scope,
257                        tree,
258                        attrs,
259                        dsdb_flags,
260                        parent);
261
262         talloc_free(tmp_ctx);
263         return ret;
264 }
265
266 /*
267   find an object given a GUID. This searches across all partitions
268  */
269 int dsdb_module_obj_by_guid(struct ldb_module *module,
270                             TALLOC_CTX *mem_ctx,
271                             struct ldb_message **_msg,
272                             const struct GUID *guid,
273                             const char * const *attrs,
274                             struct ldb_request *parent)
275 {
276         struct ldb_result *res;
277         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
278         int ret;
279
280         ret = dsdb_module_search(module, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
281                                  attrs,
282                                  DSDB_FLAG_NEXT_MODULE |
283                                  DSDB_SEARCH_SHOW_RECYCLED |
284                                  DSDB_SEARCH_SEARCH_ALL_PARTITIONS |
285                                  DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT,
286                                  parent,
287                                  "objectGUID=%s", GUID_string(tmp_ctx, guid));
288         if (ret != LDB_SUCCESS) {
289                 talloc_free(tmp_ctx);
290                 return ret;
291         }
292         if (res->count == 0) {
293                 talloc_free(tmp_ctx);
294                 return ldb_error(ldb_module_get_ctx(module), LDB_ERR_NO_SUCH_OBJECT, __func__);
295         }
296         if (res->count != 1) {
297                 ldb_asprintf_errstring(ldb_module_get_ctx(module), "More than one object found matching objectGUID %s\n",
298                                        GUID_string(tmp_ctx, guid));
299                 talloc_free(tmp_ctx);
300                 return LDB_ERR_OPERATIONS_ERROR;
301         }
302
303         *_msg = talloc_steal(mem_ctx, res->msgs[0]);
304
305         talloc_free(tmp_ctx);
306         return LDB_SUCCESS;
307 }
308
309 /*
310   find a DN given a GUID. This searches across all partitions
311  */
312 int dsdb_module_dn_by_guid(struct ldb_module *module, TALLOC_CTX *mem_ctx,
313                            const struct GUID *guid, struct ldb_dn **dn,
314                            struct ldb_request *parent)
315 {
316         struct ldb_message *msg = NULL;
317         static const char * const attrs[] = { NULL };
318         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
319         int ret;
320
321         ret = dsdb_module_obj_by_guid(module,
322                                       tmp_ctx,
323                                       &msg,
324                                       guid,
325                                       attrs,
326                                       parent);
327         if (ret != LDB_SUCCESS) {
328                 talloc_free(tmp_ctx);
329                 return ret;
330         }
331
332         *dn = talloc_steal(mem_ctx, msg->dn);
333
334         talloc_free(tmp_ctx);
335         return LDB_SUCCESS;
336 }
337
338 /*
339   find a GUID given a DN.
340  */
341 int dsdb_module_guid_by_dn(struct ldb_module *module, struct ldb_dn *dn, struct GUID *guid,
342                            struct ldb_request *parent)
343 {
344         static const char * const attrs[] = { NULL };
345         struct ldb_result *res;
346         TALLOC_CTX *tmp_ctx = talloc_new(module);
347         int ret;
348         NTSTATUS status;
349
350         ret = dsdb_module_search_dn(module, tmp_ctx, &res, dn, attrs,
351                                     DSDB_FLAG_NEXT_MODULE |
352                                     DSDB_SEARCH_SHOW_RECYCLED |
353                                     DSDB_SEARCH_SHOW_EXTENDED_DN,
354                                     parent);
355         if (ret != LDB_SUCCESS) {
356                 ldb_asprintf_errstring(ldb_module_get_ctx(module), "Failed to find GUID for %s",
357                                        ldb_dn_get_linearized(dn));
358                 talloc_free(tmp_ctx);
359                 return ret;
360         }
361
362         status = dsdb_get_extended_dn_guid(res->msgs[0]->dn, guid, "GUID");
363         if (!NT_STATUS_IS_OK(status)) {
364                 talloc_free(tmp_ctx);
365                 return ldb_operr(ldb_module_get_ctx(module));
366         }
367
368         talloc_free(tmp_ctx);
369         return LDB_SUCCESS;
370 }
371
372
373 /*
374   a ldb_extended request operating on modules below the
375   current module
376
377   Note that this does not automatically start a transaction. If you
378   need a transaction the caller needs to start it as needed.
379  */
380 int dsdb_module_extended(struct ldb_module *module,
381                          TALLOC_CTX *mem_ctx,
382                          struct ldb_result **_res,
383                          const char* oid, void* data,
384                          uint32_t dsdb_flags,
385                          struct ldb_request *parent)
386 {
387         struct ldb_request *req;
388         int ret;
389         struct ldb_context *ldb = ldb_module_get_ctx(module);
390         TALLOC_CTX *tmp_ctx = talloc_new(module);
391         struct ldb_result *res;
392
393         if (_res != NULL) {
394                 (*_res) = NULL;
395         }
396
397         res = talloc_zero(tmp_ctx, struct ldb_result);
398         if (!res) {
399                 talloc_free(tmp_ctx);
400                 return ldb_oom(ldb_module_get_ctx(module));
401         }
402
403         ret = ldb_build_extended_req(&req, ldb,
404                         tmp_ctx,
405                         oid,
406                         data,
407                         NULL,
408                         res, ldb_extended_default_callback,
409                         parent);
410
411         LDB_REQ_SET_LOCATION(req);
412         if (ret != LDB_SUCCESS) {
413                 talloc_free(tmp_ctx);
414                 return ret;
415         }
416
417         ret = dsdb_request_add_controls(req, dsdb_flags);
418         if (ret != LDB_SUCCESS) {
419                 talloc_free(tmp_ctx);
420                 return ret;
421         }
422
423         if (dsdb_flags & DSDB_FLAG_TRUSTED) {
424                 ldb_req_mark_trusted(req);
425         }
426
427         /* Run the new request */
428         if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) {
429                 ret = ldb_next_request(module, req);
430         } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
431                 ret = ldb_request(ldb_module_get_ctx(module), req);
432         } else {
433                 const struct ldb_module_ops *ops = ldb_module_get_ops(module);
434                 SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE);
435                 ret = ops->extended(module, req);
436         }
437         if (ret == LDB_SUCCESS) {
438                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
439         }
440
441         if (_res != NULL && ret == LDB_SUCCESS) {
442                 (*_res) = talloc_steal(mem_ctx, res);
443         }
444
445         talloc_free(tmp_ctx);
446         return ret;
447 }
448
449
450 /*
451   a ldb_modify request operating on modules below the
452   current module
453  */
454 int dsdb_module_modify(struct ldb_module *module,
455                        const struct ldb_message *message,
456                        uint32_t dsdb_flags,
457                        struct ldb_request *parent)
458 {
459         struct ldb_request *mod_req;
460         int ret;
461         struct ldb_context *ldb = ldb_module_get_ctx(module);
462         TALLOC_CTX *tmp_ctx = talloc_new(module);
463         struct ldb_result *res;
464
465         res = talloc_zero(tmp_ctx, struct ldb_result);
466         if (!res) {
467                 talloc_free(tmp_ctx);
468                 return ldb_oom(ldb_module_get_ctx(module));
469         }
470
471         ret = ldb_build_mod_req(&mod_req, ldb, tmp_ctx,
472                                 message,
473                                 NULL,
474                                 res,
475                                 ldb_modify_default_callback,
476                                 parent);
477         LDB_REQ_SET_LOCATION(mod_req);
478         if (ret != LDB_SUCCESS) {
479                 talloc_free(tmp_ctx);
480                 return ret;
481         }
482
483         ret = dsdb_request_add_controls(mod_req, dsdb_flags);
484         if (ret != LDB_SUCCESS) {
485                 talloc_free(tmp_ctx);
486                 return ret;
487         }
488
489         if (dsdb_flags & DSDB_FLAG_TRUSTED) {
490                 ldb_req_mark_trusted(mod_req);
491         }
492
493         /* Run the new request */
494         if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) {
495                 ret = ldb_next_request(module, mod_req);
496         } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
497                 ret = ldb_request(ldb_module_get_ctx(module), mod_req);
498         } else {
499                 const struct ldb_module_ops *ops = ldb_module_get_ops(module);
500                 SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE);
501                 ret = ops->modify(module, mod_req);
502         }
503         if (ret == LDB_SUCCESS) {
504                 ret = ldb_wait(mod_req->handle, LDB_WAIT_ALL);
505         }
506
507         talloc_free(tmp_ctx);
508         return ret;
509 }
510
511
512
513 /*
514   a ldb_rename request operating on modules below the
515   current module
516  */
517 int dsdb_module_rename(struct ldb_module *module,
518                        struct ldb_dn *olddn, struct ldb_dn *newdn,
519                        uint32_t dsdb_flags,
520                        struct ldb_request *parent)
521 {
522         struct ldb_request *req;
523         int ret;
524         struct ldb_context *ldb = ldb_module_get_ctx(module);
525         TALLOC_CTX *tmp_ctx = talloc_new(module);
526         struct ldb_result *res;
527
528         res = talloc_zero(tmp_ctx, struct ldb_result);
529         if (!res) {
530                 talloc_free(tmp_ctx);
531                 return ldb_oom(ldb_module_get_ctx(module));
532         }
533
534         ret = ldb_build_rename_req(&req, ldb, tmp_ctx,
535                                    olddn,
536                                    newdn,
537                                    NULL,
538                                    res,
539                                    ldb_modify_default_callback,
540                                    parent);
541         LDB_REQ_SET_LOCATION(req);
542         if (ret != LDB_SUCCESS) {
543                 talloc_free(tmp_ctx);
544                 return ret;
545         }
546
547         ret = dsdb_request_add_controls(req, dsdb_flags);
548         if (ret != LDB_SUCCESS) {
549                 talloc_free(tmp_ctx);
550                 return ret;
551         }
552
553         if (dsdb_flags & DSDB_FLAG_TRUSTED) {
554                 ldb_req_mark_trusted(req);
555         }
556
557         /* Run the new request */
558         if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) {
559                 ret = ldb_next_request(module, req);
560         } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
561                 ret = ldb_request(ldb_module_get_ctx(module), req);
562         } else {
563                 const struct ldb_module_ops *ops = ldb_module_get_ops(module);
564                 SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE);
565                 ret = ops->rename(module, req);
566         }
567         if (ret == LDB_SUCCESS) {
568                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
569         }
570
571         talloc_free(tmp_ctx);
572         return ret;
573 }
574
575 /*
576   a ldb_add request operating on modules below the
577   current module
578  */
579 int dsdb_module_add(struct ldb_module *module,
580                     const struct ldb_message *message,
581                     uint32_t dsdb_flags,
582                     struct ldb_request *parent)
583 {
584         struct ldb_request *req;
585         int ret;
586         struct ldb_context *ldb = ldb_module_get_ctx(module);
587         TALLOC_CTX *tmp_ctx = talloc_new(module);
588         struct ldb_result *res;
589
590         res = talloc_zero(tmp_ctx, struct ldb_result);
591         if (!res) {
592                 talloc_free(tmp_ctx);
593                 return ldb_oom(ldb_module_get_ctx(module));
594         }
595
596         ret = ldb_build_add_req(&req, ldb, tmp_ctx,
597                                 message,
598                                 NULL,
599                                 res,
600                                 ldb_modify_default_callback,
601                                 parent);
602         LDB_REQ_SET_LOCATION(req);
603         if (ret != LDB_SUCCESS) {
604                 talloc_free(tmp_ctx);
605                 return ret;
606         }
607
608         ret = dsdb_request_add_controls(req, dsdb_flags);
609         if (ret != LDB_SUCCESS) {
610                 talloc_free(tmp_ctx);
611                 return ret;
612         }
613
614         if (dsdb_flags & DSDB_FLAG_TRUSTED) {
615                 ldb_req_mark_trusted(req);
616         }
617
618         /* Run the new request */
619         if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) {
620                 ret = ldb_next_request(module, req);
621         } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
622                 ret = ldb_request(ldb_module_get_ctx(module), req);
623         } else {
624                 const struct ldb_module_ops *ops = ldb_module_get_ops(module);
625                 SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE);
626                 ret = ops->add(module, req);
627         }
628         if (ret == LDB_SUCCESS) {
629                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
630         }
631
632         talloc_free(tmp_ctx);
633         return ret;
634 }
635
636 /*
637   a ldb_delete request operating on modules below the
638   current module
639  */
640 int dsdb_module_del(struct ldb_module *module,
641                     struct ldb_dn *dn,
642                     uint32_t dsdb_flags,
643                     struct ldb_request *parent)
644 {
645         struct ldb_request *req;
646         int ret;
647         struct ldb_context *ldb = ldb_module_get_ctx(module);
648         TALLOC_CTX *tmp_ctx = talloc_new(module);
649         struct ldb_result *res;
650
651         res = talloc_zero(tmp_ctx, struct ldb_result);
652         if (!res) {
653                 talloc_free(tmp_ctx);
654                 return ldb_oom(ldb);
655         }
656
657         ret = ldb_build_del_req(&req, ldb, tmp_ctx,
658                                 dn,
659                                 NULL,
660                                 res,
661                                 ldb_modify_default_callback,
662                                 parent);
663         LDB_REQ_SET_LOCATION(req);
664         if (ret != LDB_SUCCESS) {
665                 talloc_free(tmp_ctx);
666                 return ret;
667         }
668
669         ret = dsdb_request_add_controls(req, dsdb_flags);
670         if (ret != LDB_SUCCESS) {
671                 talloc_free(tmp_ctx);
672                 return ret;
673         }
674
675         if (dsdb_flags & DSDB_FLAG_TRUSTED) {
676                 ldb_req_mark_trusted(req);
677         }
678
679         /* Run the new request */
680         if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) {
681                 ret = ldb_next_request(module, req);
682         } else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
683                 ret = ldb_request(ldb_module_get_ctx(module), req);
684         } else {
685                 const struct ldb_module_ops *ops = ldb_module_get_ops(module);
686                 SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE);
687                 ret = ops->del(module, req);
688         }
689         if (ret == LDB_SUCCESS) {
690                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
691         }
692
693         talloc_free(tmp_ctx);
694         return ret;
695 }
696
697 /*
698   check if a single valued link has multiple non-deleted values
699
700   This is needed when we will be using the RELAX control to stop
701   ldb_tdb from checking single valued links
702  */
703 int dsdb_check_single_valued_link(const struct dsdb_attribute *attr,
704                                   const struct ldb_message_element *el)
705 {
706         bool found_active = false;
707         unsigned int i;
708
709         if (!(attr->ldb_schema_attribute->flags & LDB_ATTR_FLAG_SINGLE_VALUE) ||
710             el->num_values < 2) {
711                 return LDB_SUCCESS;
712         }
713
714         for (i=0; i<el->num_values; i++) {
715                 if (!dsdb_dn_is_deleted_val(&el->values[i])) {
716                         if (found_active) {
717                                 return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
718                         }
719                         found_active = true;
720                 }
721         }
722
723         return LDB_SUCCESS;
724 }
725
726
727 int dsdb_check_samba_compatible_feature(struct ldb_module *module,
728                                         const char *feature,
729                                         bool *found)
730 {
731         struct ldb_context *ldb = ldb_module_get_ctx(module);
732         struct ldb_result *res;
733         static const char * const samba_dsdb_attrs[] = {
734                 SAMBA_COMPATIBLE_FEATURES_ATTR,
735                 NULL
736         };
737         int ret;
738         struct ldb_dn *samba_dsdb_dn = NULL;
739         TALLOC_CTX *tmp_ctx = talloc_new(ldb);
740         if (tmp_ctx == NULL) {
741                 *found = false;
742                 return ldb_oom(ldb);
743         }
744         *found = false;
745
746         samba_dsdb_dn = ldb_dn_new(tmp_ctx, ldb, "@SAMBA_DSDB");
747         if (samba_dsdb_dn == NULL) {
748                 TALLOC_FREE(tmp_ctx);
749                 return ldb_oom(ldb);
750         }
751
752         ret = dsdb_module_search_dn(module,
753                                     tmp_ctx,
754                                     &res,
755                                     samba_dsdb_dn,
756                                     samba_dsdb_attrs,
757                                     DSDB_FLAG_NEXT_MODULE,
758                                     NULL);
759         if (ret == LDB_SUCCESS) {
760                 *found = ldb_msg_check_string_attribute(
761                         res->msgs[0],
762                         SAMBA_COMPATIBLE_FEATURES_ATTR,
763                         feature);
764         } else if (ret == LDB_ERR_NO_SUCH_OBJECT) {
765                 /* it is not an error not to find it */
766                 ret = LDB_SUCCESS;
767         }
768         TALLOC_FREE(tmp_ctx);
769         return ret;
770 }
771
772
773 /*
774   check if an optional feature is enabled on our own NTDS DN
775
776   Note that features can be marked as enabled in more than one
777   place. For example, the recyclebin feature is marked as enabled both
778   on the CN=Partitions,CN=Configuration object and on the NTDS DN of
779   each DC in the forest. It seems likely that it is the job of the KCC
780   to propagate between the two
781  */
782 int dsdb_check_optional_feature(struct ldb_module *module, struct GUID op_feature_guid, bool *feature_enabled)
783 {
784         TALLOC_CTX *tmp_ctx;
785         struct ldb_context *ldb = ldb_module_get_ctx(module);
786         struct ldb_result *res;
787         struct ldb_dn *search_dn;
788         struct GUID search_guid;
789         static const char * const attrs[] = {"msDS-EnabledFeature", NULL};
790         int ret;
791         unsigned int i;
792         struct ldb_message_element *el;
793         struct ldb_dn *feature_dn;
794
795         tmp_ctx = talloc_new(ldb);
796
797         feature_dn = samdb_ntds_settings_dn(ldb_module_get_ctx(module), tmp_ctx);
798         if (feature_dn == NULL) {
799                 talloc_free(tmp_ctx);
800                 return ldb_operr(ldb_module_get_ctx(module));
801         }
802
803         *feature_enabled = false;
804
805         ret = dsdb_module_search_dn(module, tmp_ctx, &res, feature_dn, attrs, DSDB_FLAG_NEXT_MODULE, NULL);
806         if (ret != LDB_SUCCESS) {
807                 ldb_asprintf_errstring(ldb,
808                                 "Could not find the feature object - dn: %s\n",
809                                 ldb_dn_get_linearized(feature_dn));
810                 talloc_free(tmp_ctx);
811                 return LDB_ERR_NO_SUCH_OBJECT;
812         }
813         if (res->msgs[0]->num_elements > 0) {
814                 static const char * const attrs2[] = {"msDS-OptionalFeatureGUID", NULL};
815
816                 el = ldb_msg_find_element(res->msgs[0],"msDS-EnabledFeature");
817
818                 for (i=0; i<el->num_values; i++) {
819                         search_dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &el->values[i]);
820
821                         ret = dsdb_module_search_dn(module, tmp_ctx, &res,
822                                                     search_dn, attrs2, DSDB_FLAG_NEXT_MODULE, NULL);
823                         if (ret != LDB_SUCCESS) {
824                                 ldb_asprintf_errstring(ldb,
825                                                 "Could no find object dn: %s\n",
826                                                 ldb_dn_get_linearized(search_dn));
827                                 talloc_free(tmp_ctx);
828                                 return LDB_ERR_OPERATIONS_ERROR;
829                         }
830
831                         search_guid = samdb_result_guid(res->msgs[0], "msDS-OptionalFeatureGUID");
832
833                         if (GUID_equal(&search_guid, &op_feature_guid)) {
834                                 *feature_enabled = true;
835                                 break;
836                         }
837                 }
838         }
839         talloc_free(tmp_ctx);
840         return LDB_SUCCESS;
841 }
842
843 /*
844   find the NTDS GUID from a computers DN record
845  */
846 int dsdb_module_find_ntdsguid_for_computer(struct ldb_module *module,
847                                            TALLOC_CTX *mem_ctx,
848                                            struct ldb_dn *computer_dn,
849                                            struct GUID *ntds_guid,
850                                            struct ldb_request *parent)
851 {
852         int ret;
853         struct ldb_dn *dn;
854
855         *ntds_guid = GUID_zero();
856
857         ret = dsdb_module_reference_dn(module, mem_ctx, computer_dn,
858                                        "serverReferenceBL", &dn, parent);
859         if (ret != LDB_SUCCESS) {
860                 return ret;
861         }
862
863         if (!ldb_dn_add_child_fmt(dn, "CN=NTDS Settings")) {
864                 talloc_free(dn);
865                 return LDB_ERR_OPERATIONS_ERROR;
866         }
867
868         ret = dsdb_module_guid_by_dn(module, dn, ntds_guid, parent);
869         talloc_free(dn);
870         return ret;
871 }
872
873 /*
874   find a 'reference' DN that points at another object
875   (eg. serverReference, rIDManagerReference etc)
876  */
877 int dsdb_module_reference_dn(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_dn *base,
878                              const char *attribute, struct ldb_dn **dn, struct ldb_request *parent)
879 {
880         const char *attrs[2];
881         struct ldb_result *res;
882         int ret;
883
884         attrs[0] = attribute;
885         attrs[1] = NULL;
886
887         ret = dsdb_module_search_dn(module, mem_ctx, &res, base, attrs,
888                                     DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_EXTENDED_DN, parent);
889         if (ret != LDB_SUCCESS) {
890                 return ret;
891         }
892
893         *dn = ldb_msg_find_attr_as_dn(ldb_module_get_ctx(module),
894                                       mem_ctx, res->msgs[0], attribute);
895         if (!*dn) {
896                 ldb_reset_err_string(ldb_module_get_ctx(module));
897                 talloc_free(res);
898                 return LDB_ERR_NO_SUCH_ATTRIBUTE;
899         }
900
901         talloc_free(res);
902         return LDB_SUCCESS;
903 }
904
905 /*
906   find the RID Manager$ DN via the rIDManagerReference attribute in the
907   base DN
908  */
909 int dsdb_module_rid_manager_dn(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_dn **dn,
910                                struct ldb_request *parent)
911 {
912         return dsdb_module_reference_dn(module, mem_ctx,
913                                         ldb_get_default_basedn(ldb_module_get_ctx(module)),
914                                         "rIDManagerReference", dn, parent);
915 }
916
917 /*
918   used to chain to the callers callback
919  */
920 int dsdb_next_callback(struct ldb_request *req, struct ldb_reply *ares)
921 {
922         struct ldb_request *up_req = talloc_get_type(req->context, struct ldb_request);
923
924         if (!ares) {
925                 return ldb_module_done(up_req, NULL, NULL,
926                                        LDB_ERR_OPERATIONS_ERROR);
927         }
928
929         if (ares->error != LDB_SUCCESS || ares->type == LDB_REPLY_DONE) {
930                 return ldb_module_done(up_req, ares->controls,
931                                        ares->response, ares->error);
932         }
933
934         /* Otherwise pass on the callback */
935         switch (ares->type) {
936         case LDB_REPLY_ENTRY:
937                 return ldb_module_send_entry(up_req, ares->message,
938                                              ares->controls);
939
940         case LDB_REPLY_REFERRAL:
941                 return ldb_module_send_referral(up_req,
942                                                 ares->referral);
943         default:
944                 /* Can't happen */
945                 return LDB_ERR_OPERATIONS_ERROR;
946         }
947 }
948
949 /*
950   load the uSNHighest and the uSNUrgent attributes from the @REPLCHANGED
951   object for a partition
952  */
953 int dsdb_module_load_partition_usn(struct ldb_module *module, struct ldb_dn *dn,
954                                    uint64_t *uSN, uint64_t *urgent_uSN, struct ldb_request *parent)
955 {
956         struct ldb_context *ldb = ldb_module_get_ctx(module);
957         struct ldb_request *req;
958         int ret;
959         TALLOC_CTX *tmp_ctx = talloc_new(module);
960         struct dsdb_control_current_partition *p_ctrl;
961         struct ldb_result *res;
962
963         res = talloc_zero(tmp_ctx, struct ldb_result);
964         if (!res) {
965                 talloc_free(tmp_ctx);
966                 return ldb_module_oom(module);
967         }
968
969         ret = ldb_build_search_req(&req, ldb, tmp_ctx,
970                                    ldb_dn_new(tmp_ctx, ldb, "@REPLCHANGED"),
971                                    LDB_SCOPE_BASE,
972                                    NULL, NULL,
973                                    NULL,
974                                    res, ldb_search_default_callback,
975                                    parent);
976         LDB_REQ_SET_LOCATION(req);
977         if (ret != LDB_SUCCESS) {
978                 talloc_free(tmp_ctx);
979                 return ret;
980         }
981
982         p_ctrl = talloc(req, struct dsdb_control_current_partition);
983         if (p_ctrl == NULL) {
984                 talloc_free(tmp_ctx);
985                 return ldb_module_oom(module);
986         }
987         p_ctrl->version = DSDB_CONTROL_CURRENT_PARTITION_VERSION;
988         p_ctrl->dn = dn;
989
990
991         ret = ldb_request_add_control(req,
992                                       DSDB_CONTROL_CURRENT_PARTITION_OID,
993                                       false, p_ctrl);
994         if (ret != LDB_SUCCESS) {
995                 talloc_free(tmp_ctx);
996                 return ret;
997         }
998
999         /* Run the new request */
1000         ret = ldb_next_request(module, req);
1001
1002         if (ret == LDB_SUCCESS) {
1003                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1004         }
1005
1006         if (ret == LDB_ERR_NO_SUCH_OBJECT || ret == LDB_ERR_INVALID_DN_SYNTAX) {
1007                 /* it hasn't been created yet, which means
1008                    an implicit value of zero */
1009                 *uSN = 0;
1010                 talloc_free(tmp_ctx);
1011                 ldb_reset_err_string(ldb);
1012                 return LDB_SUCCESS;
1013         }
1014
1015         if (ret != LDB_SUCCESS) {
1016                 talloc_free(tmp_ctx);
1017                 return ret;
1018         }
1019
1020         if (res->count != 1) {
1021                 *uSN = 0;
1022                 if (urgent_uSN) {
1023                         *urgent_uSN = 0;
1024                 }
1025         } else {
1026                 *uSN = ldb_msg_find_attr_as_uint64(res->msgs[0], "uSNHighest", 0);
1027                 if (urgent_uSN) {
1028                         *urgent_uSN = ldb_msg_find_attr_as_uint64(res->msgs[0], "uSNUrgent", 0);
1029                 }
1030         }
1031
1032         talloc_free(tmp_ctx);
1033
1034         return LDB_SUCCESS;
1035 }
1036
1037 /*
1038   save uSNHighest and uSNUrgent attributes in the @REPLCHANGED object for a
1039   partition
1040  */
1041 int dsdb_module_save_partition_usn(struct ldb_module *module, struct ldb_dn *dn,
1042                                    uint64_t uSN, uint64_t urgent_uSN,
1043                                    struct ldb_request *parent)
1044 {
1045         struct ldb_context *ldb = ldb_module_get_ctx(module);
1046         struct ldb_request *req;
1047         struct ldb_message *msg;
1048         struct dsdb_control_current_partition *p_ctrl;
1049         int ret;
1050         struct ldb_result *res;
1051
1052         msg = ldb_msg_new(module);
1053         if (msg == NULL) {
1054                 return ldb_module_oom(module);
1055         }
1056
1057         msg->dn = ldb_dn_new(msg, ldb, "@REPLCHANGED");
1058         if (msg->dn == NULL) {
1059                 talloc_free(msg);
1060                 return ldb_operr(ldb_module_get_ctx(module));
1061         }
1062
1063         res = talloc_zero(msg, struct ldb_result);
1064         if (!res) {
1065                 talloc_free(msg);
1066                 return ldb_module_oom(module);
1067         }
1068
1069         ret = samdb_msg_add_uint64(ldb, msg, msg, "uSNHighest", uSN);
1070         if (ret != LDB_SUCCESS) {
1071                 talloc_free(msg);
1072                 return ret;
1073         }
1074         msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
1075
1076         /* urgent_uSN is optional so may not be stored */
1077         if (urgent_uSN) {
1078                 ret = samdb_msg_add_uint64(ldb, msg, msg, "uSNUrgent",
1079                                            urgent_uSN);
1080                 if (ret != LDB_SUCCESS) {
1081                         talloc_free(msg);
1082                         return ret;
1083                 }
1084                 msg->elements[1].flags = LDB_FLAG_MOD_REPLACE;
1085         }
1086
1087
1088         p_ctrl = talloc(msg, struct dsdb_control_current_partition);
1089         if (p_ctrl == NULL) {
1090                 talloc_free(msg);
1091                 return ldb_oom(ldb);
1092         }
1093         p_ctrl->version = DSDB_CONTROL_CURRENT_PARTITION_VERSION;
1094         p_ctrl->dn = dn;
1095         ret = ldb_build_mod_req(&req, ldb, msg,
1096                                 msg,
1097                                 NULL,
1098                                 res,
1099                                 ldb_modify_default_callback,
1100                                 parent);
1101         LDB_REQ_SET_LOCATION(req);
1102 again:
1103         if (ret != LDB_SUCCESS) {
1104                 talloc_free(msg);
1105                 return ret;
1106         }
1107
1108         ret = ldb_request_add_control(req,
1109                                       DSDB_CONTROL_CURRENT_PARTITION_OID,
1110                                       false, p_ctrl);
1111         if (ret != LDB_SUCCESS) {
1112                 talloc_free(msg);
1113                 return ret;
1114         }
1115
1116         /* Run the new request */
1117         ret = ldb_next_request(module, req);
1118
1119         if (ret == LDB_SUCCESS) {
1120                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1121         }
1122         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
1123                 ret = ldb_build_add_req(&req, ldb, msg,
1124                                         msg,
1125                                         NULL,
1126                                         res,
1127                                         ldb_modify_default_callback,
1128                                         parent);
1129                 LDB_REQ_SET_LOCATION(req);
1130                 goto again;
1131         }
1132
1133         talloc_free(msg);
1134
1135         return ret;
1136 }
1137
1138 bool dsdb_module_am_system(struct ldb_module *module)
1139 {
1140         struct ldb_context *ldb = ldb_module_get_ctx(module);
1141         struct auth_session_info *session_info
1142                 = talloc_get_type(
1143                         ldb_get_opaque(ldb, DSDB_SESSION_INFO),
1144                         struct auth_session_info);
1145         return security_session_user_level(session_info, NULL) == SECURITY_SYSTEM;
1146 }
1147
1148 bool dsdb_module_am_administrator(struct ldb_module *module)
1149 {
1150         struct ldb_context *ldb = ldb_module_get_ctx(module);
1151         struct auth_session_info *session_info
1152                 = talloc_get_type(
1153                         ldb_get_opaque(ldb, DSDB_SESSION_INFO),
1154                         struct auth_session_info);
1155         return security_session_user_level(session_info, NULL) == SECURITY_ADMINISTRATOR;
1156 }
1157
1158 /*
1159  * Return â€˜true’ if the caller has system access. The â€˜acl’ module passes
1160  * SYSTEM_CONTROL_STRIP_CRITICAL when it wants to strip the critical flag.
1161  */
1162 bool dsdb_have_system_access(
1163         struct ldb_module *module,
1164         struct ldb_request *req,
1165         const enum system_control_strip_critical strip_critical)
1166 {
1167         struct ldb_control *as_system = NULL;
1168
1169         as_system = ldb_request_get_control(req, LDB_CONTROL_AS_SYSTEM_OID);
1170         if (as_system != NULL) {
1171                 switch (strip_critical) {
1172                 case SYSTEM_CONTROL_KEEP_CRITICAL:
1173                         break;
1174                 case SYSTEM_CONTROL_STRIP_CRITICAL:
1175                         as_system->critical = 0;
1176                         break;
1177                 }
1178
1179                 return true;
1180         }
1181
1182         return dsdb_module_am_system(module);
1183 }
1184
1185 /*
1186   check if the recyclebin is enabled
1187  */
1188 int dsdb_recyclebin_enabled(struct ldb_module *module, bool *enabled)
1189 {
1190         struct ldb_context *ldb = ldb_module_get_ctx(module);
1191         struct GUID recyclebin_guid;
1192         int ret;
1193
1194         GUID_from_string(DS_GUID_FEATURE_RECYCLE_BIN, &recyclebin_guid);
1195
1196         ret = dsdb_check_optional_feature(module, recyclebin_guid, enabled);
1197         if (ret != LDB_SUCCESS) {
1198                 ldb_asprintf_errstring(ldb, "Could not verify if Recycle Bin is enabled \n");
1199                 return ret;
1200         }
1201
1202         return LDB_SUCCESS;
1203 }
1204
1205 int dsdb_msg_constrainted_update_int32(struct ldb_module *module,
1206                                        struct ldb_message *msg,
1207                                        const char *attr,
1208                                        const int32_t *old_val,
1209                                        const int32_t *new_val)
1210 {
1211         struct ldb_message_element *el;
1212         int ret;
1213         char *vstring;
1214
1215         if (old_val) {
1216                 ret = ldb_msg_add_empty(msg, attr, LDB_FLAG_MOD_DELETE, &el);
1217                 if (ret != LDB_SUCCESS) {
1218                         return ret;
1219                 }
1220                 el->num_values = 1;
1221                 el->values = talloc_array(msg, struct ldb_val, el->num_values);
1222                 if (!el->values) {
1223                         return ldb_module_oom(module);
1224                 }
1225                 vstring = talloc_asprintf(el->values, "%ld", (long)*old_val);
1226                 if (!vstring) {
1227                         return ldb_module_oom(module);
1228                 }
1229                 *el->values = data_blob_string_const(vstring);
1230         }
1231
1232         if (new_val) {
1233                 ret = ldb_msg_add_empty(msg, attr, LDB_FLAG_MOD_ADD, &el);
1234                 if (ret != LDB_SUCCESS) {
1235                         return ret;
1236                 }
1237                 el->num_values = 1;
1238                 el->values = talloc_array(msg, struct ldb_val, el->num_values);
1239                 if (!el->values) {
1240                         return ldb_module_oom(module);
1241                 }
1242                 vstring = talloc_asprintf(el->values, "%ld", (long)*new_val);
1243                 if (!vstring) {
1244                         return ldb_module_oom(module);
1245                 }
1246                 *el->values = data_blob_string_const(vstring);
1247         }
1248
1249         return LDB_SUCCESS;
1250 }
1251
1252 int dsdb_msg_constrainted_update_uint32(struct ldb_module *module,
1253                                         struct ldb_message *msg,
1254                                         const char *attr,
1255                                         const uint32_t *old_val,
1256                                         const uint32_t *new_val)
1257 {
1258         return dsdb_msg_constrainted_update_int32(module, msg, attr,
1259                                                   (const int32_t *)old_val,
1260                                                   (const int32_t *)new_val);
1261 }
1262
1263 int dsdb_msg_constrainted_update_int64(struct ldb_module *module,
1264                                        struct ldb_message *msg,
1265                                        const char *attr,
1266                                        const int64_t *old_val,
1267                                        const int64_t *new_val)
1268 {
1269         struct ldb_message_element *el;
1270         int ret;
1271         char *vstring;
1272
1273         if (old_val) {
1274                 ret = ldb_msg_add_empty(msg, attr, LDB_FLAG_MOD_DELETE, &el);
1275                 if (ret != LDB_SUCCESS) {
1276                         return ret;
1277                 }
1278                 el->num_values = 1;
1279                 el->values = talloc_array(msg, struct ldb_val, el->num_values);
1280                 if (!el->values) {
1281                         return ldb_module_oom(module);
1282                 }
1283                 vstring = talloc_asprintf(el->values, "%lld", (long long)*old_val);
1284                 if (!vstring) {
1285                         return ldb_module_oom(module);
1286                 }
1287                 *el->values = data_blob_string_const(vstring);
1288         }
1289
1290         if (new_val) {
1291                 ret = ldb_msg_add_empty(msg, attr, LDB_FLAG_MOD_ADD, &el);
1292                 if (ret != LDB_SUCCESS) {
1293                         return ret;
1294                 }
1295                 el->num_values = 1;
1296                 el->values = talloc_array(msg, struct ldb_val, el->num_values);
1297                 if (!el->values) {
1298                         return ldb_module_oom(module);
1299                 }
1300                 vstring = talloc_asprintf(el->values, "%lld", (long long)*new_val);
1301                 if (!vstring) {
1302                         return ldb_module_oom(module);
1303                 }
1304                 *el->values = data_blob_string_const(vstring);
1305         }
1306
1307         return LDB_SUCCESS;
1308 }
1309
1310 int dsdb_msg_constrainted_update_uint64(struct ldb_module *module,
1311                                         struct ldb_message *msg,
1312                                         const char *attr,
1313                                         const uint64_t *old_val,
1314                                         const uint64_t *new_val)
1315 {
1316         return dsdb_msg_constrainted_update_int64(module, msg, attr,
1317                                                   (const int64_t *)old_val,
1318                                                   (const int64_t *)new_val);
1319 }
1320
1321 /*
1322   update an int32 attribute safely via a constrained delete/add
1323  */
1324 int dsdb_module_constrainted_update_int32(struct ldb_module *module,
1325                                           struct ldb_dn *dn,
1326                                           const char *attr,
1327                                           const int32_t *old_val,
1328                                           const int32_t *new_val,
1329                                           struct ldb_request *parent)
1330 {
1331         struct ldb_message *msg;
1332         int ret;
1333
1334         msg = ldb_msg_new(module);
1335         if (msg == NULL) {
1336                 return ldb_module_oom(module);
1337         }
1338         msg->dn = dn;
1339
1340         ret = dsdb_msg_constrainted_update_int32(module,
1341                                                  msg, attr,
1342                                                  old_val,
1343                                                  new_val);
1344         if (ret != LDB_SUCCESS) {
1345                 talloc_free(msg);
1346                 return ret;
1347         }
1348
1349         ret = dsdb_module_modify(module, msg, DSDB_FLAG_NEXT_MODULE, parent);
1350         talloc_free(msg);
1351         return ret;
1352 }
1353
1354 int dsdb_module_constrainted_update_uint32(struct ldb_module *module,
1355                                            struct ldb_dn *dn,
1356                                            const char *attr,
1357                                            const uint32_t *old_val,
1358                                            const uint32_t *new_val,
1359                                            struct ldb_request *parent)
1360 {
1361         return dsdb_module_constrainted_update_int32(module, dn, attr,
1362                                                      (const int32_t *)old_val,
1363                                                      (const int32_t *)new_val, parent);
1364 }
1365
1366 /*
1367   update an int64 attribute safely via a constrained delete/add
1368  */
1369 int dsdb_module_constrainted_update_int64(struct ldb_module *module,
1370                                           struct ldb_dn *dn,
1371                                           const char *attr,
1372                                           const int64_t *old_val,
1373                                           const int64_t *new_val,
1374                                           struct ldb_request *parent)
1375 {
1376         struct ldb_message *msg;
1377         int ret;
1378
1379         msg = ldb_msg_new(module);
1380         if (msg == NULL) {
1381                 return ldb_module_oom(module);
1382         }
1383         msg->dn = dn;
1384
1385         ret = dsdb_msg_constrainted_update_int64(module,
1386                                                  msg, attr,
1387                                                  old_val,
1388                                                  new_val);
1389         if (ret != LDB_SUCCESS) {
1390                 talloc_free(msg);
1391                 return ret;
1392         }
1393
1394         ret = dsdb_module_modify(module, msg, DSDB_FLAG_NEXT_MODULE, parent);
1395         talloc_free(msg);
1396         return ret;
1397 }
1398
1399 int dsdb_module_constrainted_update_uint64(struct ldb_module *module,
1400                                            struct ldb_dn *dn,
1401                                            const char *attr,
1402                                            const uint64_t *old_val,
1403                                            const uint64_t *new_val,
1404                                            struct ldb_request *parent)
1405 {
1406         return dsdb_module_constrainted_update_int64(module, dn, attr,
1407                                                      (const int64_t *)old_val,
1408                                                      (const int64_t *)new_val,
1409                                                      parent);
1410 }
1411
1412
1413 const struct ldb_val *dsdb_module_find_dsheuristics(struct ldb_module *module,
1414                                                     TALLOC_CTX *mem_ctx, struct ldb_request *parent)
1415 {
1416         int ret;
1417         struct ldb_dn *new_dn;
1418         struct ldb_context *ldb = ldb_module_get_ctx(module);
1419         static const char * const attrs[] = { "dSHeuristics", NULL };
1420         struct ldb_result *res;
1421
1422         new_dn = ldb_dn_copy(mem_ctx, ldb_get_config_basedn(ldb));
1423         if (!ldb_dn_add_child_fmt(new_dn,
1424                                    "CN=Directory Service,CN=Windows NT,CN=Services")) {
1425                 talloc_free(new_dn);
1426                 return NULL;
1427         }
1428         ret = dsdb_module_search_dn(module, mem_ctx, &res,
1429                                     new_dn,
1430                                     attrs,
1431                                     DSDB_FLAG_NEXT_MODULE,
1432                                     parent);
1433         if (ret == LDB_SUCCESS && res->count == 1) {
1434                 talloc_free(new_dn);
1435                 return ldb_msg_find_ldb_val(res->msgs[0],
1436                                             "dSHeuristics");
1437         }
1438         talloc_free(new_dn);
1439         return NULL;
1440 }
1441
1442 bool dsdb_block_anonymous_ops(struct ldb_module *module, struct ldb_request *parent)
1443 {
1444         TALLOC_CTX *tmp_ctx = talloc_new(module);
1445         bool result;
1446         const struct ldb_val *hr_val = dsdb_module_find_dsheuristics(module,
1447                                                                      tmp_ctx, parent);
1448         if (hr_val == NULL || hr_val->length < DS_HR_BLOCK_ANONYMOUS_OPS) {
1449                 result = true;
1450         } else if (hr_val->data[DS_HR_BLOCK_ANONYMOUS_OPS -1] == '2') {
1451                 result = false;
1452         } else {
1453                 result = true;
1454         }
1455
1456         talloc_free(tmp_ctx);
1457         return result;
1458 }
1459
1460 bool dsdb_user_password_support(struct ldb_module *module,
1461                                 TALLOC_CTX *mem_ctx,
1462                                 struct ldb_request *parent)
1463 {
1464         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1465         bool result;
1466         const struct ldb_val *hr_val = dsdb_module_find_dsheuristics(module,
1467                                                                      tmp_ctx,
1468                                                                      parent);
1469         if (hr_val == NULL || hr_val->length < DS_HR_USER_PASSWORD_SUPPORT) {
1470                 result = false;
1471         } else if ((hr_val->data[DS_HR_USER_PASSWORD_SUPPORT -1] == '2') ||
1472                    (hr_val->data[DS_HR_USER_PASSWORD_SUPPORT -1] == '0')) {
1473                 result = false;
1474         } else {
1475                 result = true;
1476         }
1477
1478         talloc_free(tmp_ctx);
1479         return result;
1480 }
1481
1482 bool dsdb_do_list_object(struct ldb_module *module,
1483                          TALLOC_CTX *mem_ctx,
1484                          struct ldb_request *parent)
1485 {
1486         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1487         bool result;
1488         const struct ldb_val *hr_val = dsdb_module_find_dsheuristics(module,
1489                                                                      tmp_ctx,
1490                                                                      parent);
1491         if (hr_val == NULL || hr_val->length < DS_HR_DOLISTOBJECT) {
1492                 result = false;
1493         } else if (hr_val->data[DS_HR_DOLISTOBJECT -1] == '1') {
1494                 result = true;
1495         } else {
1496                 result = false;
1497         }
1498
1499         talloc_free(tmp_ctx);
1500         return result;
1501 }
1502
1503 bool dsdb_attribute_authz_on_ldap_add(struct ldb_module *module,
1504                                       TALLOC_CTX *mem_ctx,
1505                                       struct ldb_request *parent)
1506 {
1507         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1508         bool result = false;
1509         const struct ldb_val *hr_val = dsdb_module_find_dsheuristics(module,
1510                                                                      tmp_ctx,
1511                                                                      parent);
1512         if (hr_val != NULL && hr_val->length >= DS_HR_ATTR_AUTHZ_ON_LDAP_ADD) {
1513                 uint8_t val = hr_val->data[DS_HR_ATTR_AUTHZ_ON_LDAP_ADD - 1];
1514                 if (val != '0' && val != '2') {
1515                         result = true;
1516                 }
1517         }
1518
1519         talloc_free(tmp_ctx);
1520         return result;
1521 }
1522
1523 bool dsdb_block_owner_implicit_rights(struct ldb_module *module,
1524                                       TALLOC_CTX *mem_ctx,
1525                                       struct ldb_request *parent)
1526 {
1527         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1528         bool result = false;
1529         const struct ldb_val *hr_val = dsdb_module_find_dsheuristics(module,
1530                                                                      tmp_ctx,
1531                                                                      parent);
1532         if (hr_val != NULL && hr_val->length >= DS_HR_BLOCK_OWNER_IMPLICIT_RIGHTS) {
1533                 uint8_t val = hr_val->data[DS_HR_BLOCK_OWNER_IMPLICIT_RIGHTS - 1];
1534                 if (val != '0' && val != '2') {
1535                         result = true;
1536                 }
1537         }
1538
1539         talloc_free(tmp_ctx);
1540         return result;
1541 }
1542
1543 /*
1544   show the chain of requests, useful for debugging async requests
1545  */
1546 void dsdb_req_chain_debug(struct ldb_request *req, int level)
1547 {
1548         char *s = ldb_module_call_chain(req, req);
1549         DEBUG(level, ("%s\n", s));
1550         talloc_free(s);
1551 }
1552
1553 /*
1554  * Get all the values that *might* be added by an ldb message, as a composite
1555  * ldb element.
1556  *
1557  * This is useful when we need to check all the possible values against some
1558  * criteria.
1559  *
1560  * In cases where a modify message mixes multiple ADDs, DELETEs, and REPLACES,
1561  * the returned element might contain more values than would actually end up
1562  * in the database if the message was run to its conclusion.
1563  *
1564  * If the operation is not LDB_ADD or LDB_MODIFY, an operations error is
1565  * returned.
1566  *
1567  * The returned element might not be new, and should not be modified or freed
1568  * before the message is finished.
1569  */
1570
1571 int dsdb_get_expected_new_values(TALLOC_CTX *mem_ctx,
1572                                  const struct ldb_message *msg,
1573                                  const char *attr_name,
1574                                  struct ldb_message_element **el,
1575                                  enum ldb_request_type operation)
1576 {
1577         unsigned int i;
1578         unsigned int el_count = 0;
1579         unsigned int val_count = 0;
1580         struct ldb_val *v = NULL;
1581         struct ldb_message_element *_el = NULL;
1582         *el = NULL;
1583
1584         if (operation != LDB_ADD && operation != LDB_MODIFY) {
1585                 DBG_ERR("inapplicable operation type: %d\n", operation);
1586                 return LDB_ERR_OPERATIONS_ERROR;
1587         }
1588
1589         /* count the adding or replacing elements */
1590         for (i = 0; i < msg->num_elements; i++) {
1591                 if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) {
1592                         unsigned int tmp;
1593                         if ((operation == LDB_MODIFY) &&
1594                             (LDB_FLAG_MOD_TYPE(msg->elements[i].flags)
1595                                                 == LDB_FLAG_MOD_DELETE)) {
1596                                 continue;
1597                         }
1598                         el_count++;
1599                         tmp = val_count + msg->elements[i].num_values;
1600                         if (unlikely(tmp < val_count)) {
1601                                 DBG_ERR("too many values for one element!\n");
1602                                 return LDB_ERR_OPERATIONS_ERROR;
1603                         }
1604                         val_count = tmp;
1605                 }
1606         }
1607         if (el_count == 0) {
1608                 /* nothing to see here */
1609                 return LDB_SUCCESS;
1610         }
1611
1612         if (el_count == 1 || val_count == 0) {
1613                 /*
1614                  * There is one effective element, which we can return as-is,
1615                  * OR there are only elements with zero values -- any of which
1616                  * will do.
1617                  */
1618                 for (i = 0; i < msg->num_elements; i++) {
1619                         if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) {
1620                                 if ((operation == LDB_MODIFY) &&
1621                                     (LDB_FLAG_MOD_TYPE(msg->elements[i].flags)
1622                                      == LDB_FLAG_MOD_DELETE)) {
1623                                         continue;
1624                                 }
1625                                 *el = &msg->elements[i];
1626                                 return LDB_SUCCESS;
1627                         }
1628                 }
1629         }
1630
1631         _el = talloc_zero(mem_ctx, struct ldb_message_element);
1632         if (_el == NULL) {
1633                 return LDB_ERR_OPERATIONS_ERROR;
1634         }
1635         _el->name = attr_name;
1636
1637         if (val_count == 0) {
1638                 /*
1639                  * Seems unlikely, but sometimes we might be adding zero
1640                  * values in multiple separate elements. The talloc zero has
1641                  * already set the expected values = NULL, num_values = 0.
1642                  */
1643                 *el = _el;
1644                 return LDB_SUCCESS;
1645         }
1646
1647         _el->values = talloc_array(_el, struct ldb_val, val_count);
1648         if (_el->values == NULL) {
1649                 talloc_free(_el);
1650                 return LDB_ERR_OPERATIONS_ERROR;
1651         }
1652         _el->num_values = val_count;
1653
1654         v = _el->values;
1655
1656         for (i = 0; i < msg->num_elements; i++) {
1657                 if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) {
1658                         const struct ldb_message_element *tmp_el = &msg->elements[i];
1659                         if ((operation == LDB_MODIFY) &&
1660                             (LDB_FLAG_MOD_TYPE(tmp_el->flags)
1661                                                 == LDB_FLAG_MOD_DELETE)) {
1662                                 continue;
1663                         }
1664                         if (tmp_el->values == NULL || tmp_el->num_values == 0) {
1665                                 continue;
1666                         }
1667                         memcpy(v,
1668                                tmp_el->values,
1669                                tmp_el->num_values * sizeof(*v));
1670                         v += tmp_el->num_values;
1671                 }
1672         }
1673
1674         *el = _el;
1675         return LDB_SUCCESS;
1676 }
1677
1678
1679 /*
1680  * Get the value of a single-valued attribute from an ADDed message. 'val' will only live as
1681  * long as 'msg' and 'original_val' do, and must not be freed.
1682  */
1683 int dsdb_msg_add_get_single_value(const struct ldb_message *msg,
1684                                   const char *attr_name,
1685                                   const struct ldb_val **val)
1686 {
1687         const struct ldb_message_element *el = NULL;
1688
1689         /*
1690          * The ldb_msg_normalize() call in ldb_request() ensures that
1691          * there is at most one message element for each
1692          * attribute. Thus, we don't need a loop to deal with an
1693          * LDB_ADD.
1694          */
1695         el = ldb_msg_find_element(msg, attr_name);
1696         if (el == NULL) {
1697                 *val = NULL;
1698                 return LDB_SUCCESS;
1699         }
1700         if (el->num_values != 1) {
1701                 return LDB_ERR_CONSTRAINT_VIOLATION;
1702         }
1703
1704         *val = &el->values[0];
1705         return LDB_SUCCESS;
1706 }
1707
1708 /*
1709  * Get the value of a single-valued attribute after processing a
1710  * message. 'operation' is either LDB_ADD or LDB_MODIFY. 'val' will only live as
1711  * long as 'msg' and 'original_val' do, and must not be freed.
1712  */
1713 int dsdb_msg_get_single_value(const struct ldb_message *msg,
1714                               const char *attr_name,
1715                               const struct ldb_val *original_val,
1716                               const struct ldb_val **val,
1717                               enum ldb_request_type operation)
1718 {
1719         unsigned idx;
1720
1721         *val = NULL;
1722
1723         if (operation == LDB_ADD) {
1724                 if (original_val != NULL) {
1725                         /* This is an error on the caller's part. */
1726                         return LDB_ERR_CONSTRAINT_VIOLATION;
1727                 }
1728                 return dsdb_msg_add_get_single_value(msg, attr_name, val);
1729         }
1730
1731         SMB_ASSERT(operation == LDB_MODIFY);
1732
1733         *val = original_val;
1734
1735         for (idx = 0; idx < msg->num_elements; ++idx) {
1736                 const struct ldb_message_element *el = &msg->elements[idx];
1737
1738                 if (ldb_attr_cmp(el->name, attr_name) != 0) {
1739                         continue;
1740                 }
1741
1742                 switch (el->flags & LDB_FLAG_MOD_MASK) {
1743                 case LDB_FLAG_MOD_ADD:
1744                         if (el->num_values != 1) {
1745                                 return LDB_ERR_CONSTRAINT_VIOLATION;
1746                         }
1747                         if (*val != NULL) {
1748                                 return LDB_ERR_CONSTRAINT_VIOLATION;
1749                         }
1750
1751                         *val = &el->values[0];
1752
1753                         break;
1754
1755                 case LDB_FLAG_MOD_REPLACE:
1756                         if (el->num_values > 1) {
1757                                 return LDB_ERR_CONSTRAINT_VIOLATION;
1758                         }
1759
1760                         *val = el->num_values ? &el->values[0] : NULL;
1761
1762                         break;
1763
1764                 case LDB_FLAG_MOD_DELETE:
1765                         if (el->num_values > 1) {
1766                                 return LDB_ERR_CONSTRAINT_VIOLATION;
1767                         }
1768
1769                         /*
1770                          * If a value was specified for the delete, we don't
1771                          * bother checking it matches the value we currently
1772                          * have. Any mismatch will be caught later (e.g. in
1773                          * ldb_kv_modify_internal).
1774                          */
1775
1776                         *val = NULL;
1777
1778                         break;
1779                 }
1780         }
1781
1782         return LDB_SUCCESS;
1783 }
1784
1785 /*
1786  * This function determines the (last) structural or 88 object class of a passed
1787  * "objectClass" attribute - per MS-ADTS 3.1.1.1.4 this is the last value.
1788  * Without schema this does not work and hence NULL is returned.
1789  */
1790 const struct dsdb_class *dsdb_get_last_structural_class(const struct dsdb_schema *schema,
1791                                                         const struct ldb_message_element *element)
1792 {
1793         const struct dsdb_class *last_class;
1794
1795         if (schema == NULL) {
1796                 return NULL;
1797         }
1798
1799         if (element->num_values == 0) {
1800                 return NULL;
1801         }
1802
1803         last_class = dsdb_class_by_lDAPDisplayName_ldb_val(schema,
1804                                                            &element->values[element->num_values-1]);
1805         if (last_class == NULL) {
1806                 return NULL;
1807         }
1808         if (last_class->objectClassCategory > 1) {
1809                 return NULL;
1810         }
1811
1812         return last_class;
1813 }
1814
1815 const struct dsdb_class *dsdb_get_structural_oc_from_msg(const struct dsdb_schema *schema,
1816                                                          const struct ldb_message *msg)
1817 {
1818         struct ldb_message_element *oc_el;
1819
1820         oc_el = ldb_msg_find_element(msg, "objectClass");
1821         if (!oc_el) {
1822                 return NULL;
1823         }
1824
1825         return dsdb_get_last_structural_class(schema, oc_el);
1826 }
1827
1828 /*
1829   Get the parent class of an objectclass, or NULL if none exists.
1830  */
1831 const struct dsdb_class *dsdb_get_parent_class(const struct dsdb_schema *schema,
1832                                                const struct dsdb_class *objectclass)
1833 {
1834         if (ldb_attr_cmp(objectclass->lDAPDisplayName, "top") == 0) {
1835                 return NULL;
1836         }
1837
1838         if (objectclass->subClassOf == NULL) {
1839                 return NULL;
1840         }
1841
1842         return dsdb_class_by_lDAPDisplayName(schema, objectclass->subClassOf);
1843 }
1844
1845 /*
1846   Return true if 'struct_objectclass' is a subclass of 'other_objectclass'. The
1847   two objectclasses must originate from the same schema, to allow for
1848   pointer-based identity comparison.
1849  */
1850 bool dsdb_is_subclass_of(const struct dsdb_schema *schema,
1851                          const struct dsdb_class *struct_objectclass,
1852                          const struct dsdb_class *other_objectclass)
1853 {
1854         while (struct_objectclass != NULL) {
1855                 /* Pointer comparison can be used due to the same schema str. */
1856                 if (struct_objectclass == other_objectclass) {
1857                         return true;
1858                 }
1859
1860                 struct_objectclass = dsdb_get_parent_class(schema, struct_objectclass);
1861         }
1862
1863         return false;
1864 }
1865
1866 /* Fix the DN so that the relative attribute names are in upper case so that the DN:
1867    cn=Administrator,cn=users,dc=samba,dc=example,dc=com becomes
1868    CN=Administrator,CN=users,DC=samba,DC=example,DC=com
1869 */
1870 int dsdb_fix_dn_rdncase(struct ldb_context *ldb, struct ldb_dn *dn)
1871 {
1872         int i, ret;
1873         char *upper_rdn_attr;
1874
1875         for (i=0; i < ldb_dn_get_comp_num(dn); i++) {
1876                 /* We need the attribute name in upper case */
1877                 upper_rdn_attr = strupper_talloc(dn,
1878                                                  ldb_dn_get_component_name(dn, i));
1879                 if (!upper_rdn_attr) {
1880                         return ldb_oom(ldb);
1881                 }
1882                 ret = ldb_dn_set_component(dn, i, upper_rdn_attr,
1883                                            *ldb_dn_get_component_val(dn, i));
1884                 talloc_free(upper_rdn_attr);
1885                 if (ret != LDB_SUCCESS) {
1886                         return ret;
1887                 }
1888         }
1889         return LDB_SUCCESS;
1890 }
1891
1892 /**
1893  * Make most specific objectCategory for the objectClass of passed object
1894  * NOTE: In this implementation we count that it is called on already
1895  * verified objectClass attribute value. See objectclass.c thorough
1896  * implementation for all the magic that involves
1897  *
1898  * @param ldb   ldb context
1899  * @param schema cached schema for ldb. We may get it, but it is very time consuming.
1900  *                      Hence leave the responsibility to the caller.
1901  * @param obj   AD object to determine objectCategory for
1902  * @param mem_ctx Memory context - usually it is obj actually
1903  * @param pobjectcategory location to store found objectCategory
1904  *
1905  * @return LDB_SUCCESS or error including out of memory error
1906  */
1907 int dsdb_make_object_category(struct ldb_context *ldb, const struct dsdb_schema *schema,
1908                               const struct ldb_message *obj,
1909                               TALLOC_CTX *mem_ctx, const char **pobjectcategory)
1910 {
1911         const struct dsdb_class                 *objectclass;
1912         struct ldb_message_element              *objectclass_element;
1913         struct dsdb_extended_dn_store_format    *dn_format;
1914
1915         objectclass_element = ldb_msg_find_element(obj, "objectClass");
1916         if (!objectclass_element) {
1917                 ldb_asprintf_errstring(ldb, "dsdb: Cannot add %s, no objectclass specified!",
1918                                        ldb_dn_get_linearized(obj->dn));
1919                 return LDB_ERR_OBJECT_CLASS_VIOLATION;
1920         }
1921         if (objectclass_element->num_values == 0) {
1922                 ldb_asprintf_errstring(ldb, "dsdb: Cannot add %s, at least one (structural) objectclass has to be specified!",
1923                                        ldb_dn_get_linearized(obj->dn));
1924                 return LDB_ERR_CONSTRAINT_VIOLATION;
1925         }
1926
1927         /*
1928          * Get the new top-most structural object class and check for
1929          * unrelated structural classes
1930          */
1931         objectclass = dsdb_get_last_structural_class(schema,
1932                                                      objectclass_element);
1933         if (objectclass == NULL) {
1934                 ldb_asprintf_errstring(ldb,
1935                                        "Failed to find a structural class for %s",
1936                                        ldb_dn_get_linearized(obj->dn));
1937                 return LDB_ERR_UNWILLING_TO_PERFORM;
1938         }
1939
1940         dn_format = talloc_get_type(ldb_get_opaque(ldb, DSDB_EXTENDED_DN_STORE_FORMAT_OPAQUE_NAME),
1941                                     struct dsdb_extended_dn_store_format);
1942         if (dn_format && dn_format->store_extended_dn_in_ldb == false) {
1943                 /* Strip off extended components */
1944                 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb,
1945                                                objectclass->defaultObjectCategory);
1946                 *pobjectcategory = ldb_dn_alloc_linearized(mem_ctx, dn);
1947                 talloc_free(dn);
1948         } else {
1949                 *pobjectcategory = talloc_strdup(mem_ctx, objectclass->defaultObjectCategory);
1950         }
1951
1952         if (*pobjectcategory == NULL) {
1953                 return ldb_oom(ldb);
1954         }
1955
1956         return LDB_SUCCESS;
1957 }
1958
1959 /*
1960  * Remove all password related attributes.
1961  */
1962 void dsdb_remove_password_related_attrs(struct ldb_message *msg,
1963                                         bool userPassword)
1964 {
1965         if (userPassword) {
1966                 ldb_msg_remove_attr(msg, "userPassword");
1967         }
1968         ldb_msg_remove_attr(msg, "clearTextPassword");
1969         ldb_msg_remove_attr(msg, "unicodePwd");
1970         ldb_msg_remove_attr(msg, "ntPwdHistory");
1971         ldb_msg_remove_attr(msg, "dBCSPwd");
1972         ldb_msg_remove_attr(msg, "lmPwdHistory");
1973         ldb_msg_remove_attr(msg, "supplementalCredentials");
1974         ldb_msg_remove_attr(msg, "pwdLastSet");
1975 }