s4:samldb LDB module - update the copyright notice
[samba.git] / source4 / dsdb / samdb / ldb_modules / samldb.c
1 /*
2    SAM ldb module
3
4    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
5    Copyright (C) Simo Sorce  2004-2008
6    Copyright (C) Matthias Dieter Wallnöfer 2009-2010
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 /*
23  *  Name: ldb
24  *
25  *  Component: ldb samldb module
26  *
27  *  Description: add embedded user/group creation functionality
28  *
29  *  Author: Simo Sorce
30  */
31
32 #include "includes.h"
33 #include "libcli/ldap/ldap_ndr.h"
34 #include "ldb_module.h"
35 #include "dsdb/samdb/samdb.h"
36 #include "dsdb/samdb/ldb_modules/util.h"
37 #include "libcli/security/security.h"
38 #include "librpc/gen_ndr/ndr_security.h"
39 #include "../lib/util/util_ldb.h"
40 #include "ldb_wrap.h"
41 #include "param/param.h"
42
43 struct samldb_ctx;
44
45 typedef int (*samldb_step_fn_t)(struct samldb_ctx *);
46
47 struct samldb_step {
48         struct samldb_step *next;
49         samldb_step_fn_t fn;
50 };
51
52 struct samldb_ctx {
53         struct ldb_module *module;
54         struct ldb_request *req;
55
56         /* used for add operations */
57         const char *type;
58
59         /* the resulting message */
60         struct ldb_message *msg;
61
62         /* holds the entry SID */
63         struct dom_sid *sid;
64
65         /* holds a generic dn */
66         struct ldb_dn *dn;
67
68         /* used in conjunction with "sid" in "samldb_dn_from_sid" */
69         struct ldb_dn *res_dn;
70
71         /* used in conjunction with "dn" in "samldb_sid_from_dn" */
72         struct dom_sid *res_sid;
73
74         /* used in "samldb_user_dn_to_prim_group_rid" */
75         uint32_t prim_group_rid;
76
77         /* used in conjunction with "prim_group_rid" in
78          * "samldb_prim_group_rid_to_users_cnt" */
79         unsigned int users_cnt;
80
81         /* used in "samldb_group_add_member" and "samldb_group_del_member" */
82         struct ldb_dn *group_dn;
83         struct ldb_dn *member_dn;
84
85         /* used in "samldb_primary_group_change" */
86         struct ldb_dn *user_dn;
87         struct ldb_dn *old_prim_group_dn, *new_prim_group_dn;
88
89         /* generic counter - used in "samldb_member_check" */
90         unsigned int cnt;
91
92         /* all the async steps necessary to complete the operation */
93         struct samldb_step *steps;
94         struct samldb_step *curstep;
95
96         /* If someone set an ares to forward controls and response back to the caller */
97         struct ldb_reply *ares;
98 };
99
100 static struct samldb_ctx *samldb_ctx_init(struct ldb_module *module,
101                                           struct ldb_request *req)
102 {
103         struct ldb_context *ldb;
104         struct samldb_ctx *ac;
105
106         ldb = ldb_module_get_ctx(module);
107
108         ac = talloc_zero(req, struct samldb_ctx);
109         if (ac == NULL) {
110                 ldb_oom(ldb);
111                 return NULL;
112         }
113
114         ac->module = module;
115         ac->req = req;
116
117         return ac;
118 }
119
120 static int samldb_add_step(struct samldb_ctx *ac, samldb_step_fn_t fn)
121 {
122         struct samldb_step *step, *stepper;
123
124         step = talloc_zero(ac, struct samldb_step);
125         if (step == NULL) {
126                 return LDB_ERR_OPERATIONS_ERROR;
127         }
128
129         step->fn = fn;
130
131         if (ac->steps == NULL) {
132                 ac->steps = step;
133                 ac->curstep = step;
134         } else {
135                 if (ac->curstep == NULL)
136                         return LDB_ERR_OPERATIONS_ERROR;
137                 for (stepper = ac->curstep; stepper->next != NULL;
138                         stepper = stepper->next);
139                 stepper->next = step;
140         }
141
142         return LDB_SUCCESS;
143 }
144
145 static int samldb_first_step(struct samldb_ctx *ac)
146 {
147         if (ac->steps == NULL) {
148                 return LDB_ERR_OPERATIONS_ERROR;
149         }
150
151         ac->curstep = ac->steps;
152         return ac->curstep->fn(ac);
153 }
154
155 static int samldb_next_step(struct samldb_ctx *ac)
156 {
157         if (ac->curstep->next) {
158                 ac->curstep = ac->curstep->next;
159                 return ac->curstep->fn(ac);
160         }
161
162         /* we exit the samldb module here */
163         /* If someone set an ares to forward controls and response back to the caller, use them */
164         if (ac->ares) {
165                 return ldb_module_done(ac->req, ac->ares->controls,
166                                        ac->ares->response, LDB_SUCCESS);
167         } else {
168                 return ldb_module_done(ac->req, NULL, NULL, LDB_SUCCESS);
169         }
170 }
171
172 static int samldb_generate_samAccountName(struct ldb_message *msg)
173 {
174         char *name;
175
176         /* Format: $000000-000000000000 */
177
178         name = talloc_asprintf(msg, "$%.6X-%.6X%.6X",
179                                 (unsigned int)generate_random(),
180                                 (unsigned int)generate_random(),
181                                 (unsigned int)generate_random());
182         if (name == NULL) {
183                 return LDB_ERR_OPERATIONS_ERROR;
184         }
185         return ldb_msg_add_steal_string(msg, "samAccountName", name);
186 }
187
188 /*
189  * samldb_check_samAccountName (async)
190  */
191
192 static int samldb_check_samAccountName_callback(struct ldb_request *req,
193                                                 struct ldb_reply *ares)
194 {
195         struct samldb_ctx *ac;
196         int ret;
197
198         ac = talloc_get_type(req->context, struct samldb_ctx);
199
200         if (ares->error != LDB_SUCCESS) {
201                 return ldb_module_done(ac->req, ares->controls,
202                                        ares->response, ares->error);
203         }
204
205         switch (ares->type) {
206         case LDB_REPLY_ENTRY:
207                 /* if we get an entry it means this samAccountName
208                  * already exists */
209                 return ldb_module_done(ac->req, NULL, NULL,
210                                        LDB_ERR_ENTRY_ALREADY_EXISTS);
211
212         case LDB_REPLY_REFERRAL:
213                 /* ignore */
214                 talloc_free(ares);
215                 ret = LDB_SUCCESS;
216                 break;
217
218         case LDB_REPLY_DONE:
219                 /* not found, go on */
220                 talloc_free(ares);
221                 ret = samldb_next_step(ac);
222                 break;
223         }
224
225         if (ret != LDB_SUCCESS) {
226                 return ldb_module_done(ac->req, NULL, NULL, ret);
227         }
228
229         return LDB_SUCCESS;
230 }
231
232 static int samldb_check_samAccountName(struct samldb_ctx *ac)
233 {
234         struct ldb_context *ldb;
235         struct ldb_request *req;
236         const char *name;
237         char *filter;
238         int ret;
239
240         ldb = ldb_module_get_ctx(ac->module);
241
242         if (ldb_msg_find_element(ac->msg, "samAccountName") == NULL) {
243                 ret = samldb_generate_samAccountName(ac->msg);
244                 if (ret != LDB_SUCCESS) {
245                         return ret;
246                 }
247         }
248
249         name = ldb_msg_find_attr_as_string(ac->msg, "samAccountName", NULL);
250         if (name == NULL) {
251                 return LDB_ERR_OPERATIONS_ERROR;
252         }
253         filter = talloc_asprintf(ac, "samAccountName=%s",
254                                  ldb_binary_encode_string(ac, name));
255         if (filter == NULL) {
256                 return LDB_ERR_OPERATIONS_ERROR;
257         }
258
259         ret = ldb_build_search_req(&req, ldb, ac,
260                                    ldb_get_default_basedn(ldb),
261                                    LDB_SCOPE_SUBTREE,
262                                    filter, NULL,
263                                    NULL,
264                                    ac, samldb_check_samAccountName_callback,
265                                    ac->req);
266         talloc_free(filter);
267         if (ret != LDB_SUCCESS) {
268                 return ret;
269         }
270         return ldb_next_request(ac->module, req);
271 }
272
273
274 static int samldb_check_samAccountType(struct samldb_ctx *ac)
275 {
276         struct ldb_context *ldb;
277         unsigned int account_type;
278         unsigned int group_type;
279         unsigned int uac;
280         int ret;
281
282         ldb = ldb_module_get_ctx(ac->module);
283
284         /* make sure sAMAccountType is not specified */
285         if (ldb_msg_find_element(ac->msg, "sAMAccountType") != NULL) {
286                 ldb_asprintf_errstring(ldb,
287                         "sAMAccountType must not be specified!");
288                 return LDB_ERR_UNWILLING_TO_PERFORM;
289         }
290
291         if (strcmp("user", ac->type) == 0) {
292                 uac = samdb_result_uint(ac->msg, "userAccountControl", 0);
293                 if (uac == 0) {
294                         ldb_asprintf_errstring(ldb,
295                                 "userAccountControl invalid!");
296                         return LDB_ERR_UNWILLING_TO_PERFORM;
297                 } else {
298                         account_type = ds_uf2atype(uac);
299                         ret = samdb_msg_add_uint(ldb,
300                                                  ac->msg, ac->msg,
301                                                  "sAMAccountType",
302                                                  account_type);
303                         if (ret != LDB_SUCCESS) {
304                                 return ret;
305                         }
306                 }
307         } else
308         if (strcmp("group", ac->type) == 0) {
309
310                 group_type = samdb_result_uint(ac->msg, "groupType", 0);
311                 if (group_type == 0) {
312                         ldb_asprintf_errstring(ldb,
313                                 "groupType invalid!\n");
314                         return LDB_ERR_UNWILLING_TO_PERFORM;
315                 } else {
316                         account_type = ds_gtype2atype(group_type);
317                         ret = samdb_msg_add_uint(ldb,
318                                                  ac->msg, ac->msg,
319                                                  "sAMAccountType",
320                                                  account_type);
321                         if (ret != LDB_SUCCESS) {
322                                 return ret;
323                         }
324                 }
325         }
326
327         return samldb_next_step(ac);
328 }
329
330 static bool samldb_msg_add_sid(struct ldb_message *msg,
331                                 const char *name,
332                                 const struct dom_sid *sid)
333 {
334         struct ldb_val v;
335         enum ndr_err_code ndr_err;
336
337         ndr_err = ndr_push_struct_blob(&v, msg, NULL, sid,
338                                        (ndr_push_flags_fn_t)ndr_push_dom_sid);
339         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
340                 return false;
341         }
342         return (ldb_msg_add_value(msg, name, &v, NULL) == 0);
343 }
344
345
346 /* allocate a SID using our RID Set */
347 static int samldb_allocate_sid(struct samldb_ctx *ac)
348 {
349         uint32_t rid;
350         int ret;
351         struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
352
353         ret = ridalloc_allocate_rid(ac->module, &rid);
354         if (ret != LDB_SUCCESS) {
355                 return ret;
356         }
357
358         ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid);
359         if (ac->sid == NULL) {
360                 ldb_module_oom(ac->module);
361                 return LDB_ERR_OPERATIONS_ERROR;
362         }
363
364         if ( ! samldb_msg_add_sid(ac->msg, "objectSid", ac->sid)) {
365                 return LDB_ERR_OPERATIONS_ERROR;
366         }
367
368         return samldb_next_step(ac);
369 }
370
371 /*
372  * samldb_dn_from_sid (async)
373  */
374
375 static int samldb_dn_from_sid(struct samldb_ctx *ac);
376
377 static int samldb_dn_from_sid_callback(struct ldb_request *req,
378         struct ldb_reply *ares)
379 {
380         struct ldb_context *ldb;
381         struct samldb_ctx *ac;
382         int ret;
383
384         ac = talloc_get_type(req->context, struct samldb_ctx);
385         ldb = ldb_module_get_ctx(ac->module);
386
387         if (!ares) {
388                 ret = LDB_ERR_OPERATIONS_ERROR;
389                 goto done;
390         }
391         if (ares->error != LDB_SUCCESS) {
392                 return ldb_module_done(ac->req, ares->controls,
393                                         ares->response, ares->error);
394         }
395
396         switch (ares->type) {
397         case LDB_REPLY_ENTRY:
398                 /* save entry */
399                 if (ac->res_dn != NULL) {
400                         /* one too many! */
401                         ldb_set_errstring(ldb,
402                                 "Invalid number of results while searching "
403                                 "for domain objects!");
404                         ret = LDB_ERR_OPERATIONS_ERROR;
405                         break;
406                 }
407                 ac->res_dn = ldb_dn_copy(ac, ares->message->dn);
408
409                 talloc_free(ares);
410                 ret = LDB_SUCCESS;
411                 break;
412
413         case LDB_REPLY_REFERRAL:
414                 /* ignore */
415                 talloc_free(ares);
416                 ret = LDB_SUCCESS;
417                 break;
418
419         case LDB_REPLY_DONE:
420                 talloc_free(ares);
421
422                 /* found or not found, go on */
423                 ret = samldb_next_step(ac);
424                 break;
425         }
426
427 done:
428         if (ret != LDB_SUCCESS) {
429                 return ldb_module_done(ac->req, NULL, NULL, ret);
430         }
431
432         return LDB_SUCCESS;
433 }
434
435 /* Finds the DN "res_dn" of an object with a given SID "sid" */
436 static int samldb_dn_from_sid(struct samldb_ctx *ac)
437 {
438         struct ldb_context *ldb;
439         static const char * const attrs[] = { NULL };
440         struct ldb_request *req;
441         char *filter;
442         int ret;
443
444         ldb = ldb_module_get_ctx(ac->module);
445
446         if (ac->sid == NULL)
447                 return LDB_ERR_OPERATIONS_ERROR;
448
449         filter = talloc_asprintf(ac, "(objectSid=%s)",
450                 ldap_encode_ndr_dom_sid(ac, ac->sid));
451         if (filter == NULL)
452                 return LDB_ERR_OPERATIONS_ERROR;
453
454         ret = ldb_build_search_req(&req, ldb, ac,
455                                 ldb_get_default_basedn(ldb),
456                                 LDB_SCOPE_SUBTREE,
457                                 filter, attrs,
458                                 NULL,
459                                 ac, samldb_dn_from_sid_callback,
460                                 ac->req);
461         if (ret != LDB_SUCCESS)
462                 return ret;
463
464         return ldb_next_request(ac->module, req);
465 }
466
467
468 static int samldb_check_primaryGroupID_1(struct samldb_ctx *ac)
469 {
470         struct ldb_context *ldb;
471         uint32_t rid;
472
473         ldb = ldb_module_get_ctx(ac->module);
474
475         rid = samdb_result_uint(ac->msg, "primaryGroupID", ~0);
476         ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid);
477         if (ac->sid == NULL)
478                 return LDB_ERR_OPERATIONS_ERROR;
479         ac->res_dn = NULL;
480
481         return samldb_next_step(ac);
482 }
483
484 static int samldb_check_primaryGroupID_2(struct samldb_ctx *ac)
485 {
486         if (ac->res_dn == NULL) {
487                 struct ldb_context *ldb;
488                 ldb = ldb_module_get_ctx(ac->module);
489                 ldb_asprintf_errstring(ldb,
490                                        "Failed to find group sid %s!",
491                                        dom_sid_string(ac->sid, ac->sid));
492                 return LDB_ERR_UNWILLING_TO_PERFORM;
493         }
494
495         return samldb_next_step(ac);
496 }
497
498
499 /*
500  * samldb_set_defaultObjectCategory_callback (async)
501  */
502
503 static int samldb_set_defaultObjectCategory_callback(struct ldb_request *req,
504                                                      struct ldb_reply *ares)
505 {
506         struct ldb_context *ldb;
507         struct samldb_ctx *ac;
508         int ret;
509
510         ac = talloc_get_type(req->context, struct samldb_ctx);
511         ldb = ldb_module_get_ctx(ac->module);
512
513         if (!ares) {
514                 ret = LDB_ERR_OPERATIONS_ERROR;
515                 goto done;
516         }
517
518         if (ares->type == LDB_REPLY_REFERRAL) {
519                 return ldb_module_send_referral(ac->req, ares->referral);
520         }
521
522         if (ares->error != LDB_SUCCESS) {
523                 return ldb_module_done(ac->req, ares->controls,
524                                         ares->response, ares->error);
525         }
526         if (ares->type != LDB_REPLY_DONE) {
527                 ldb_set_errstring(ldb,
528                         "Invalid reply type!");
529                 ret = LDB_ERR_OPERATIONS_ERROR;
530                 goto done;
531         }
532
533         ret = samldb_next_step(ac);
534
535 done:
536         if (ret != LDB_SUCCESS) {
537                 return ldb_module_done(ac->req, NULL, NULL, ret);
538         }
539
540         return LDB_SUCCESS;
541 }
542
543 static int samldb_set_defaultObjectCategory(struct samldb_ctx *ac)
544 {
545         struct ldb_context *ldb;
546         struct ldb_message *msg;
547         struct ldb_request *req;
548         int ret;
549
550         ldb = ldb_module_get_ctx(ac->module);
551
552         /* (Re)set the default object category to have it set to the DN in the
553          * storage format */
554         msg = ldb_msg_new(ac);
555         msg->dn = ac->msg->dn;
556         ldb_msg_add_empty(msg, "defaultObjectCategory",
557                           LDB_FLAG_MOD_REPLACE, NULL);
558         ldb_msg_add_steal_string(msg, "defaultObjectCategory",
559                                  ldb_dn_alloc_linearized(msg, ac->dn));
560
561         ret = ldb_build_mod_req(&req, ldb, ac,
562                                 msg, NULL,
563                                 ac,
564                                 samldb_set_defaultObjectCategory_callback,
565                                 ac->req);
566         if (ret != LDB_SUCCESS) {
567                 talloc_free(msg);
568                 return ret;
569         }
570
571         return ldb_next_request(ac->module, req);
572 }
573
574 /*
575  * samldb_find_for_defaultObjectCategory (async)
576  */
577
578 static int samldb_find_for_defaultObjectCategory_callback(struct ldb_request *req,
579                                                           struct ldb_reply *ares)
580 {
581         struct ldb_context *ldb;
582         struct samldb_ctx *ac;
583         int ret;
584
585         ac = talloc_get_type(req->context, struct samldb_ctx);
586         ldb = ldb_module_get_ctx(ac->module);
587
588         if (!ares) {
589                 ret = LDB_ERR_OPERATIONS_ERROR;
590                 goto done;
591         }
592         if (ares->error != LDB_SUCCESS) {
593                 if (ares->error == LDB_ERR_NO_SUCH_OBJECT) {
594                         if (ldb_request_get_control(ac->req,
595                                                     LDB_CONTROL_RELAX_OID) != NULL) {
596                                 /* Don't be pricky when the DN doesn't exist */
597                                 /* if we have the RELAX control specified */
598                                 ac->dn = req->op.search.base;
599                                 return samldb_next_step(ac);
600                         } else {
601                                 ldb_set_errstring(ldb,
602                                         "samldb_find_defaultObjectCategory: "
603                                         "Invalid DN for 'defaultObjectCategory'!");
604                                 ares->error = LDB_ERR_CONSTRAINT_VIOLATION;
605                         }
606                 }
607
608                 return ldb_module_done(ac->req, ares->controls,
609                                        ares->response, ares->error);
610         }
611
612         switch (ares->type) {
613         case LDB_REPLY_ENTRY:
614                 ac->dn = talloc_steal(ac, ares->message->dn);
615
616                 ret = LDB_SUCCESS;
617                 break;
618
619         case LDB_REPLY_REFERRAL:
620                 /* ignore */
621                 talloc_free(ares);
622                 ret = LDB_SUCCESS;
623                 break;
624
625         case LDB_REPLY_DONE:
626                 talloc_free(ares);
627
628                 if (ac->dn != NULL) {
629                         /* when found go on */
630                         ret = samldb_next_step(ac);
631                 } else {
632                         ret = LDB_ERR_OPERATIONS_ERROR;
633                 }
634                 break;
635         }
636
637 done:
638         if (ret != LDB_SUCCESS) {
639                 return ldb_module_done(ac->req, NULL, NULL, ret);
640         }
641
642         return LDB_SUCCESS;
643 }
644
645 static int samldb_find_for_defaultObjectCategory(struct samldb_ctx *ac)
646 {
647         struct ldb_context *ldb;
648         struct ldb_request *req;
649         static const char *no_attrs[] = { NULL };
650         int ret;
651         const struct ldb_val *val;
652         struct ldb_dn *def_obj_cat_dn;
653
654         ldb = ldb_module_get_ctx(ac->module);
655
656         ac->dn = NULL;
657
658         val = ldb_msg_find_ldb_val(ac->msg, "defaultObjectCategory");
659         if (val != NULL) {
660                 /* "defaultObjectCategory" has been set by the caller. Do some
661                  * checks for consistency.
662                  * NOTE: The real constraint check (that 'defaultObjectCategory'
663                  * is the DN of the new objectclass or any parent of it) is
664                  * still incomplete.
665                  * For now we say that 'defaultObjectCategory' is valid if it
666                  * exists and it is of objectclass "classSchema". */
667                 def_obj_cat_dn = ldb_dn_from_ldb_val(ac, ldb, val);
668                 if (def_obj_cat_dn == NULL) {
669                         ldb_set_errstring(ldb,
670                                 "samldb_find_defaultObjectCategory: Invalid DN "
671                                 "for 'defaultObjectCategory'!");
672                         return LDB_ERR_CONSTRAINT_VIOLATION;
673                 }
674         } else {
675                 /* "defaultObjectCategory" has not been set by the caller. Use
676                  * the entry DN for it. */
677                 def_obj_cat_dn = ac->msg->dn;
678         }
679
680         ret = ldb_build_search_req(&req, ldb, ac,
681                                    def_obj_cat_dn, LDB_SCOPE_BASE,
682                                    "objectClass=classSchema", no_attrs,
683                                    NULL,
684                                    ac, samldb_find_for_defaultObjectCategory_callback,
685                                    ac->req);
686         if (ret != LDB_SUCCESS) {
687                 return ret;
688         }
689
690         ret = dsdb_request_add_controls(req,
691                                         DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT);
692         if (ret != LDB_SUCCESS) {
693                 return ret;
694         }
695
696         return ldb_next_request(ac->module, req);
697 }
698
699 /**
700  * msDS-IntId attributeSchema attribute handling
701  * during LDB_ADD request processing
702  */
703 static int samldb_add_handle_msDS_IntId(struct samldb_ctx *ac)
704 {
705         int ret;
706         bool id_exists;
707         uint32_t msds_intid;
708         uint32_t system_flags;
709         struct ldb_context *ldb;
710         struct ldb_result *ldb_res;
711         struct ldb_dn *schema_dn;
712
713         ldb = ldb_module_get_ctx(ac->module);
714         schema_dn = ldb_get_schema_basedn(ldb);
715
716         /* replicated update should always go through */
717         if (ldb_request_get_control(ac->req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) {
718                 return LDB_SUCCESS;
719         }
720
721         /* msDS-IntId is handled by system and should never be
722          * passed by clients */
723         if (ldb_msg_find_element(ac->msg, "msDS-IntId")) {
724                 return LDB_ERR_UNWILLING_TO_PERFORM;
725         }
726
727         /* do not generate msDS-IntId if Relax control is passed */
728         if (ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) {
729                 return LDB_SUCCESS;
730         }
731
732         /* check Functional Level */
733         if (dsdb_functional_level(ldb) < DS_DOMAIN_FUNCTION_2003) {
734                 return LDB_SUCCESS;
735         }
736
737         /* check systemFlags for SCHEMA_BASE_OBJECT flag */
738         system_flags = ldb_msg_find_attr_as_uint(ac->msg, "systemFlags", 0);
739         if (system_flags & SYSTEM_FLAG_SCHEMA_BASE_OBJECT) {
740                 return LDB_SUCCESS;
741         }
742
743         /* Generate new value for msDs-IntId
744          * Value should be in 0x80000000..0xBFFFFFFF range */
745         msds_intid = generate_random() % 0X3FFFFFFF;
746         msds_intid += 0x80000000;
747
748         /* probe id values until unique one is found */
749         do {
750                 msds_intid++;
751                 if (msds_intid > 0xBFFFFFFF) {
752                         msds_intid = 0x80000001;
753                 }
754
755                 ret = dsdb_module_search(ac->module, ac,
756                                          &ldb_res,
757                                          schema_dn, LDB_SCOPE_ONELEVEL, NULL, 0,
758                                          "(msDS-IntId=%d)", msds_intid);
759                 if (ret != LDB_SUCCESS) {
760                         ldb_debug_set(ldb, LDB_DEBUG_ERROR,
761                                       __location__": Searching for msDS-IntId=%d failed - %s\n",
762                                       msds_intid,
763                                       ldb_errstring(ldb));
764                         return LDB_ERR_OPERATIONS_ERROR;
765                 }
766                 id_exists = (ldb_res->count > 0);
767
768                 talloc_free(ldb_res);
769         } while(id_exists);
770
771         return ldb_msg_add_fmt(ac->msg, "msDS-IntId", "%d", msds_intid);
772 }
773
774
775 /*
776  * samldb_add_entry (async)
777  */
778
779 static int samldb_add_entry_callback(struct ldb_request *req,
780                                         struct ldb_reply *ares)
781 {
782         struct ldb_context *ldb;
783         struct samldb_ctx *ac;
784         int ret;
785
786         ac = talloc_get_type(req->context, struct samldb_ctx);
787         ldb = ldb_module_get_ctx(ac->module);
788
789         if (!ares) {
790                 return ldb_module_done(ac->req, NULL, NULL,
791                                         LDB_ERR_OPERATIONS_ERROR);
792         }
793
794         if (ares->type == LDB_REPLY_REFERRAL) {
795                 return ldb_module_send_referral(ac->req, ares->referral);
796         }
797
798         if (ares->error != LDB_SUCCESS) {
799                 return ldb_module_done(ac->req, ares->controls,
800                                         ares->response, ares->error);
801         }
802         if (ares->type != LDB_REPLY_DONE) {
803                 ldb_set_errstring(ldb,
804                         "Invalid reply type!\n");
805                 return ldb_module_done(ac->req, NULL, NULL,
806                                         LDB_ERR_OPERATIONS_ERROR);
807         }
808
809         /* The caller may wish to get controls back from the add */
810         ac->ares = talloc_steal(ac, ares);
811
812         ret = samldb_next_step(ac);
813         if (ret != LDB_SUCCESS) {
814                 return ldb_module_done(ac->req, NULL, NULL, ret);
815         }
816         return ret;
817 }
818
819 static int samldb_add_entry(struct samldb_ctx *ac)
820 {
821         struct ldb_context *ldb;
822         struct ldb_request *req;
823         int ret;
824
825         ldb = ldb_module_get_ctx(ac->module);
826
827         ret = ldb_build_add_req(&req, ldb, ac,
828                                 ac->msg,
829                                 ac->req->controls,
830                                 ac, samldb_add_entry_callback,
831                                 ac->req);
832         if (ret != LDB_SUCCESS) {
833                 return ret;
834         }
835
836         return ldb_next_request(ac->module, req);
837 }
838
839 /*
840  * return true if msg carries an attributeSchema that is intended to be RODC
841  * filtered but is also a system-critical attribute.
842  */
843 static bool check_rodc_critical_attribute(struct ldb_message *msg)
844 {
845         uint32_t schemaFlagsEx, searchFlags, rodc_filtered_flags;
846
847         schemaFlagsEx = ldb_msg_find_attr_as_uint(msg, "schemaFlagsEx", 0);
848         searchFlags = ldb_msg_find_attr_as_uint(msg, "searchFlags", 0);
849         rodc_filtered_flags = (SEARCH_FLAG_RODC_ATTRIBUTE | SEARCH_FLAG_CONFIDENTIAL);
850
851         if ((schemaFlagsEx & SCHEMA_FLAG_ATTR_IS_CRITICAL) &&
852                 ((searchFlags & rodc_filtered_flags) == rodc_filtered_flags)) {
853                 return true;
854         } else {
855                 return false;
856         }
857 }
858
859
860 static int samldb_fill_object(struct samldb_ctx *ac, const char *type)
861 {
862         struct ldb_context *ldb;
863         struct loadparm_context *lp_ctx;
864         enum sid_generator sid_generator;
865         int ret;
866
867         ldb = ldb_module_get_ctx(ac->module);
868
869         /* Add informations for the different account types */
870         ac->type = type;
871         if (strcmp(ac->type, "user") == 0) {
872                 ret = samdb_find_or_add_attribute(ldb, ac->msg,
873                         "userAccountControl", "546");
874                 if (ret != LDB_SUCCESS) return ret;
875                 ret = samdb_find_or_add_attribute(ldb, ac->msg,
876                         "badPwdCount", "0");
877                 if (ret != LDB_SUCCESS) return ret;
878                 ret = samdb_find_or_add_attribute(ldb, ac->msg,
879                         "codePage", "0");
880                 if (ret != LDB_SUCCESS) return ret;
881                 ret = samdb_find_or_add_attribute(ldb, ac->msg,
882                         "countryCode", "0");
883                 if (ret != LDB_SUCCESS) return ret;
884                 ret = samdb_find_or_add_attribute(ldb, ac->msg,
885                         "badPasswordTime", "0");
886                 if (ret != LDB_SUCCESS) return ret;
887                 ret = samdb_find_or_add_attribute(ldb, ac->msg,
888                         "lastLogoff", "0");
889                 if (ret != LDB_SUCCESS) return ret;
890                 ret = samdb_find_or_add_attribute(ldb, ac->msg,
891                         "lastLogon", "0");
892                 if (ret != LDB_SUCCESS) return ret;
893                 ret = samdb_find_or_add_attribute(ldb, ac->msg,
894                         "pwdLastSet", "0");
895                 if (ret != LDB_SUCCESS) return ret;
896                 if (!ldb_msg_find_element(ac->msg, "primaryGroupID")) {
897                         ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg,
898                                                  "primaryGroupID", DOMAIN_RID_USERS);
899                         if (ret != LDB_SUCCESS) return ret;
900                 }
901                 ret = samdb_find_or_add_attribute(ldb, ac->msg,
902                         "accountExpires", "9223372036854775807");
903                 if (ret != LDB_SUCCESS) return ret;
904                 ret = samdb_find_or_add_attribute(ldb, ac->msg,
905                         "logonCount", "0");
906                 if (ret != LDB_SUCCESS) return ret;
907         } else if (strcmp(ac->type, "group") == 0) {
908                 ret = samdb_find_or_add_attribute(ldb, ac->msg,
909                         "groupType", "-2147483646");
910                 if (ret != LDB_SUCCESS) return ret;
911         } else if (strcmp(ac->type, "classSchema") == 0) {
912                 const struct ldb_val *rdn_value;
913
914                 ret = samdb_find_or_add_attribute(ldb, ac->msg,
915                                                   "rdnAttId", "cn");
916                 if (ret != LDB_SUCCESS) return ret;
917
918                 /* do not allow to mark an attributeSchema as RODC filtered if it
919                  * is system-critical */
920                 if (check_rodc_critical_attribute(ac->msg)) {
921                         ldb_asprintf_errstring(ldb, "Refusing schema add of %s - cannot combine critical class with RODC filtering",
922                                                ldb_dn_get_linearized(ac->msg->dn));
923                         return LDB_ERR_UNWILLING_TO_PERFORM;
924                 }
925
926
927                 rdn_value = ldb_dn_get_rdn_val(ac->msg->dn);
928                 if (!ldb_msg_find_element(ac->msg, "lDAPDisplayName")) {
929                         /* the RDN has prefix "CN" */
930                         ret = ldb_msg_add_string(ac->msg, "lDAPDisplayName",
931                                 samdb_cn_to_lDAPDisplayName(ac,
932                                         (const char *) rdn_value->data));
933                         if (ret != LDB_SUCCESS) {
934                                 ldb_oom(ldb);
935                                 return ret;
936                         }
937                 }
938
939                 if (!ldb_msg_find_element(ac->msg, "schemaIDGUID")) {
940                         struct GUID guid;
941                         /* a new GUID */
942                         guid = GUID_random();
943                         ret = dsdb_msg_add_guid(ac->msg, &guid, "schemaIDGUID");
944                         if (ret != LDB_SUCCESS) {
945                                 ldb_oom(ldb);
946                                 return ret;
947                         }
948                 }
949
950                 ret = samldb_add_step(ac, samldb_add_entry);
951                 if (ret != LDB_SUCCESS) return ret;
952
953                 ret = samldb_add_step(ac, samldb_find_for_defaultObjectCategory);
954                 if (ret != LDB_SUCCESS) return ret;
955
956                 ret = samldb_add_step(ac, samldb_set_defaultObjectCategory);
957                 if (ret != LDB_SUCCESS) return ret;
958
959                 return samldb_first_step(ac);
960         } else if (strcmp(ac->type, "attributeSchema") == 0) {
961                 const struct ldb_val *rdn_value;
962                 rdn_value = ldb_dn_get_rdn_val(ac->msg->dn);
963                 if (!ldb_msg_find_element(ac->msg, "lDAPDisplayName")) {
964                         /* the RDN has prefix "CN" */
965                         ret = ldb_msg_add_string(ac->msg, "lDAPDisplayName",
966                                 samdb_cn_to_lDAPDisplayName(ac,
967                                         (const char *) rdn_value->data));
968                         if (ret != LDB_SUCCESS) {
969                                 ldb_oom(ldb);
970                                 return ret;
971                         }
972                 }
973
974                 /* do not allow to mark an attributeSchema as RODC filtered if it
975                  * is system-critical */
976                 if (check_rodc_critical_attribute(ac->msg)) {
977                         ldb_asprintf_errstring(ldb, "Refusing schema add of %s - cannot combine critical attribute with RODC filtering",
978                                                ldb_dn_get_linearized(ac->msg->dn));
979                         return LDB_ERR_UNWILLING_TO_PERFORM;
980                 }
981
982                 ret = samdb_find_or_add_attribute(ldb, ac->msg,
983                                                   "isSingleValued", "FALSE");
984                 if (ret != LDB_SUCCESS) return ret;
985
986                 if (!ldb_msg_find_element(ac->msg, "schemaIDGUID")) {
987                         struct GUID guid;
988                         /* a new GUID */
989                         guid = GUID_random();
990                         ret = dsdb_msg_add_guid(ac->msg, &guid, "schemaIDGUID");
991                         if (ret != LDB_SUCCESS) {
992                                 ldb_oom(ldb);
993                                 return ret;
994                         }
995                 }
996
997                 /* handle msDS-IntID attribute */
998                 ret = samldb_add_handle_msDS_IntId(ac);
999                 if (ret != LDB_SUCCESS) return ret;
1000
1001                 ret = samldb_add_step(ac, samldb_add_entry);
1002                 if (ret != LDB_SUCCESS) return ret;
1003
1004                 return samldb_first_step(ac);
1005         } else {
1006                 ldb_asprintf_errstring(ldb,
1007                         "Invalid entry type!");
1008                 return LDB_ERR_OPERATIONS_ERROR;
1009         }
1010
1011         /* check if we have a valid samAccountName */
1012         ret = samldb_add_step(ac, samldb_check_samAccountName);
1013         if (ret != LDB_SUCCESS) return ret;
1014
1015         /* check account_type/group_type */
1016         ret = samldb_add_step(ac, samldb_check_samAccountType);
1017         if (ret != LDB_SUCCESS) return ret;
1018
1019         /* check if we have a valid primary group ID */
1020         if (strcmp(ac->type, "user") == 0) {
1021                 ret = samldb_add_step(ac, samldb_check_primaryGroupID_1);
1022                 if (ret != LDB_SUCCESS) return ret;
1023                 ret = samldb_add_step(ac, samldb_dn_from_sid);
1024                 if (ret != LDB_SUCCESS) return ret;
1025                 ret = samldb_add_step(ac, samldb_check_primaryGroupID_2);
1026                 if (ret != LDB_SUCCESS) return ret;
1027         }
1028
1029         lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
1030                  struct loadparm_context);
1031
1032         /* don't allow objectSID to be specified without the RELAX control */
1033         ac->sid = samdb_result_dom_sid(ac, ac->msg, "objectSid");
1034         if (ac->sid && !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID) &&
1035             !dsdb_module_am_system(ac->module)) {
1036                 ldb_asprintf_errstring(ldb, "No SID may be specified in user/group creation for %s",
1037                                        ldb_dn_get_linearized(ac->msg->dn));
1038                 return LDB_ERR_UNWILLING_TO_PERFORM;
1039         }
1040
1041         if ( ! ac->sid) {
1042                 sid_generator = lp_sid_generator(lp_ctx);
1043                 if (sid_generator == SID_GENERATOR_INTERNAL) {
1044                         ret = samldb_add_step(ac, samldb_allocate_sid);
1045                         if (ret != LDB_SUCCESS) return ret;
1046                 }
1047         }
1048
1049         /* finally proceed with adding the entry */
1050         ret = samldb_add_step(ac, samldb_add_entry);
1051         if (ret != LDB_SUCCESS) return ret;
1052
1053         return samldb_first_step(ac);
1054 }
1055
1056 static int samldb_fill_foreignSecurityPrincipal_object(struct samldb_ctx *ac)
1057 {
1058         struct ldb_context *ldb;
1059         int ret;
1060
1061         ldb = ldb_module_get_ctx(ac->module);
1062
1063         ac->sid = samdb_result_dom_sid(ac->msg, ac->msg, "objectSid");
1064         if (ac->sid == NULL) {
1065                 ac->sid = dom_sid_parse_talloc(ac->msg,
1066                            (const char *)ldb_dn_get_rdn_val(ac->msg->dn)->data);
1067                 if (!ac->sid) {
1068                         ldb_set_errstring(ldb,
1069                                         "No valid SID found in "
1070                                         "ForeignSecurityPrincipal CN!");
1071                         talloc_free(ac);
1072                         return LDB_ERR_CONSTRAINT_VIOLATION;
1073                 }
1074                 if ( ! samldb_msg_add_sid(ac->msg, "objectSid", ac->sid)) {
1075                         talloc_free(ac);
1076                         return LDB_ERR_OPERATIONS_ERROR;
1077                 }
1078         }
1079
1080         /* finally proceed with adding the entry */
1081         ret = samldb_add_step(ac, samldb_add_entry);
1082         if (ret != LDB_SUCCESS) return ret;
1083
1084         return samldb_first_step(ac);
1085 }
1086
1087 static int samldb_check_rdn(struct ldb_module *module, struct ldb_dn *dn)
1088 {
1089         struct ldb_context *ldb;
1090         const char *rdn_name;
1091
1092         ldb = ldb_module_get_ctx(module);
1093         rdn_name = ldb_dn_get_rdn_name(dn);
1094
1095         if (strcasecmp(rdn_name, "cn") != 0) {
1096                 ldb_asprintf_errstring(ldb,
1097                                         "Bad RDN (%s=) for samldb object, "
1098                                         "should be CN=!", rdn_name);
1099                 return LDB_ERR_CONSTRAINT_VIOLATION;
1100         }
1101
1102         return LDB_SUCCESS;
1103 }
1104
1105 static int samldb_schema_info_update(struct samldb_ctx *ac)
1106 {
1107         WERROR werr;
1108         struct ldb_context *ldb;
1109         struct dsdb_schema *schema;
1110
1111         /* replicated update should always go through */
1112         if (ldb_request_get_control(ac->req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) {
1113                 return LDB_SUCCESS;
1114         }
1115
1116         /* do not update schemaInfo during provisioning */
1117         if (ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) {
1118                 return LDB_SUCCESS;
1119         }
1120
1121         ldb = ldb_module_get_ctx(ac->module);
1122         schema = dsdb_get_schema(ldb, NULL);
1123         if (!schema) {
1124                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
1125                               "samldb_schema_info_update: no dsdb_schema loaded");
1126                 DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
1127                 return LDB_ERR_OPERATIONS_ERROR;
1128         }
1129
1130         werr = dsdb_module_schema_info_update(ac->module, schema, 0);
1131         if (!W_ERROR_IS_OK(werr)) {
1132                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
1133                               "samldb_schema_info_update: "
1134                               "dsdb_module_schema_info_update failed with %s",
1135                               win_errstr(werr));
1136                 DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
1137                 return LDB_ERR_OPERATIONS_ERROR;
1138         }
1139
1140         return LDB_SUCCESS;
1141 }
1142
1143 /*
1144  * samldb_sid_from_dn (async)
1145  */
1146
1147 static int samldb_sid_from_dn(struct samldb_ctx *ac);
1148
1149 static int samldb_sid_from_dn_callback(struct ldb_request *req,
1150         struct ldb_reply *ares)
1151 {
1152         struct ldb_context *ldb;
1153         struct samldb_ctx *ac;
1154         int ret;
1155
1156         ac = talloc_get_type(req->context, struct samldb_ctx);
1157         ldb = ldb_module_get_ctx(ac->module);
1158
1159         if (!ares) {
1160                 ret = LDB_ERR_OPERATIONS_ERROR;
1161                 goto done;
1162         }
1163         if (ares->error != LDB_SUCCESS) {
1164                 return ldb_module_done(ac->req, ares->controls,
1165                                         ares->response, ares->error);
1166         }
1167
1168         switch (ares->type) {
1169         case LDB_REPLY_ENTRY:
1170                 /* save entry */
1171                 if (ac->res_sid != NULL) {
1172                         /* one too many! */
1173                         ldb_set_errstring(ldb,
1174                                 "Invalid number of results while searching "
1175                                 "for domain objects!");
1176                         ret = LDB_ERR_OPERATIONS_ERROR;
1177                         break;
1178                 }
1179                 ac->res_sid = samdb_result_dom_sid(ac, ares->message,
1180                         "objectSid");
1181
1182                 talloc_free(ares);
1183                 ret = LDB_SUCCESS;
1184                 break;
1185
1186         case LDB_REPLY_REFERRAL:
1187                 /* ignore */
1188                 talloc_free(ares);
1189                 ret = LDB_SUCCESS;
1190                 break;
1191
1192         case LDB_REPLY_DONE:
1193                 talloc_free(ares);
1194
1195                 /* found or not found, go on */
1196                 ret = samldb_next_step(ac);
1197                 break;
1198         }
1199
1200 done:
1201         if (ret != LDB_SUCCESS) {
1202                 return ldb_module_done(ac->req, NULL, NULL, ret);
1203         }
1204
1205         return LDB_SUCCESS;
1206 }
1207
1208 /* Finds the SID "res_sid" of an object with a given DN "dn" */
1209 static int samldb_sid_from_dn(struct samldb_ctx *ac)
1210 {
1211         struct ldb_context *ldb;
1212         static const char * const attrs[] = { "objectSid", NULL };
1213         struct ldb_request *req;
1214         int ret;
1215
1216         ldb = ldb_module_get_ctx(ac->module);
1217
1218         if (ac->dn == NULL)
1219                 return LDB_ERR_OPERATIONS_ERROR;
1220
1221         ret = ldb_build_search_req(&req, ldb, ac,
1222                                 ac->dn,
1223                                 LDB_SCOPE_BASE,
1224                                 NULL, attrs,
1225                                 NULL,
1226                                 ac, samldb_sid_from_dn_callback,
1227                                 ac->req);
1228         if (ret != LDB_SUCCESS)
1229                 return ret;
1230
1231         return ldb_next_request(ac->module, req);
1232 }
1233
1234 /*
1235  * samldb_user_dn_to_prim_group_rid (async)
1236  */
1237
1238 static int samldb_user_dn_to_prim_group_rid(struct samldb_ctx *ac);
1239
1240 static int samldb_user_dn_to_prim_group_rid_callback(struct ldb_request *req,
1241         struct ldb_reply *ares)
1242 {
1243         struct ldb_context *ldb;
1244         struct samldb_ctx *ac;
1245         int ret;
1246
1247         ac = talloc_get_type(req->context, struct samldb_ctx);
1248         ldb = ldb_module_get_ctx(ac->module);
1249
1250         if (!ares) {
1251                 ret = LDB_ERR_OPERATIONS_ERROR;
1252                 goto done;
1253         }
1254         if (ares->error != LDB_SUCCESS) {
1255                 return ldb_module_done(ac->req, ares->controls,
1256                                         ares->response, ares->error);
1257         }
1258
1259         switch (ares->type) {
1260         case LDB_REPLY_ENTRY:
1261                 /* save entry */
1262                 if (ac->prim_group_rid != 0) {
1263                         /* one too many! */
1264                         ldb_set_errstring(ldb,
1265                                 "Invalid number of results while searching "
1266                                 "for domain objects!");
1267                         ret = LDB_ERR_OPERATIONS_ERROR;
1268                         break;
1269                 }
1270                 ac->prim_group_rid = samdb_result_uint(ares->message,
1271                         "primaryGroupID", ~0);
1272
1273                 talloc_free(ares);
1274                 ret = LDB_SUCCESS;
1275                 break;
1276
1277         case LDB_REPLY_REFERRAL:
1278                 /* ignore */
1279                 talloc_free(ares);
1280                 ret = LDB_SUCCESS;
1281                 break;
1282
1283         case LDB_REPLY_DONE:
1284                 talloc_free(ares);
1285                 if (ac->prim_group_rid == 0) {
1286                         ldb_asprintf_errstring(ldb,
1287                                 "Unable to get the primary group RID!");
1288                         ret = LDB_ERR_OPERATIONS_ERROR;
1289                         break;
1290                 }
1291
1292                 /* found, go on */
1293                 ret = samldb_next_step(ac);
1294                 break;
1295         }
1296
1297 done:
1298         if (ret != LDB_SUCCESS) {
1299                 return ldb_module_done(ac->req, NULL, NULL, ret);
1300         }
1301
1302         return LDB_SUCCESS;
1303 }
1304
1305 /* Locates the "primaryGroupID" attribute from a certain user specified as
1306  * "user_dn". Saves the result in "prim_group_rid". */
1307 static int samldb_user_dn_to_prim_group_rid(struct samldb_ctx *ac)
1308 {
1309         struct ldb_context *ldb;
1310         static const char * const attrs[] = { "primaryGroupID", NULL };
1311         struct ldb_request *req;
1312         int ret;
1313
1314         ldb = ldb_module_get_ctx(ac->module);
1315
1316         if (ac->user_dn == NULL)
1317                 return LDB_ERR_OPERATIONS_ERROR;
1318
1319         ret = ldb_build_search_req(&req, ldb, ac,
1320                                 ac->user_dn,
1321                                 LDB_SCOPE_BASE,
1322                                 NULL, attrs,
1323                                 NULL,
1324                                 ac, samldb_user_dn_to_prim_group_rid_callback,
1325                                 ac->req);
1326         if (ret != LDB_SUCCESS)
1327                 return ret;
1328
1329         return ldb_next_request(ac->module, req);
1330 }
1331
1332 /*
1333  * samldb_prim_group_rid_to_users_cnt (async)
1334  */
1335
1336 static int samldb_prim_group_rid_to_users_cnt(struct samldb_ctx *ac);
1337
1338 static int samldb_prim_group_rid_to_users_cnt_callback(struct ldb_request *req,
1339         struct ldb_reply *ares)
1340 {
1341         struct ldb_context *ldb;
1342         struct samldb_ctx *ac;
1343         int ret;
1344
1345         ac = talloc_get_type(req->context, struct samldb_ctx);
1346         ldb = ldb_module_get_ctx(ac->module);
1347
1348         if (!ares) {
1349                 ret = LDB_ERR_OPERATIONS_ERROR;
1350                 goto done;
1351         }
1352         if (ares->error != LDB_SUCCESS) {
1353                 return ldb_module_done(ac->req, ares->controls,
1354                                         ares->response, ares->error);
1355         }
1356
1357         switch (ares->type) {
1358         case LDB_REPLY_ENTRY:
1359                 /* save entry */
1360                 ++(ac->users_cnt);
1361
1362                 talloc_free(ares);
1363                 ret = LDB_SUCCESS;
1364                 break;
1365
1366         case LDB_REPLY_REFERRAL:
1367                 /* ignore */
1368                 talloc_free(ares);
1369                 ret = LDB_SUCCESS;
1370                 break;
1371
1372         case LDB_REPLY_DONE:
1373                 talloc_free(ares);
1374
1375                 /* found or not found, go on */
1376                 ret = samldb_next_step(ac);
1377                 break;
1378         }
1379
1380 done:
1381         if (ret != LDB_SUCCESS) {
1382                 return ldb_module_done(ac->req, NULL, NULL, ret);
1383         }
1384
1385         return LDB_SUCCESS;
1386 }
1387
1388 /* Finds the amount of users which have the primary group "prim_group_rid" and
1389  * save the result in "users_cnt" */
1390 static int samldb_prim_group_rid_to_users_cnt(struct samldb_ctx *ac)
1391 {
1392         struct ldb_context *ldb;
1393         static const char * const attrs[] = { NULL };
1394         struct ldb_request *req;
1395         char *filter;
1396         int ret;
1397
1398         ldb = ldb_module_get_ctx(ac->module);
1399
1400         if ((ac->prim_group_rid == 0) || (ac->users_cnt != 0))
1401                 return LDB_ERR_OPERATIONS_ERROR;
1402
1403         filter = talloc_asprintf(ac, "(&(primaryGroupID=%u)(objectclass=user))",
1404                 ac->prim_group_rid);
1405         if (filter == NULL)
1406                 return LDB_ERR_OPERATIONS_ERROR;
1407
1408         ret = ldb_build_search_req(&req, ldb, ac,
1409                                 ldb_get_default_basedn(ldb),
1410                                 LDB_SCOPE_SUBTREE,
1411                                 filter, attrs,
1412                                 NULL,
1413                                 ac,
1414                                 samldb_prim_group_rid_to_users_cnt_callback,
1415                                 ac->req);
1416         if (ret != LDB_SUCCESS)
1417                 return ret;
1418
1419         return ldb_next_request(ac->module, req);
1420 }
1421
1422 /*
1423  * samldb_group_add_member (async)
1424  * samldb_group_del_member (async)
1425  */
1426
1427 static int samldb_group_add_del_member_callback(struct ldb_request *req,
1428         struct ldb_reply *ares)
1429 {
1430         struct ldb_context *ldb;
1431         struct samldb_ctx *ac;
1432         int ret;
1433
1434         ac = talloc_get_type(req->context, struct samldb_ctx);
1435         ldb = ldb_module_get_ctx(ac->module);
1436
1437         if (!ares) {
1438                 ret = LDB_ERR_OPERATIONS_ERROR;
1439                 goto done;
1440         }
1441
1442         if (ares->type == LDB_REPLY_REFERRAL) {
1443                 return ldb_module_send_referral(ac->req, ares->referral);
1444         }
1445
1446         if (ares->error != LDB_SUCCESS) {
1447                 if (ares->error == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1448                         /* On error "NO_SUCH_ATTRIBUTE" (delete of an invalid
1449                          * "member" attribute) return "UNWILLING_TO_PERFORM" */
1450                         ares->error = LDB_ERR_UNWILLING_TO_PERFORM;
1451                 }
1452                 return ldb_module_done(ac->req, ares->controls,
1453                                         ares->response, ares->error);
1454         }
1455         if (ares->type != LDB_REPLY_DONE) {
1456                 ldb_set_errstring(ldb,
1457                         "Invalid reply type!");
1458                 ret = LDB_ERR_OPERATIONS_ERROR;
1459                 goto done;
1460         }
1461
1462         ret = samldb_next_step(ac);
1463
1464 done:
1465         if (ret != LDB_SUCCESS) {
1466                 return ldb_module_done(ac->req, NULL, NULL, ret);
1467         }
1468
1469         return LDB_SUCCESS;
1470 }
1471
1472 /* Adds a member with DN "member_dn" to a group with DN "group_dn" */
1473 static int samldb_group_add_member(struct samldb_ctx *ac)
1474 {
1475         struct ldb_context *ldb;
1476         struct ldb_request *req;
1477         struct ldb_message *msg;
1478         int ret;
1479
1480         ldb = ldb_module_get_ctx(ac->module);
1481
1482         if ((ac->group_dn == NULL) || (ac->member_dn == NULL))
1483                 return LDB_ERR_OPERATIONS_ERROR;
1484
1485         msg = ldb_msg_new(ac);
1486         msg->dn = ac->group_dn;
1487         samdb_msg_add_addval(ldb, ac, msg, "member",
1488                 ldb_dn_get_linearized(ac->member_dn));
1489
1490         ret = ldb_build_mod_req(&req, ldb, ac,
1491                                 msg, NULL,
1492                                 ac, samldb_group_add_del_member_callback,
1493                                 ac->req);
1494         if (ret != LDB_SUCCESS)
1495                 return ret;
1496
1497         return ldb_next_request(ac->module, req);
1498 }
1499
1500 /* Removes a member with DN "member_dn" from a group with DN "group_dn" */
1501 static int samldb_group_del_member(struct samldb_ctx *ac)
1502 {
1503         struct ldb_context *ldb;
1504         struct ldb_request *req;
1505         struct ldb_message *msg;
1506         int ret;
1507
1508         ldb = ldb_module_get_ctx(ac->module);
1509
1510         if ((ac->group_dn == NULL) || (ac->member_dn == NULL))
1511                 return LDB_ERR_OPERATIONS_ERROR;
1512
1513         msg = ldb_msg_new(ac);
1514         msg->dn = ac->group_dn;
1515         samdb_msg_add_delval(ldb, ac, msg, "member",
1516                 ldb_dn_get_linearized(ac->member_dn));
1517
1518         ret = ldb_build_mod_req(&req, ldb, ac,
1519                                 msg, NULL,
1520                                 ac, samldb_group_add_del_member_callback,
1521                                 ac->req);
1522         if (ret != LDB_SUCCESS)
1523                 return ret;
1524
1525         return ldb_next_request(ac->module, req);
1526 }
1527
1528
1529 static int samldb_prim_group_change_1(struct samldb_ctx *ac)
1530 {
1531         struct ldb_context *ldb;
1532         uint32_t rid;
1533
1534         ldb = ldb_module_get_ctx(ac->module);
1535
1536         ac->user_dn = ac->msg->dn;
1537
1538         rid = samdb_result_uint(ac->msg, "primaryGroupID", ~0);
1539         ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid);
1540         if (ac->sid == NULL)
1541                 return LDB_ERR_OPERATIONS_ERROR;
1542         ac->res_dn = NULL;
1543
1544         ac->prim_group_rid = 0;
1545
1546         return samldb_next_step(ac);
1547 }
1548
1549 static int samldb_prim_group_change_2(struct samldb_ctx *ac)
1550 {
1551         struct ldb_context *ldb;
1552
1553         ldb = ldb_module_get_ctx(ac->module);
1554
1555         if (ac->res_dn != NULL)
1556                 ac->new_prim_group_dn = ac->res_dn;
1557         else
1558                 return LDB_ERR_UNWILLING_TO_PERFORM;
1559
1560         ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb),
1561                 ac->prim_group_rid);
1562         if (ac->sid == NULL)
1563                 return LDB_ERR_OPERATIONS_ERROR;
1564         ac->res_dn = NULL;
1565
1566         return samldb_next_step(ac);
1567 }
1568
1569 static int samldb_prim_group_change_4(struct samldb_ctx *ac);
1570 static int samldb_prim_group_change_5(struct samldb_ctx *ac);
1571 static int samldb_prim_group_change_6(struct samldb_ctx *ac);
1572
1573 static int samldb_prim_group_change_3(struct samldb_ctx *ac)
1574 {
1575         int ret;
1576
1577         if (ac->res_dn != NULL)
1578                 ac->old_prim_group_dn = ac->res_dn;
1579         else
1580                 return LDB_ERR_UNWILLING_TO_PERFORM;
1581
1582         /* Only update when the primary group changed */
1583         if (ldb_dn_compare(ac->old_prim_group_dn, ac->new_prim_group_dn) != 0) {
1584                 ac->member_dn = ac->user_dn;
1585                 /* Remove the "member" attribute of the actual (new) primary
1586                  * group */
1587
1588                 ret = samldb_add_step(ac, samldb_prim_group_change_4);
1589                 if (ret != LDB_SUCCESS) return ret;
1590
1591                 ret = samldb_add_step(ac, samldb_group_del_member);
1592                 if (ret != LDB_SUCCESS) return ret;
1593
1594                 /* Add a "member" attribute for the previous primary group */
1595
1596                 ret = samldb_add_step(ac, samldb_prim_group_change_5);
1597                 if (ret != LDB_SUCCESS) return ret;
1598
1599                 ret = samldb_add_step(ac, samldb_group_add_member);
1600                 if (ret != LDB_SUCCESS) return ret;
1601         }
1602
1603         ret = samldb_add_step(ac, samldb_prim_group_change_6);
1604         if (ret != LDB_SUCCESS) return ret;
1605
1606         return samldb_next_step(ac);
1607 }
1608
1609 static int samldb_prim_group_change_4(struct samldb_ctx *ac)
1610 {
1611         ac->group_dn = ac->new_prim_group_dn;
1612
1613         return samldb_next_step(ac);
1614 }
1615
1616 static int samldb_prim_group_change_5(struct samldb_ctx *ac)
1617 {
1618         ac->group_dn = ac->old_prim_group_dn;
1619
1620         return samldb_next_step(ac);
1621 }
1622
1623 static int samldb_prim_group_change_6(struct samldb_ctx *ac)
1624 {
1625         return ldb_next_request(ac->module, ac->req);
1626 }
1627
1628 static int samldb_prim_group_change(struct samldb_ctx *ac)
1629 {
1630         int ret;
1631
1632         /* Finds out the DN of the new primary group */
1633
1634         ret = samldb_add_step(ac, samldb_prim_group_change_1);
1635         if (ret != LDB_SUCCESS) return ret;
1636
1637         ret = samldb_add_step(ac, samldb_dn_from_sid);
1638         if (ret != LDB_SUCCESS) return ret;
1639
1640         ret = samldb_add_step(ac, samldb_user_dn_to_prim_group_rid);
1641         if (ret != LDB_SUCCESS) return ret;
1642
1643         /* Finds out the DN of the old primary group */
1644
1645         ret = samldb_add_step(ac, samldb_prim_group_change_2);
1646         if (ret != LDB_SUCCESS) return ret;
1647
1648         ret = samldb_add_step(ac, samldb_dn_from_sid);
1649         if (ret != LDB_SUCCESS) return ret;
1650
1651         ret = samldb_add_step(ac, samldb_prim_group_change_3);
1652         if (ret != LDB_SUCCESS) return ret;
1653
1654         return samldb_first_step(ac);
1655 }
1656
1657
1658 static int samldb_member_check_1(struct samldb_ctx *ac)
1659 {
1660         struct ldb_context *ldb;
1661         struct ldb_message_element *el;
1662
1663         ldb = ldb_module_get_ctx(ac->module);
1664
1665         el = ldb_msg_find_element(ac->msg, "member");
1666
1667         ac->user_dn = ldb_dn_from_ldb_val(ac, ldb, &el->values[ac->cnt]);
1668         if (!ldb_dn_validate(ac->user_dn))
1669                 return LDB_ERR_OPERATIONS_ERROR;
1670         ac->prim_group_rid = 0;
1671
1672         return samldb_next_step(ac);
1673 }
1674
1675 static int samldb_member_check_2(struct samldb_ctx *ac)
1676 {
1677         struct ldb_context *ldb;
1678
1679         ldb = ldb_module_get_ctx(ac->module);
1680
1681         ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb),
1682                 ac->prim_group_rid);
1683         if (ac->sid == NULL)
1684                 return LDB_ERR_OPERATIONS_ERROR;
1685         ac->res_dn = NULL;
1686
1687         return samldb_next_step(ac);
1688 }
1689
1690 static int samldb_member_check_3(struct samldb_ctx *ac)
1691 {
1692         if (ldb_dn_compare(ac->res_dn, ac->msg->dn) == 0)
1693                 return LDB_ERR_ENTRY_ALREADY_EXISTS;
1694
1695         ++(ac->cnt);
1696
1697         return samldb_next_step(ac);
1698 }
1699
1700 static int samldb_member_check_4(struct samldb_ctx *ac)
1701 {
1702         return ldb_next_request(ac->module, ac->req);
1703 }
1704
1705 static int samldb_member_check(struct samldb_ctx *ac)
1706 {
1707         struct ldb_message_element *el;
1708         int i, ret;
1709
1710         el = ldb_msg_find_element(ac->msg, "member");
1711         ac->cnt = 0;
1712         for (i = 0; i < el->num_values; i++) {
1713                 /* Denies to add "member"s to groups which are primary ones
1714                  * for them */
1715                 ret = samldb_add_step(ac, samldb_member_check_1);
1716                 if (ret != LDB_SUCCESS) return ret;
1717
1718                 ret = samldb_add_step(ac, samldb_user_dn_to_prim_group_rid);
1719                 if (ret != LDB_SUCCESS) return ret;
1720
1721                 ret = samldb_add_step(ac, samldb_member_check_2);
1722                 if (ret != LDB_SUCCESS) return ret;
1723
1724                 ret = samldb_add_step(ac, samldb_dn_from_sid);
1725                 if (ret != LDB_SUCCESS) return ret;
1726
1727                 ret = samldb_add_step(ac, samldb_member_check_3);
1728                 if (ret != LDB_SUCCESS) return ret;
1729         }
1730
1731         ret = samldb_add_step(ac, samldb_member_check_4);
1732         if (ret != LDB_SUCCESS) return ret;
1733
1734         return samldb_first_step(ac);
1735 }
1736
1737
1738 static int samldb_prim_group_users_check_1(struct samldb_ctx *ac)
1739 {
1740         ac->dn = ac->req->op.del.dn;
1741         ac->res_sid = NULL;
1742
1743         return samldb_next_step(ac);
1744 }
1745
1746 static int samldb_prim_group_users_check_2(struct samldb_ctx *ac)
1747 {
1748         NTSTATUS status;
1749         uint32_t rid;
1750
1751         if (ac->res_sid == NULL) {
1752                 /* No SID - therefore ok here */
1753                 return ldb_next_request(ac->module, ac->req);
1754         }
1755         status = dom_sid_split_rid(ac, ac->res_sid, NULL, &rid);
1756         if (!NT_STATUS_IS_OK(status))
1757                 return LDB_ERR_OPERATIONS_ERROR;
1758
1759         if (rid == 0) {
1760                 /* Special object (security principal?) */
1761                 return ldb_next_request(ac->module, ac->req);
1762         }
1763
1764         ac->prim_group_rid = rid;
1765         ac->users_cnt = 0;
1766
1767         return samldb_next_step(ac);
1768 }
1769
1770 static int samldb_prim_group_users_check_3(struct samldb_ctx *ac)
1771 {
1772         if (ac->users_cnt > 0)
1773                 return LDB_ERR_ENTRY_ALREADY_EXISTS;
1774
1775         return ldb_next_request(ac->module, ac->req);
1776 }
1777
1778 static int samldb_prim_group_users_check(struct samldb_ctx *ac)
1779 {
1780         int ret;
1781
1782         /* Finds out the SID/RID of the domain object */
1783
1784         ret = samldb_add_step(ac, samldb_prim_group_users_check_1);
1785         if (ret != LDB_SUCCESS) return ret;
1786
1787         ret = samldb_add_step(ac, samldb_sid_from_dn);
1788         if (ret != LDB_SUCCESS) return ret;
1789
1790         /* Deny delete requests from groups which are primary ones */
1791
1792         ret = samldb_add_step(ac, samldb_prim_group_users_check_2);
1793         if (ret != LDB_SUCCESS) return ret;
1794
1795         ret = samldb_add_step(ac, samldb_prim_group_rid_to_users_cnt);
1796         if (ret != LDB_SUCCESS) return ret;
1797
1798         ret = samldb_add_step(ac, samldb_prim_group_users_check_3);
1799         if (ret != LDB_SUCCESS) return ret;
1800
1801         return samldb_first_step(ac);
1802 }
1803
1804
1805 /* add */
1806 static int samldb_add(struct ldb_module *module, struct ldb_request *req)
1807 {
1808         struct ldb_context *ldb;
1809         struct samldb_ctx *ac;
1810         int ret;
1811
1812         ldb = ldb_module_get_ctx(module);
1813         ldb_debug(ldb, LDB_DEBUG_TRACE, "samldb_add\n");
1814
1815         /* do not manipulate our control entries */
1816         if (ldb_dn_is_special(req->op.add.message->dn)) {
1817                 return ldb_next_request(module, req);
1818         }
1819
1820         ac = samldb_ctx_init(module, req);
1821         if (ac == NULL) {
1822                 return LDB_ERR_OPERATIONS_ERROR;
1823         }
1824
1825         /* build the new msg */
1826         ac->msg = ldb_msg_copy(ac, ac->req->op.add.message);
1827         if (!ac->msg) {
1828                 talloc_free(ac);
1829                 ldb_debug(ldb, LDB_DEBUG_FATAL,
1830                           "samldb_add: ldb_msg_copy failed!\n");
1831                 return LDB_ERR_OPERATIONS_ERROR;
1832         }
1833
1834         if (samdb_find_attribute(ldb, ac->msg,
1835                                  "objectclass", "computer") != NULL) {
1836
1837                 /* make sure the computer object also has the 'user'
1838                  * objectclass so it will be handled by the next call */
1839                 ret = samdb_find_or_add_value(ldb, ac->msg,
1840                                                 "objectclass", "user");
1841                 if (ret != LDB_SUCCESS) {
1842                         talloc_free(ac);
1843                         return ret;
1844                 }
1845         }
1846
1847         if (samdb_find_attribute(ldb, ac->msg,
1848                                  "objectclass", "user") != NULL) {
1849
1850                 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
1851                 if (ret != LDB_SUCCESS) {
1852                         talloc_free(ac);
1853                         return ret;
1854                 }
1855
1856                 return samldb_fill_object(ac, "user");
1857         }
1858
1859         if (samdb_find_attribute(ldb, ac->msg,
1860                                  "objectclass", "group") != NULL) {
1861
1862                 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
1863                 if (ret != LDB_SUCCESS) {
1864                         talloc_free(ac);
1865                         return ret;
1866                 }
1867
1868                 return samldb_fill_object(ac, "group");
1869         }
1870
1871         /* perhaps a foreignSecurityPrincipal? */
1872         if (samdb_find_attribute(ldb, ac->msg,
1873                                  "objectclass",
1874                                  "foreignSecurityPrincipal") != NULL) {
1875
1876                 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
1877                 if (ret != LDB_SUCCESS) {
1878                         talloc_free(ac);
1879                         return ret;
1880                 }
1881
1882                 return samldb_fill_foreignSecurityPrincipal_object(ac);
1883         }
1884
1885         if (samdb_find_attribute(ldb, ac->msg,
1886                                  "objectclass", "classSchema") != NULL) {
1887
1888                 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
1889                 if (ret != LDB_SUCCESS) {
1890                         talloc_free(ac);
1891                         return ret;
1892                 }
1893
1894                 ret = samldb_schema_info_update(ac);
1895                 if (ret != LDB_SUCCESS) {
1896                         talloc_free(ac);
1897                         return ret;
1898                 }
1899
1900                 return samldb_fill_object(ac, "classSchema");
1901         }
1902
1903         if (samdb_find_attribute(ldb, ac->msg,
1904                                  "objectclass", "attributeSchema") != NULL) {
1905
1906                 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
1907                 if (ret != LDB_SUCCESS) {
1908                         talloc_free(ac);
1909                         return ret;
1910                 }
1911
1912                 ret = samldb_schema_info_update(ac);
1913                 if (ret != LDB_SUCCESS) {
1914                         talloc_free(ac);
1915                         return ret;
1916                 }
1917
1918                 return samldb_fill_object(ac, "attributeSchema");
1919         }
1920
1921         talloc_free(ac);
1922
1923         /* nothing matched, go on */
1924         return ldb_next_request(module, req);
1925 }
1926
1927 /* modify */
1928 static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
1929 {
1930         struct ldb_context *ldb;
1931         struct ldb_message *msg;
1932         struct ldb_message_element *el, *el2;
1933         int ret;
1934         uint32_t account_type;
1935
1936         if (ldb_dn_is_special(req->op.mod.message->dn)) {
1937                 /* do not manipulate our control entries */
1938                 return ldb_next_request(module, req);
1939         }
1940
1941         ldb = ldb_module_get_ctx(module);
1942
1943         if (ldb_msg_find_element(req->op.mod.message, "sAMAccountType") != NULL) {
1944                 ldb_asprintf_errstring(ldb,
1945                         "sAMAccountType must not be specified!");
1946                 return LDB_ERR_UNWILLING_TO_PERFORM;
1947         }
1948
1949         /* msDS-IntId is not allowed to be modified
1950          * except when modification comes from replication */
1951         if (ldb_msg_find_element(req->op.mod.message, "msDS-IntId")) {
1952                 if (!ldb_request_get_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) {
1953                         return LDB_ERR_CONSTRAINT_VIOLATION;
1954                 }
1955         }
1956
1957         /* TODO: do not modify original request, create a new one */
1958
1959         el = ldb_msg_find_element(req->op.mod.message, "groupType");
1960         if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
1961                 uint32_t group_type;
1962
1963                 req->op.mod.message = msg = ldb_msg_copy_shallow(req,
1964                         req->op.mod.message);
1965
1966                 group_type = strtoul((const char *)el->values[0].data, NULL, 0);
1967                 account_type =  ds_gtype2atype(group_type);
1968                 ret = samdb_msg_add_uint(ldb, msg, msg,
1969                                          "sAMAccountType",
1970                                          account_type);
1971                 if (ret != LDB_SUCCESS) {
1972                         return ret;
1973                 }
1974                 el2 = ldb_msg_find_element(msg, "sAMAccountType");
1975                 el2->flags = LDB_FLAG_MOD_REPLACE;
1976         }
1977
1978         el = ldb_msg_find_element(req->op.mod.message, "primaryGroupID");
1979         if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
1980                 struct samldb_ctx *ac;
1981
1982                 ac = samldb_ctx_init(module, req);
1983                 if (ac == NULL)
1984                         return LDB_ERR_OPERATIONS_ERROR;
1985
1986                 req->op.mod.message = ac->msg = ldb_msg_copy_shallow(req,
1987                         req->op.mod.message);
1988
1989                 return samldb_prim_group_change(ac);
1990         }
1991
1992         el = ldb_msg_find_element(req->op.mod.message, "userAccountControl");
1993         if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
1994                 uint32_t user_account_control;
1995
1996                 req->op.mod.message = msg = ldb_msg_copy_shallow(req,
1997                         req->op.mod.message);
1998
1999                 user_account_control = strtoul((const char *)el->values[0].data,
2000                         NULL, 0);
2001                 account_type = ds_uf2atype(user_account_control);
2002                 ret = samdb_msg_add_uint(ldb, msg, msg,
2003                                          "sAMAccountType",
2004                                          account_type);
2005                 if (ret != LDB_SUCCESS) {
2006                         return ret;
2007                 }
2008                 el2 = ldb_msg_find_element(msg, "sAMAccountType");
2009                 el2->flags = LDB_FLAG_MOD_REPLACE;
2010
2011                 if (user_account_control & UF_SERVER_TRUST_ACCOUNT) {
2012                         ret = samdb_msg_add_string(ldb, msg, msg,
2013                                                    "isCriticalSystemObject", "TRUE");
2014                         if (ret != LDB_SUCCESS) {
2015                                 return ret;
2016                         }
2017                         el2 = ldb_msg_find_element(msg, "isCriticalSystemObject");
2018                         el2->flags = LDB_FLAG_MOD_REPLACE;
2019
2020                         /* DCs have primaryGroupID of DOMAIN_RID_DCS */
2021                         if (!ldb_msg_find_element(msg, "primaryGroupID")) {
2022                                 ret = samdb_msg_add_uint(ldb, msg, msg,
2023                                                          "primaryGroupID", DOMAIN_RID_DCS);
2024                                 if (ret != LDB_SUCCESS) {
2025                                         return ret;
2026                                 }
2027                                 el2 = ldb_msg_find_element(msg, "primaryGroupID");
2028                                 el2->flags = LDB_FLAG_MOD_REPLACE;
2029                         }
2030                 }
2031         }
2032
2033         el = ldb_msg_find_element(req->op.mod.message, "member");
2034         if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
2035                 struct samldb_ctx *ac;
2036
2037                 ac = samldb_ctx_init(module, req);
2038                 if (ac == NULL)
2039                         return LDB_ERR_OPERATIONS_ERROR;
2040
2041                 req->op.mod.message = ac->msg = ldb_msg_copy_shallow(req,
2042                         req->op.mod.message);
2043
2044                 return samldb_member_check(ac);
2045         }
2046
2047         /* nothing matched, go on */
2048         return ldb_next_request(module, req);
2049 }
2050
2051 /* delete */
2052 static int samldb_delete(struct ldb_module *module, struct ldb_request *req)
2053 {
2054         struct samldb_ctx *ac;
2055
2056         if (ldb_dn_is_special(req->op.del.dn)) {
2057                 /* do not manipulate our control entries */
2058                 return ldb_next_request(module, req);
2059         }
2060
2061         ac = samldb_ctx_init(module, req);
2062         if (ac == NULL)
2063                 return LDB_ERR_OPERATIONS_ERROR;
2064
2065         return samldb_prim_group_users_check(ac);
2066 }
2067
2068 static int samldb_extended_allocate_rid_pool(struct ldb_module *module, struct ldb_request *req)
2069 {
2070         struct ldb_context *ldb = ldb_module_get_ctx(module);
2071         struct dsdb_fsmo_extended_op *exop;
2072         int ret;
2073
2074         exop = talloc_get_type(req->op.extended.data, struct dsdb_fsmo_extended_op);
2075         if (!exop) {
2076                 ldb_debug(ldb, LDB_DEBUG_FATAL, "samldb_extended_allocate_rid_pool: invalid extended data\n");
2077                 return LDB_ERR_PROTOCOL_ERROR;
2078         }
2079
2080         ret = ridalloc_allocate_rid_pool_fsmo(module, exop);
2081         if (ret != LDB_SUCCESS) {
2082                 return ret;
2083         }
2084
2085         return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
2086 }
2087
2088 static int samldb_extended(struct ldb_module *module, struct ldb_request *req)
2089 {
2090         if (strcmp(req->op.extended.oid, DSDB_EXTENDED_ALLOCATE_RID_POOL) == 0) {
2091                 return samldb_extended_allocate_rid_pool(module, req);
2092         }
2093
2094         return ldb_next_request(module, req);
2095 }
2096
2097
2098 _PUBLIC_ const struct ldb_module_ops ldb_samldb_module_ops = {
2099         .name          = "samldb",
2100         .add           = samldb_add,
2101         .modify        = samldb_modify,
2102         .del           = samldb_delete,
2103         .extended      = samldb_extended
2104 };
2105