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
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.
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.
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/>.
25 * Component: ldb samldb module
27 * Description: add embedded user/group creation functionality
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"
41 #include "param/param.h"
45 typedef int (*samldb_step_fn_t)(struct samldb_ctx *);
48 struct samldb_step *next;
53 struct ldb_module *module;
54 struct ldb_request *req;
56 /* used for add operations */
59 /* the resulting message */
60 struct ldb_message *msg;
62 /* holds the entry SID */
65 /* holds a generic dn */
68 /* used in conjunction with "sid" in "samldb_dn_from_sid" */
69 struct ldb_dn *res_dn;
71 /* used in conjunction with "dn" in "samldb_sid_from_dn" */
72 struct dom_sid *res_sid;
74 /* used in "samldb_user_dn_to_prim_group_rid" */
75 uint32_t prim_group_rid;
77 /* used in conjunction with "prim_group_rid" in
78 * "samldb_prim_group_rid_to_users_cnt" */
79 unsigned int users_cnt;
81 /* used in "samldb_group_add_member" and "samldb_group_del_member" */
82 struct ldb_dn *group_dn;
83 struct ldb_dn *member_dn;
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;
89 /* generic counter - used in "samldb_member_check" */
92 /* all the async steps necessary to complete the operation */
93 struct samldb_step *steps;
94 struct samldb_step *curstep;
96 /* If someone set an ares to forward controls and response back to the caller */
97 struct ldb_reply *ares;
100 static struct samldb_ctx *samldb_ctx_init(struct ldb_module *module,
101 struct ldb_request *req)
103 struct ldb_context *ldb;
104 struct samldb_ctx *ac;
106 ldb = ldb_module_get_ctx(module);
108 ac = talloc_zero(req, struct samldb_ctx);
120 static int samldb_add_step(struct samldb_ctx *ac, samldb_step_fn_t fn)
122 struct samldb_step *step, *stepper;
124 step = talloc_zero(ac, struct samldb_step);
126 return LDB_ERR_OPERATIONS_ERROR;
131 if (ac->steps == NULL) {
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;
145 static int samldb_first_step(struct samldb_ctx *ac)
147 if (ac->steps == NULL) {
148 return LDB_ERR_OPERATIONS_ERROR;
151 ac->curstep = ac->steps;
152 return ac->curstep->fn(ac);
155 static int samldb_next_step(struct samldb_ctx *ac)
157 if (ac->curstep->next) {
158 ac->curstep = ac->curstep->next;
159 return ac->curstep->fn(ac);
162 /* we exit the samldb module here */
163 /* If someone set an ares to forward controls and response back to the caller, use them */
165 return ldb_module_done(ac->req, ac->ares->controls,
166 ac->ares->response, LDB_SUCCESS);
168 return ldb_module_done(ac->req, NULL, NULL, LDB_SUCCESS);
172 static int samldb_generate_samAccountName(struct ldb_message *msg)
176 /* Format: $000000-000000000000 */
178 name = talloc_asprintf(msg, "$%.6X-%.6X%.6X",
179 (unsigned int)generate_random(),
180 (unsigned int)generate_random(),
181 (unsigned int)generate_random());
183 return LDB_ERR_OPERATIONS_ERROR;
185 return ldb_msg_add_steal_string(msg, "samAccountName", name);
189 * samldb_check_samAccountName (async)
192 static int samldb_check_samAccountName_callback(struct ldb_request *req,
193 struct ldb_reply *ares)
195 struct samldb_ctx *ac;
198 ac = talloc_get_type(req->context, struct samldb_ctx);
200 if (ares->error != LDB_SUCCESS) {
201 return ldb_module_done(ac->req, ares->controls,
202 ares->response, ares->error);
205 switch (ares->type) {
206 case LDB_REPLY_ENTRY:
207 /* if we get an entry it means this samAccountName
209 return ldb_module_done(ac->req, NULL, NULL,
210 LDB_ERR_ENTRY_ALREADY_EXISTS);
212 case LDB_REPLY_REFERRAL:
219 /* not found, go on */
221 ret = samldb_next_step(ac);
225 if (ret != LDB_SUCCESS) {
226 return ldb_module_done(ac->req, NULL, NULL, ret);
232 static int samldb_check_samAccountName(struct samldb_ctx *ac)
234 struct ldb_context *ldb;
235 struct ldb_request *req;
240 ldb = ldb_module_get_ctx(ac->module);
242 if (ldb_msg_find_element(ac->msg, "samAccountName") == NULL) {
243 ret = samldb_generate_samAccountName(ac->msg);
244 if (ret != LDB_SUCCESS) {
249 name = ldb_msg_find_attr_as_string(ac->msg, "samAccountName", NULL);
251 return LDB_ERR_OPERATIONS_ERROR;
253 filter = talloc_asprintf(ac, "samAccountName=%s",
254 ldb_binary_encode_string(ac, name));
255 if (filter == NULL) {
256 return LDB_ERR_OPERATIONS_ERROR;
259 ret = ldb_build_search_req(&req, ldb, ac,
260 ldb_get_default_basedn(ldb),
264 ac, samldb_check_samAccountName_callback,
267 if (ret != LDB_SUCCESS) {
270 return ldb_next_request(ac->module, req);
274 static int samldb_check_samAccountType(struct samldb_ctx *ac)
276 struct ldb_context *ldb;
277 unsigned int account_type;
278 unsigned int group_type;
282 ldb = ldb_module_get_ctx(ac->module);
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;
291 if (strcmp("user", ac->type) == 0) {
292 uac = samdb_result_uint(ac->msg, "userAccountControl", 0);
294 ldb_asprintf_errstring(ldb,
295 "userAccountControl invalid!");
296 return LDB_ERR_UNWILLING_TO_PERFORM;
298 account_type = ds_uf2atype(uac);
299 ret = samdb_msg_add_uint(ldb,
303 if (ret != LDB_SUCCESS) {
308 if (strcmp("group", ac->type) == 0) {
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;
316 account_type = ds_gtype2atype(group_type);
317 ret = samdb_msg_add_uint(ldb,
321 if (ret != LDB_SUCCESS) {
327 return samldb_next_step(ac);
330 static bool samldb_msg_add_sid(struct ldb_message *msg,
332 const struct dom_sid *sid)
335 enum ndr_err_code ndr_err;
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)) {
342 return (ldb_msg_add_value(msg, name, &v, NULL) == 0);
346 /* allocate a SID using our RID Set */
347 static int samldb_allocate_sid(struct samldb_ctx *ac)
351 struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
353 ret = ridalloc_allocate_rid(ac->module, &rid);
354 if (ret != LDB_SUCCESS) {
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;
364 if ( ! samldb_msg_add_sid(ac->msg, "objectSid", ac->sid)) {
365 return LDB_ERR_OPERATIONS_ERROR;
368 return samldb_next_step(ac);
372 * samldb_dn_from_sid (async)
375 static int samldb_dn_from_sid(struct samldb_ctx *ac);
377 static int samldb_dn_from_sid_callback(struct ldb_request *req,
378 struct ldb_reply *ares)
380 struct ldb_context *ldb;
381 struct samldb_ctx *ac;
384 ac = talloc_get_type(req->context, struct samldb_ctx);
385 ldb = ldb_module_get_ctx(ac->module);
388 ret = LDB_ERR_OPERATIONS_ERROR;
391 if (ares->error != LDB_SUCCESS) {
392 return ldb_module_done(ac->req, ares->controls,
393 ares->response, ares->error);
396 switch (ares->type) {
397 case LDB_REPLY_ENTRY:
399 if (ac->res_dn != NULL) {
401 ldb_set_errstring(ldb,
402 "Invalid number of results while searching "
403 "for domain objects!");
404 ret = LDB_ERR_OPERATIONS_ERROR;
407 ac->res_dn = ldb_dn_copy(ac, ares->message->dn);
413 case LDB_REPLY_REFERRAL:
422 /* found or not found, go on */
423 ret = samldb_next_step(ac);
428 if (ret != LDB_SUCCESS) {
429 return ldb_module_done(ac->req, NULL, NULL, ret);
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)
438 struct ldb_context *ldb;
439 static const char * const attrs[] = { NULL };
440 struct ldb_request *req;
444 ldb = ldb_module_get_ctx(ac->module);
447 return LDB_ERR_OPERATIONS_ERROR;
449 filter = talloc_asprintf(ac, "(objectSid=%s)",
450 ldap_encode_ndr_dom_sid(ac, ac->sid));
452 return LDB_ERR_OPERATIONS_ERROR;
454 ret = ldb_build_search_req(&req, ldb, ac,
455 ldb_get_default_basedn(ldb),
459 ac, samldb_dn_from_sid_callback,
461 if (ret != LDB_SUCCESS)
464 return ldb_next_request(ac->module, req);
468 static int samldb_check_primaryGroupID_1(struct samldb_ctx *ac)
470 struct ldb_context *ldb;
473 ldb = ldb_module_get_ctx(ac->module);
475 rid = samdb_result_uint(ac->msg, "primaryGroupID", ~0);
476 ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid);
478 return LDB_ERR_OPERATIONS_ERROR;
481 return samldb_next_step(ac);
484 static int samldb_check_primaryGroupID_2(struct samldb_ctx *ac)
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;
495 return samldb_next_step(ac);
500 * samldb_set_defaultObjectCategory_callback (async)
503 static int samldb_set_defaultObjectCategory_callback(struct ldb_request *req,
504 struct ldb_reply *ares)
506 struct ldb_context *ldb;
507 struct samldb_ctx *ac;
510 ac = talloc_get_type(req->context, struct samldb_ctx);
511 ldb = ldb_module_get_ctx(ac->module);
514 ret = LDB_ERR_OPERATIONS_ERROR;
518 if (ares->type == LDB_REPLY_REFERRAL) {
519 return ldb_module_send_referral(ac->req, ares->referral);
522 if (ares->error != LDB_SUCCESS) {
523 return ldb_module_done(ac->req, ares->controls,
524 ares->response, ares->error);
526 if (ares->type != LDB_REPLY_DONE) {
527 ldb_set_errstring(ldb,
528 "Invalid reply type!");
529 ret = LDB_ERR_OPERATIONS_ERROR;
533 ret = samldb_next_step(ac);
536 if (ret != LDB_SUCCESS) {
537 return ldb_module_done(ac->req, NULL, NULL, ret);
543 static int samldb_set_defaultObjectCategory(struct samldb_ctx *ac)
545 struct ldb_context *ldb;
546 struct ldb_message *msg;
547 struct ldb_request *req;
550 ldb = ldb_module_get_ctx(ac->module);
552 /* (Re)set the default object category to have it set to the DN in the
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));
561 ret = ldb_build_mod_req(&req, ldb, ac,
564 samldb_set_defaultObjectCategory_callback,
566 if (ret != LDB_SUCCESS) {
571 return ldb_next_request(ac->module, req);
575 * samldb_find_for_defaultObjectCategory (async)
578 static int samldb_find_for_defaultObjectCategory_callback(struct ldb_request *req,
579 struct ldb_reply *ares)
581 struct ldb_context *ldb;
582 struct samldb_ctx *ac;
585 ac = talloc_get_type(req->context, struct samldb_ctx);
586 ldb = ldb_module_get_ctx(ac->module);
589 ret = LDB_ERR_OPERATIONS_ERROR;
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);
601 ldb_set_errstring(ldb,
602 "samldb_find_defaultObjectCategory: "
603 "Invalid DN for 'defaultObjectCategory'!");
604 ares->error = LDB_ERR_CONSTRAINT_VIOLATION;
608 return ldb_module_done(ac->req, ares->controls,
609 ares->response, ares->error);
612 switch (ares->type) {
613 case LDB_REPLY_ENTRY:
614 ac->dn = talloc_steal(ac, ares->message->dn);
619 case LDB_REPLY_REFERRAL:
628 if (ac->dn != NULL) {
629 /* when found go on */
630 ret = samldb_next_step(ac);
632 ret = LDB_ERR_OPERATIONS_ERROR;
638 if (ret != LDB_SUCCESS) {
639 return ldb_module_done(ac->req, NULL, NULL, ret);
645 static int samldb_find_for_defaultObjectCategory(struct samldb_ctx *ac)
647 struct ldb_context *ldb;
648 struct ldb_request *req;
649 static const char *no_attrs[] = { NULL };
651 const struct ldb_val *val;
652 struct ldb_dn *def_obj_cat_dn;
654 ldb = ldb_module_get_ctx(ac->module);
658 val = ldb_msg_find_ldb_val(ac->msg, "defaultObjectCategory");
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
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;
675 /* "defaultObjectCategory" has not been set by the caller. Use
676 * the entry DN for it. */
677 def_obj_cat_dn = ac->msg->dn;
680 ret = ldb_build_search_req(&req, ldb, ac,
681 def_obj_cat_dn, LDB_SCOPE_BASE,
682 "objectClass=classSchema", no_attrs,
684 ac, samldb_find_for_defaultObjectCategory_callback,
686 if (ret != LDB_SUCCESS) {
690 ret = dsdb_request_add_controls(req,
691 DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT);
692 if (ret != LDB_SUCCESS) {
696 return ldb_next_request(ac->module, req);
700 * msDS-IntId attributeSchema attribute handling
701 * during LDB_ADD request processing
703 static int samldb_add_handle_msDS_IntId(struct samldb_ctx *ac)
708 uint32_t system_flags;
709 struct ldb_context *ldb;
710 struct ldb_result *ldb_res;
711 struct ldb_dn *schema_dn;
713 ldb = ldb_module_get_ctx(ac->module);
714 schema_dn = ldb_get_schema_basedn(ldb);
716 /* replicated update should always go through */
717 if (ldb_request_get_control(ac->req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) {
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;
727 /* do not generate msDS-IntId if Relax control is passed */
728 if (ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) {
732 /* check Functional Level */
733 if (dsdb_functional_level(ldb) < DS_DOMAIN_FUNCTION_2003) {
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) {
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;
748 /* probe id values until unique one is found */
751 if (msds_intid > 0xBFFFFFFF) {
752 msds_intid = 0x80000001;
755 ret = dsdb_module_search(ac->module, ac,
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",
764 return LDB_ERR_OPERATIONS_ERROR;
766 id_exists = (ldb_res->count > 0);
768 talloc_free(ldb_res);
771 return ldb_msg_add_fmt(ac->msg, "msDS-IntId", "%d", msds_intid);
776 * samldb_add_entry (async)
779 static int samldb_add_entry_callback(struct ldb_request *req,
780 struct ldb_reply *ares)
782 struct ldb_context *ldb;
783 struct samldb_ctx *ac;
786 ac = talloc_get_type(req->context, struct samldb_ctx);
787 ldb = ldb_module_get_ctx(ac->module);
790 return ldb_module_done(ac->req, NULL, NULL,
791 LDB_ERR_OPERATIONS_ERROR);
794 if (ares->type == LDB_REPLY_REFERRAL) {
795 return ldb_module_send_referral(ac->req, ares->referral);
798 if (ares->error != LDB_SUCCESS) {
799 return ldb_module_done(ac->req, ares->controls,
800 ares->response, ares->error);
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);
809 /* The caller may wish to get controls back from the add */
810 ac->ares = talloc_steal(ac, ares);
812 ret = samldb_next_step(ac);
813 if (ret != LDB_SUCCESS) {
814 return ldb_module_done(ac->req, NULL, NULL, ret);
819 static int samldb_add_entry(struct samldb_ctx *ac)
821 struct ldb_context *ldb;
822 struct ldb_request *req;
825 ldb = ldb_module_get_ctx(ac->module);
827 ret = ldb_build_add_req(&req, ldb, ac,
830 ac, samldb_add_entry_callback,
832 if (ret != LDB_SUCCESS) {
836 return ldb_next_request(ac->module, req);
840 * return true if msg carries an attributeSchema that is intended to be RODC
841 * filtered but is also a system-critical attribute.
843 static bool check_rodc_critical_attribute(struct ldb_message *msg)
845 uint32_t schemaFlagsEx, searchFlags, rodc_filtered_flags;
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);
851 if ((schemaFlagsEx & SCHEMA_FLAG_ATTR_IS_CRITICAL) &&
852 ((searchFlags & rodc_filtered_flags) == rodc_filtered_flags)) {
860 static int samldb_fill_object(struct samldb_ctx *ac, const char *type)
862 struct ldb_context *ldb;
863 struct loadparm_context *lp_ctx;
864 enum sid_generator sid_generator;
867 ldb = ldb_module_get_ctx(ac->module);
869 /* Add informations for the different account types */
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,
877 if (ret != LDB_SUCCESS) return ret;
878 ret = samdb_find_or_add_attribute(ldb, ac->msg,
880 if (ret != LDB_SUCCESS) return ret;
881 ret = samdb_find_or_add_attribute(ldb, ac->msg,
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,
889 if (ret != LDB_SUCCESS) return ret;
890 ret = samdb_find_or_add_attribute(ldb, ac->msg,
892 if (ret != LDB_SUCCESS) return ret;
893 ret = samdb_find_or_add_attribute(ldb, ac->msg,
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;
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,
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;
914 ret = samdb_find_or_add_attribute(ldb, ac->msg,
916 if (ret != LDB_SUCCESS) return ret;
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;
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) {
939 if (!ldb_msg_find_element(ac->msg, "schemaIDGUID")) {
942 guid = GUID_random();
943 ret = dsdb_msg_add_guid(ac->msg, &guid, "schemaIDGUID");
944 if (ret != LDB_SUCCESS) {
950 ret = samldb_add_step(ac, samldb_add_entry);
951 if (ret != LDB_SUCCESS) return ret;
953 ret = samldb_add_step(ac, samldb_find_for_defaultObjectCategory);
954 if (ret != LDB_SUCCESS) return ret;
956 ret = samldb_add_step(ac, samldb_set_defaultObjectCategory);
957 if (ret != LDB_SUCCESS) return ret;
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) {
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;
982 ret = samdb_find_or_add_attribute(ldb, ac->msg,
983 "isSingleValued", "FALSE");
984 if (ret != LDB_SUCCESS) return ret;
986 if (!ldb_msg_find_element(ac->msg, "schemaIDGUID")) {
989 guid = GUID_random();
990 ret = dsdb_msg_add_guid(ac->msg, &guid, "schemaIDGUID");
991 if (ret != LDB_SUCCESS) {
997 /* handle msDS-IntID attribute */
998 ret = samldb_add_handle_msDS_IntId(ac);
999 if (ret != LDB_SUCCESS) return ret;
1001 ret = samldb_add_step(ac, samldb_add_entry);
1002 if (ret != LDB_SUCCESS) return ret;
1004 return samldb_first_step(ac);
1006 ldb_asprintf_errstring(ldb,
1007 "Invalid entry type!");
1008 return LDB_ERR_OPERATIONS_ERROR;
1011 /* check if we have a valid samAccountName */
1012 ret = samldb_add_step(ac, samldb_check_samAccountName);
1013 if (ret != LDB_SUCCESS) return ret;
1015 /* check account_type/group_type */
1016 ret = samldb_add_step(ac, samldb_check_samAccountType);
1017 if (ret != LDB_SUCCESS) return ret;
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;
1029 lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
1030 struct loadparm_context);
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;
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;
1049 /* finally proceed with adding the entry */
1050 ret = samldb_add_step(ac, samldb_add_entry);
1051 if (ret != LDB_SUCCESS) return ret;
1053 return samldb_first_step(ac);
1056 static int samldb_fill_foreignSecurityPrincipal_object(struct samldb_ctx *ac)
1058 struct ldb_context *ldb;
1061 ldb = ldb_module_get_ctx(ac->module);
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);
1068 ldb_set_errstring(ldb,
1069 "No valid SID found in "
1070 "ForeignSecurityPrincipal CN!");
1072 return LDB_ERR_CONSTRAINT_VIOLATION;
1074 if ( ! samldb_msg_add_sid(ac->msg, "objectSid", ac->sid)) {
1076 return LDB_ERR_OPERATIONS_ERROR;
1080 /* finally proceed with adding the entry */
1081 ret = samldb_add_step(ac, samldb_add_entry);
1082 if (ret != LDB_SUCCESS) return ret;
1084 return samldb_first_step(ac);
1087 static int samldb_check_rdn(struct ldb_module *module, struct ldb_dn *dn)
1089 struct ldb_context *ldb;
1090 const char *rdn_name;
1092 ldb = ldb_module_get_ctx(module);
1093 rdn_name = ldb_dn_get_rdn_name(dn);
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;
1105 static int samldb_schema_info_update(struct samldb_ctx *ac)
1108 struct ldb_context *ldb;
1109 struct dsdb_schema *schema;
1111 /* replicated update should always go through */
1112 if (ldb_request_get_control(ac->req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) {
1116 /* do not update schemaInfo during provisioning */
1117 if (ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) {
1121 ldb = ldb_module_get_ctx(ac->module);
1122 schema = dsdb_get_schema(ldb, NULL);
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;
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",
1136 DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
1137 return LDB_ERR_OPERATIONS_ERROR;
1144 * samldb_sid_from_dn (async)
1147 static int samldb_sid_from_dn(struct samldb_ctx *ac);
1149 static int samldb_sid_from_dn_callback(struct ldb_request *req,
1150 struct ldb_reply *ares)
1152 struct ldb_context *ldb;
1153 struct samldb_ctx *ac;
1156 ac = talloc_get_type(req->context, struct samldb_ctx);
1157 ldb = ldb_module_get_ctx(ac->module);
1160 ret = LDB_ERR_OPERATIONS_ERROR;
1163 if (ares->error != LDB_SUCCESS) {
1164 return ldb_module_done(ac->req, ares->controls,
1165 ares->response, ares->error);
1168 switch (ares->type) {
1169 case LDB_REPLY_ENTRY:
1171 if (ac->res_sid != NULL) {
1173 ldb_set_errstring(ldb,
1174 "Invalid number of results while searching "
1175 "for domain objects!");
1176 ret = LDB_ERR_OPERATIONS_ERROR;
1179 ac->res_sid = samdb_result_dom_sid(ac, ares->message,
1186 case LDB_REPLY_REFERRAL:
1192 case LDB_REPLY_DONE:
1195 /* found or not found, go on */
1196 ret = samldb_next_step(ac);
1201 if (ret != LDB_SUCCESS) {
1202 return ldb_module_done(ac->req, NULL, NULL, ret);
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)
1211 struct ldb_context *ldb;
1212 static const char * const attrs[] = { "objectSid", NULL };
1213 struct ldb_request *req;
1216 ldb = ldb_module_get_ctx(ac->module);
1219 return LDB_ERR_OPERATIONS_ERROR;
1221 ret = ldb_build_search_req(&req, ldb, ac,
1226 ac, samldb_sid_from_dn_callback,
1228 if (ret != LDB_SUCCESS)
1231 return ldb_next_request(ac->module, req);
1235 * samldb_user_dn_to_prim_group_rid (async)
1238 static int samldb_user_dn_to_prim_group_rid(struct samldb_ctx *ac);
1240 static int samldb_user_dn_to_prim_group_rid_callback(struct ldb_request *req,
1241 struct ldb_reply *ares)
1243 struct ldb_context *ldb;
1244 struct samldb_ctx *ac;
1247 ac = talloc_get_type(req->context, struct samldb_ctx);
1248 ldb = ldb_module_get_ctx(ac->module);
1251 ret = LDB_ERR_OPERATIONS_ERROR;
1254 if (ares->error != LDB_SUCCESS) {
1255 return ldb_module_done(ac->req, ares->controls,
1256 ares->response, ares->error);
1259 switch (ares->type) {
1260 case LDB_REPLY_ENTRY:
1262 if (ac->prim_group_rid != 0) {
1264 ldb_set_errstring(ldb,
1265 "Invalid number of results while searching "
1266 "for domain objects!");
1267 ret = LDB_ERR_OPERATIONS_ERROR;
1270 ac->prim_group_rid = samdb_result_uint(ares->message,
1271 "primaryGroupID", ~0);
1277 case LDB_REPLY_REFERRAL:
1283 case LDB_REPLY_DONE:
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;
1293 ret = samldb_next_step(ac);
1298 if (ret != LDB_SUCCESS) {
1299 return ldb_module_done(ac->req, NULL, NULL, ret);
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)
1309 struct ldb_context *ldb;
1310 static const char * const attrs[] = { "primaryGroupID", NULL };
1311 struct ldb_request *req;
1314 ldb = ldb_module_get_ctx(ac->module);
1316 if (ac->user_dn == NULL)
1317 return LDB_ERR_OPERATIONS_ERROR;
1319 ret = ldb_build_search_req(&req, ldb, ac,
1324 ac, samldb_user_dn_to_prim_group_rid_callback,
1326 if (ret != LDB_SUCCESS)
1329 return ldb_next_request(ac->module, req);
1333 * samldb_prim_group_rid_to_users_cnt (async)
1336 static int samldb_prim_group_rid_to_users_cnt(struct samldb_ctx *ac);
1338 static int samldb_prim_group_rid_to_users_cnt_callback(struct ldb_request *req,
1339 struct ldb_reply *ares)
1341 struct ldb_context *ldb;
1342 struct samldb_ctx *ac;
1345 ac = talloc_get_type(req->context, struct samldb_ctx);
1346 ldb = ldb_module_get_ctx(ac->module);
1349 ret = LDB_ERR_OPERATIONS_ERROR;
1352 if (ares->error != LDB_SUCCESS) {
1353 return ldb_module_done(ac->req, ares->controls,
1354 ares->response, ares->error);
1357 switch (ares->type) {
1358 case LDB_REPLY_ENTRY:
1366 case LDB_REPLY_REFERRAL:
1372 case LDB_REPLY_DONE:
1375 /* found or not found, go on */
1376 ret = samldb_next_step(ac);
1381 if (ret != LDB_SUCCESS) {
1382 return ldb_module_done(ac->req, NULL, NULL, ret);
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)
1392 struct ldb_context *ldb;
1393 static const char * const attrs[] = { NULL };
1394 struct ldb_request *req;
1398 ldb = ldb_module_get_ctx(ac->module);
1400 if ((ac->prim_group_rid == 0) || (ac->users_cnt != 0))
1401 return LDB_ERR_OPERATIONS_ERROR;
1403 filter = talloc_asprintf(ac, "(&(primaryGroupID=%u)(objectclass=user))",
1404 ac->prim_group_rid);
1406 return LDB_ERR_OPERATIONS_ERROR;
1408 ret = ldb_build_search_req(&req, ldb, ac,
1409 ldb_get_default_basedn(ldb),
1414 samldb_prim_group_rid_to_users_cnt_callback,
1416 if (ret != LDB_SUCCESS)
1419 return ldb_next_request(ac->module, req);
1423 * samldb_group_add_member (async)
1424 * samldb_group_del_member (async)
1427 static int samldb_group_add_del_member_callback(struct ldb_request *req,
1428 struct ldb_reply *ares)
1430 struct ldb_context *ldb;
1431 struct samldb_ctx *ac;
1434 ac = talloc_get_type(req->context, struct samldb_ctx);
1435 ldb = ldb_module_get_ctx(ac->module);
1438 ret = LDB_ERR_OPERATIONS_ERROR;
1442 if (ares->type == LDB_REPLY_REFERRAL) {
1443 return ldb_module_send_referral(ac->req, ares->referral);
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;
1452 return ldb_module_done(ac->req, ares->controls,
1453 ares->response, ares->error);
1455 if (ares->type != LDB_REPLY_DONE) {
1456 ldb_set_errstring(ldb,
1457 "Invalid reply type!");
1458 ret = LDB_ERR_OPERATIONS_ERROR;
1462 ret = samldb_next_step(ac);
1465 if (ret != LDB_SUCCESS) {
1466 return ldb_module_done(ac->req, NULL, NULL, ret);
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)
1475 struct ldb_context *ldb;
1476 struct ldb_request *req;
1477 struct ldb_message *msg;
1480 ldb = ldb_module_get_ctx(ac->module);
1482 if ((ac->group_dn == NULL) || (ac->member_dn == NULL))
1483 return LDB_ERR_OPERATIONS_ERROR;
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));
1490 ret = ldb_build_mod_req(&req, ldb, ac,
1492 ac, samldb_group_add_del_member_callback,
1494 if (ret != LDB_SUCCESS)
1497 return ldb_next_request(ac->module, req);
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)
1503 struct ldb_context *ldb;
1504 struct ldb_request *req;
1505 struct ldb_message *msg;
1508 ldb = ldb_module_get_ctx(ac->module);
1510 if ((ac->group_dn == NULL) || (ac->member_dn == NULL))
1511 return LDB_ERR_OPERATIONS_ERROR;
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));
1518 ret = ldb_build_mod_req(&req, ldb, ac,
1520 ac, samldb_group_add_del_member_callback,
1522 if (ret != LDB_SUCCESS)
1525 return ldb_next_request(ac->module, req);
1529 static int samldb_prim_group_change_1(struct samldb_ctx *ac)
1531 struct ldb_context *ldb;
1534 ldb = ldb_module_get_ctx(ac->module);
1536 ac->user_dn = ac->msg->dn;
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;
1544 ac->prim_group_rid = 0;
1546 return samldb_next_step(ac);
1549 static int samldb_prim_group_change_2(struct samldb_ctx *ac)
1551 struct ldb_context *ldb;
1553 ldb = ldb_module_get_ctx(ac->module);
1555 if (ac->res_dn != NULL)
1556 ac->new_prim_group_dn = ac->res_dn;
1558 return LDB_ERR_UNWILLING_TO_PERFORM;
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;
1566 return samldb_next_step(ac);
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);
1573 static int samldb_prim_group_change_3(struct samldb_ctx *ac)
1577 if (ac->res_dn != NULL)
1578 ac->old_prim_group_dn = ac->res_dn;
1580 return LDB_ERR_UNWILLING_TO_PERFORM;
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
1588 ret = samldb_add_step(ac, samldb_prim_group_change_4);
1589 if (ret != LDB_SUCCESS) return ret;
1591 ret = samldb_add_step(ac, samldb_group_del_member);
1592 if (ret != LDB_SUCCESS) return ret;
1594 /* Add a "member" attribute for the previous primary group */
1596 ret = samldb_add_step(ac, samldb_prim_group_change_5);
1597 if (ret != LDB_SUCCESS) return ret;
1599 ret = samldb_add_step(ac, samldb_group_add_member);
1600 if (ret != LDB_SUCCESS) return ret;
1603 ret = samldb_add_step(ac, samldb_prim_group_change_6);
1604 if (ret != LDB_SUCCESS) return ret;
1606 return samldb_next_step(ac);
1609 static int samldb_prim_group_change_4(struct samldb_ctx *ac)
1611 ac->group_dn = ac->new_prim_group_dn;
1613 return samldb_next_step(ac);
1616 static int samldb_prim_group_change_5(struct samldb_ctx *ac)
1618 ac->group_dn = ac->old_prim_group_dn;
1620 return samldb_next_step(ac);
1623 static int samldb_prim_group_change_6(struct samldb_ctx *ac)
1625 return ldb_next_request(ac->module, ac->req);
1628 static int samldb_prim_group_change(struct samldb_ctx *ac)
1632 /* Finds out the DN of the new primary group */
1634 ret = samldb_add_step(ac, samldb_prim_group_change_1);
1635 if (ret != LDB_SUCCESS) return ret;
1637 ret = samldb_add_step(ac, samldb_dn_from_sid);
1638 if (ret != LDB_SUCCESS) return ret;
1640 ret = samldb_add_step(ac, samldb_user_dn_to_prim_group_rid);
1641 if (ret != LDB_SUCCESS) return ret;
1643 /* Finds out the DN of the old primary group */
1645 ret = samldb_add_step(ac, samldb_prim_group_change_2);
1646 if (ret != LDB_SUCCESS) return ret;
1648 ret = samldb_add_step(ac, samldb_dn_from_sid);
1649 if (ret != LDB_SUCCESS) return ret;
1651 ret = samldb_add_step(ac, samldb_prim_group_change_3);
1652 if (ret != LDB_SUCCESS) return ret;
1654 return samldb_first_step(ac);
1658 static int samldb_member_check_1(struct samldb_ctx *ac)
1660 struct ldb_context *ldb;
1661 struct ldb_message_element *el;
1663 ldb = ldb_module_get_ctx(ac->module);
1665 el = ldb_msg_find_element(ac->msg, "member");
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;
1672 return samldb_next_step(ac);
1675 static int samldb_member_check_2(struct samldb_ctx *ac)
1677 struct ldb_context *ldb;
1679 ldb = ldb_module_get_ctx(ac->module);
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;
1687 return samldb_next_step(ac);
1690 static int samldb_member_check_3(struct samldb_ctx *ac)
1692 if (ldb_dn_compare(ac->res_dn, ac->msg->dn) == 0)
1693 return LDB_ERR_ENTRY_ALREADY_EXISTS;
1697 return samldb_next_step(ac);
1700 static int samldb_member_check_4(struct samldb_ctx *ac)
1702 return ldb_next_request(ac->module, ac->req);
1705 static int samldb_member_check(struct samldb_ctx *ac)
1707 struct ldb_message_element *el;
1710 el = ldb_msg_find_element(ac->msg, "member");
1712 for (i = 0; i < el->num_values; i++) {
1713 /* Denies to add "member"s to groups which are primary ones
1715 ret = samldb_add_step(ac, samldb_member_check_1);
1716 if (ret != LDB_SUCCESS) return ret;
1718 ret = samldb_add_step(ac, samldb_user_dn_to_prim_group_rid);
1719 if (ret != LDB_SUCCESS) return ret;
1721 ret = samldb_add_step(ac, samldb_member_check_2);
1722 if (ret != LDB_SUCCESS) return ret;
1724 ret = samldb_add_step(ac, samldb_dn_from_sid);
1725 if (ret != LDB_SUCCESS) return ret;
1727 ret = samldb_add_step(ac, samldb_member_check_3);
1728 if (ret != LDB_SUCCESS) return ret;
1731 ret = samldb_add_step(ac, samldb_member_check_4);
1732 if (ret != LDB_SUCCESS) return ret;
1734 return samldb_first_step(ac);
1738 static int samldb_prim_group_users_check_1(struct samldb_ctx *ac)
1740 ac->dn = ac->req->op.del.dn;
1743 return samldb_next_step(ac);
1746 static int samldb_prim_group_users_check_2(struct samldb_ctx *ac)
1751 if (ac->res_sid == NULL) {
1752 /* No SID - therefore ok here */
1753 return ldb_next_request(ac->module, ac->req);
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;
1760 /* Special object (security principal?) */
1761 return ldb_next_request(ac->module, ac->req);
1764 ac->prim_group_rid = rid;
1767 return samldb_next_step(ac);
1770 static int samldb_prim_group_users_check_3(struct samldb_ctx *ac)
1772 if (ac->users_cnt > 0)
1773 return LDB_ERR_ENTRY_ALREADY_EXISTS;
1775 return ldb_next_request(ac->module, ac->req);
1778 static int samldb_prim_group_users_check(struct samldb_ctx *ac)
1782 /* Finds out the SID/RID of the domain object */
1784 ret = samldb_add_step(ac, samldb_prim_group_users_check_1);
1785 if (ret != LDB_SUCCESS) return ret;
1787 ret = samldb_add_step(ac, samldb_sid_from_dn);
1788 if (ret != LDB_SUCCESS) return ret;
1790 /* Deny delete requests from groups which are primary ones */
1792 ret = samldb_add_step(ac, samldb_prim_group_users_check_2);
1793 if (ret != LDB_SUCCESS) return ret;
1795 ret = samldb_add_step(ac, samldb_prim_group_rid_to_users_cnt);
1796 if (ret != LDB_SUCCESS) return ret;
1798 ret = samldb_add_step(ac, samldb_prim_group_users_check_3);
1799 if (ret != LDB_SUCCESS) return ret;
1801 return samldb_first_step(ac);
1806 static int samldb_add(struct ldb_module *module, struct ldb_request *req)
1808 struct ldb_context *ldb;
1809 struct samldb_ctx *ac;
1812 ldb = ldb_module_get_ctx(module);
1813 ldb_debug(ldb, LDB_DEBUG_TRACE, "samldb_add\n");
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);
1820 ac = samldb_ctx_init(module, req);
1822 return LDB_ERR_OPERATIONS_ERROR;
1825 /* build the new msg */
1826 ac->msg = ldb_msg_copy(ac, ac->req->op.add.message);
1829 ldb_debug(ldb, LDB_DEBUG_FATAL,
1830 "samldb_add: ldb_msg_copy failed!\n");
1831 return LDB_ERR_OPERATIONS_ERROR;
1834 if (samdb_find_attribute(ldb, ac->msg,
1835 "objectclass", "computer") != NULL) {
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) {
1847 if (samdb_find_attribute(ldb, ac->msg,
1848 "objectclass", "user") != NULL) {
1850 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
1851 if (ret != LDB_SUCCESS) {
1856 return samldb_fill_object(ac, "user");
1859 if (samdb_find_attribute(ldb, ac->msg,
1860 "objectclass", "group") != NULL) {
1862 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
1863 if (ret != LDB_SUCCESS) {
1868 return samldb_fill_object(ac, "group");
1871 /* perhaps a foreignSecurityPrincipal? */
1872 if (samdb_find_attribute(ldb, ac->msg,
1874 "foreignSecurityPrincipal") != NULL) {
1876 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
1877 if (ret != LDB_SUCCESS) {
1882 return samldb_fill_foreignSecurityPrincipal_object(ac);
1885 if (samdb_find_attribute(ldb, ac->msg,
1886 "objectclass", "classSchema") != NULL) {
1888 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
1889 if (ret != LDB_SUCCESS) {
1894 ret = samldb_schema_info_update(ac);
1895 if (ret != LDB_SUCCESS) {
1900 return samldb_fill_object(ac, "classSchema");
1903 if (samdb_find_attribute(ldb, ac->msg,
1904 "objectclass", "attributeSchema") != NULL) {
1906 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
1907 if (ret != LDB_SUCCESS) {
1912 ret = samldb_schema_info_update(ac);
1913 if (ret != LDB_SUCCESS) {
1918 return samldb_fill_object(ac, "attributeSchema");
1923 /* nothing matched, go on */
1924 return ldb_next_request(module, req);
1928 static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
1930 struct ldb_context *ldb;
1931 struct ldb_message *msg;
1932 struct ldb_message_element *el, *el2;
1934 uint32_t account_type;
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);
1941 ldb = ldb_module_get_ctx(module);
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;
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;
1957 /* TODO: do not modify original request, create a new one */
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;
1963 req->op.mod.message = msg = ldb_msg_copy_shallow(req,
1964 req->op.mod.message);
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,
1971 if (ret != LDB_SUCCESS) {
1974 el2 = ldb_msg_find_element(msg, "sAMAccountType");
1975 el2->flags = LDB_FLAG_MOD_REPLACE;
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;
1982 ac = samldb_ctx_init(module, req);
1984 return LDB_ERR_OPERATIONS_ERROR;
1986 req->op.mod.message = ac->msg = ldb_msg_copy_shallow(req,
1987 req->op.mod.message);
1989 return samldb_prim_group_change(ac);
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;
1996 req->op.mod.message = msg = ldb_msg_copy_shallow(req,
1997 req->op.mod.message);
1999 user_account_control = strtoul((const char *)el->values[0].data,
2001 account_type = ds_uf2atype(user_account_control);
2002 ret = samdb_msg_add_uint(ldb, msg, msg,
2005 if (ret != LDB_SUCCESS) {
2008 el2 = ldb_msg_find_element(msg, "sAMAccountType");
2009 el2->flags = LDB_FLAG_MOD_REPLACE;
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) {
2017 el2 = ldb_msg_find_element(msg, "isCriticalSystemObject");
2018 el2->flags = LDB_FLAG_MOD_REPLACE;
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) {
2027 el2 = ldb_msg_find_element(msg, "primaryGroupID");
2028 el2->flags = LDB_FLAG_MOD_REPLACE;
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;
2037 ac = samldb_ctx_init(module, req);
2039 return LDB_ERR_OPERATIONS_ERROR;
2041 req->op.mod.message = ac->msg = ldb_msg_copy_shallow(req,
2042 req->op.mod.message);
2044 return samldb_member_check(ac);
2047 /* nothing matched, go on */
2048 return ldb_next_request(module, req);
2052 static int samldb_delete(struct ldb_module *module, struct ldb_request *req)
2054 struct samldb_ctx *ac;
2056 if (ldb_dn_is_special(req->op.del.dn)) {
2057 /* do not manipulate our control entries */
2058 return ldb_next_request(module, req);
2061 ac = samldb_ctx_init(module, req);
2063 return LDB_ERR_OPERATIONS_ERROR;
2065 return samldb_prim_group_users_check(ac);
2068 static int samldb_extended_allocate_rid_pool(struct ldb_module *module, struct ldb_request *req)
2070 struct ldb_context *ldb = ldb_module_get_ctx(module);
2071 struct dsdb_fsmo_extended_op *exop;
2074 exop = talloc_get_type(req->op.extended.data, struct dsdb_fsmo_extended_op);
2076 ldb_debug(ldb, LDB_DEBUG_FATAL, "samldb_extended_allocate_rid_pool: invalid extended data\n");
2077 return LDB_ERR_PROTOCOL_ERROR;
2080 ret = ridalloc_allocate_rid_pool_fsmo(module, exop);
2081 if (ret != LDB_SUCCESS) {
2085 return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
2088 static int samldb_extended(struct ldb_module *module, struct ldb_request *req)
2090 if (strcmp(req->op.extended.oid, DSDB_EXTENDED_ALLOCATE_RID_POOL) == 0) {
2091 return samldb_extended_allocate_rid_pool(module, req);
2094 return ldb_next_request(module, req);
2098 _PUBLIC_ const struct ldb_module_ops ldb_samldb_module_ops = {
2101 .modify = samldb_modify,
2102 .del = samldb_delete,
2103 .extended = samldb_extended