4 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
5 Copyright (C) Simo Sorce 2004-2008
6 Copyright (C) Matthias Dieter Wallnöfer 2009
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 /* used to find parent domain */
63 struct ldb_dn *check_dn;
64 struct ldb_dn *domain_dn;
65 struct dom_sid *domain_sid;
68 /* holds the entry SID */
71 /* holds a generic dn */
74 /* used in conjunction with "sid" in "samldb_dn_from_sid" */
75 struct ldb_dn *res_dn;
77 /* used in conjunction with "dn" in "samldb_sid_from_dn" */
78 struct dom_sid *res_sid;
80 /* used in "samldb_user_dn_to_prim_group_rid" */
81 uint32_t prim_group_rid;
83 /* used in conjunction with "prim_group_rid" in
84 * "samldb_prim_group_rid_to_users_cnt" */
85 unsigned int users_cnt;
87 /* used in "samldb_group_add_member" and "samldb_group_del_member" */
88 struct ldb_dn *group_dn;
89 struct ldb_dn *member_dn;
91 /* used in "samldb_primary_group_change" */
92 struct ldb_dn *user_dn;
93 struct ldb_dn *old_prim_group_dn, *new_prim_group_dn;
95 /* generic counter - used in "samldb_member_check" */
98 /* all the async steps necessary to complete the operation */
99 struct samldb_step *steps;
100 struct samldb_step *curstep;
102 /* If someone set an ares to forward controls and response back to the caller */
103 struct ldb_reply *ares;
106 static struct samldb_ctx *samldb_ctx_init(struct ldb_module *module,
107 struct ldb_request *req)
109 struct ldb_context *ldb;
110 struct samldb_ctx *ac;
112 ldb = ldb_module_get_ctx(module);
114 ac = talloc_zero(req, struct samldb_ctx);
126 static int samldb_add_step(struct samldb_ctx *ac, samldb_step_fn_t fn)
128 struct samldb_step *step, *stepper;
130 step = talloc_zero(ac, struct samldb_step);
132 return LDB_ERR_OPERATIONS_ERROR;
137 if (ac->steps == NULL) {
141 if (ac->curstep == NULL)
142 return LDB_ERR_OPERATIONS_ERROR;
143 for (stepper = ac->curstep; stepper->next != NULL;
144 stepper = stepper->next);
145 stepper->next = step;
151 static int samldb_first_step(struct samldb_ctx *ac)
153 if (ac->steps == NULL) {
154 return LDB_ERR_OPERATIONS_ERROR;
157 ac->curstep = ac->steps;
158 return ac->curstep->fn(ac);
161 static int samldb_next_step(struct samldb_ctx *ac)
163 if (ac->curstep->next) {
164 ac->curstep = ac->curstep->next;
165 return ac->curstep->fn(ac);
168 /* we exit the samldb module here */
169 /* If someone set an ares to forward controls and response back to the caller, use them */
171 return ldb_module_done(ac->req, ac->ares->controls,
172 ac->ares->response, LDB_SUCCESS);
174 return ldb_module_done(ac->req, NULL, NULL, LDB_SUCCESS);
179 * samldb_get_parent_domain (async)
182 static int samldb_get_parent_domain(struct samldb_ctx *ac);
184 static int samldb_get_parent_domain_callback(struct ldb_request *req,
185 struct ldb_reply *ares)
187 struct ldb_context *ldb;
188 struct samldb_ctx *ac;
192 ac = talloc_get_type(req->context, struct samldb_ctx);
193 ldb = ldb_module_get_ctx(ac->module);
196 ret = LDB_ERR_OPERATIONS_ERROR;
199 if (ares->error != LDB_SUCCESS) {
200 return ldb_module_done(ac->req, ares->controls,
201 ares->response, ares->error);
204 switch (ares->type) {
205 case LDB_REPLY_ENTRY:
207 if ((ac->domain_dn != NULL) || (ac->domain_sid != NULL)) {
209 ldb_set_errstring(ldb,
210 "Invalid number of results while searching "
211 "for domain object!");
212 ret = LDB_ERR_OPERATIONS_ERROR;
216 nextRid = ldb_msg_find_attr_as_string(ares->message,
218 if (nextRid == NULL) {
219 ldb_asprintf_errstring(ldb,
220 "While looking for domain above %s attribute nextRid not found in %s!",
221 ldb_dn_get_linearized(
222 ac->req->op.add.message->dn),
223 ldb_dn_get_linearized(ares->message->dn));
224 ret = LDB_ERR_OPERATIONS_ERROR;
228 ac->next_rid = strtol(nextRid, NULL, 0);
230 ac->domain_sid = samdb_result_dom_sid(ac, ares->message,
232 if (ac->domain_sid == NULL) {
233 ldb_set_errstring(ldb,
234 "Unable to get the parent domain SID!");
235 ret = LDB_ERR_CONSTRAINT_VIOLATION;
238 ac->domain_dn = ldb_dn_copy(ac, ares->message->dn);
244 case LDB_REPLY_REFERRAL:
252 if ((ac->domain_dn == NULL) || (ac->domain_sid == NULL)) {
253 /* not found -> retry */
254 ret = samldb_get_parent_domain(ac);
257 ret = samldb_next_step(ac);
263 if (ret != LDB_SUCCESS) {
264 return ldb_module_done(ac->req, NULL, NULL, ret);
270 /* Find a domain object in the parents of a particular DN. */
271 static int samldb_get_parent_domain(struct samldb_ctx *ac)
273 struct ldb_context *ldb;
274 static const char * const attrs[] = { "objectSid", "nextRid", NULL };
275 struct ldb_request *req;
279 ldb = ldb_module_get_ctx(ac->module);
281 if (ac->check_dn == NULL) {
282 return LDB_ERR_OPERATIONS_ERROR;
285 dn = ldb_dn_get_parent(ac, ac->check_dn);
287 ldb_set_errstring(ldb,
288 "Unable to find parent domain object!");
289 return LDB_ERR_CONSTRAINT_VIOLATION;
294 ret = ldb_build_search_req(&req, ldb, ac,
296 "(|(objectClass=domain)"
297 "(objectClass=builtinDomain))",
300 ac, samldb_get_parent_domain_callback,
303 if (ret != LDB_SUCCESS) {
307 return ldb_next_request(ac->module, req);
311 static int samldb_generate_samAccountName(struct ldb_message *msg)
315 /* Format: $000000-000000000000 */
317 name = talloc_asprintf(msg, "$%.6X-%.6X%.6X",
318 (unsigned int)generate_random(),
319 (unsigned int)generate_random(),
320 (unsigned int)generate_random());
322 return LDB_ERR_OPERATIONS_ERROR;
324 return ldb_msg_add_steal_string(msg, "samAccountName", name);
328 * samldb_check_samAccountName (async)
331 static int samldb_check_samAccountName_callback(struct ldb_request *req,
332 struct ldb_reply *ares)
334 struct samldb_ctx *ac;
337 ac = talloc_get_type(req->context, struct samldb_ctx);
339 if (ares->error != LDB_SUCCESS) {
340 return ldb_module_done(ac->req, ares->controls,
341 ares->response, ares->error);
344 switch (ares->type) {
345 case LDB_REPLY_ENTRY:
346 /* if we get an entry it means this samAccountName
348 return ldb_module_done(ac->req, NULL, NULL,
349 LDB_ERR_ENTRY_ALREADY_EXISTS);
351 case LDB_REPLY_REFERRAL:
352 /* this should not happen */
353 return ldb_module_done(ac->req, NULL, NULL,
354 LDB_ERR_OPERATIONS_ERROR);
357 /* not found, go on */
359 ret = samldb_next_step(ac);
363 if (ret != LDB_SUCCESS) {
364 return ldb_module_done(ac->req, NULL, NULL, ret);
370 static int samldb_check_samAccountName(struct samldb_ctx *ac)
372 struct ldb_context *ldb;
373 struct ldb_request *req;
378 ldb = ldb_module_get_ctx(ac->module);
380 if (ldb_msg_find_element(ac->msg, "samAccountName") == NULL) {
381 ret = samldb_generate_samAccountName(ac->msg);
382 if (ret != LDB_SUCCESS) {
387 name = ldb_msg_find_attr_as_string(ac->msg, "samAccountName", NULL);
389 return LDB_ERR_OPERATIONS_ERROR;
391 filter = talloc_asprintf(ac, "samAccountName=%s",
392 ldb_binary_encode_string(ac, name));
393 if (filter == NULL) {
394 return LDB_ERR_OPERATIONS_ERROR;
397 ret = ldb_build_search_req(&req, ldb, ac,
398 ac->domain_dn, LDB_SCOPE_SUBTREE,
401 ac, samldb_check_samAccountName_callback,
404 if (ret != LDB_SUCCESS) {
407 return ldb_next_request(ac->module, req);
411 static int samldb_check_samAccountType(struct samldb_ctx *ac)
413 struct ldb_context *ldb;
414 unsigned int account_type;
415 unsigned int group_type;
419 ldb = ldb_module_get_ctx(ac->module);
421 /* make sure sAMAccountType is not specified */
422 if (ldb_msg_find_element(ac->msg, "sAMAccountType") != NULL) {
423 ldb_asprintf_errstring(ldb,
424 "sAMAccountType must not be specified!");
425 return LDB_ERR_UNWILLING_TO_PERFORM;
428 if (strcmp("user", ac->type) == 0) {
429 uac = samdb_result_uint(ac->msg, "userAccountControl", 0);
431 ldb_asprintf_errstring(ldb,
432 "userAccountControl invalid!");
433 return LDB_ERR_UNWILLING_TO_PERFORM;
435 account_type = ds_uf2atype(uac);
436 ret = samdb_msg_add_uint(ldb,
440 if (ret != LDB_SUCCESS) {
445 if (strcmp("group", ac->type) == 0) {
447 group_type = samdb_result_uint(ac->msg, "groupType", 0);
448 if (group_type == 0) {
449 ldb_asprintf_errstring(ldb,
450 "groupType invalid!\n");
451 return LDB_ERR_UNWILLING_TO_PERFORM;
453 account_type = ds_gtype2atype(group_type);
454 ret = samdb_msg_add_uint(ldb,
458 if (ret != LDB_SUCCESS) {
464 return samldb_next_step(ac);
469 * samldb_get_sid_domain (async)
472 static int samldb_get_sid_domain_callback(struct ldb_request *req,
473 struct ldb_reply *ares)
475 struct ldb_context *ldb;
476 struct samldb_ctx *ac;
480 ac = talloc_get_type(req->context, struct samldb_ctx);
481 ldb = ldb_module_get_ctx(ac->module);
484 ret = LDB_ERR_OPERATIONS_ERROR;
487 if (ares->error != LDB_SUCCESS) {
488 return ldb_module_done(ac->req, ares->controls,
489 ares->response, ares->error);
492 switch (ares->type) {
493 case LDB_REPLY_ENTRY:
495 if (ac->next_rid != 0) {
497 ldb_set_errstring(ldb,
498 "Invalid number of results while searching "
499 "for domain object!");
500 ret = LDB_ERR_OPERATIONS_ERROR;
504 nextRid = ldb_msg_find_attr_as_string(ares->message,
506 if (nextRid == NULL) {
507 ldb_asprintf_errstring(ldb,
508 "Attribute nextRid not found in %s!",
509 ldb_dn_get_linearized(ares->message->dn));
510 ret = LDB_ERR_OPERATIONS_ERROR;
514 ac->next_rid = strtol(nextRid, NULL, 0);
516 ac->domain_dn = ldb_dn_copy(ac, ares->message->dn);
522 case LDB_REPLY_REFERRAL:
530 if (ac->next_rid == 0) {
531 ldb_asprintf_errstring(ldb,
532 "Unable to get nextRid from domain entry!");
533 ret = LDB_ERR_OPERATIONS_ERROR;
538 ret = samldb_next_step(ac);
543 if (ret != LDB_SUCCESS) {
544 return ldb_module_done(ac->req, NULL, NULL, ret);
550 /* Find a domain object in the parents of a particular DN. */
551 static int samldb_get_sid_domain(struct samldb_ctx *ac)
553 struct ldb_context *ldb;
554 static const char * const attrs[] = { "nextRid", NULL };
555 struct ldb_request *req;
559 ldb = ldb_module_get_ctx(ac->module);
561 if (ac->sid == NULL) {
562 return LDB_ERR_OPERATIONS_ERROR;
565 ac->domain_sid = dom_sid_dup(ac, ac->sid);
566 if (!ac->domain_sid) {
567 return LDB_ERR_OPERATIONS_ERROR;
569 /* get the domain component part of the provided SID */
570 ac->domain_sid->num_auths--;
572 filter = talloc_asprintf(ac,
574 "(|(objectClass=domain)"
575 "(objectClass=builtinDomain)))",
576 ldap_encode_ndr_dom_sid(ac, ac->domain_sid));
577 if (filter == NULL) {
578 return LDB_ERR_OPERATIONS_ERROR;
581 ret = ldb_build_search_req(&req, ldb, ac,
582 ldb_get_default_basedn(ldb),
586 ac, samldb_get_sid_domain_callback,
589 if (ret != LDB_SUCCESS) {
594 return ldb_next_request(ac->module, req);
598 * samldb_dn_from_sid (async)
601 static int samldb_dn_from_sid(struct samldb_ctx *ac);
603 static int samldb_dn_from_sid_callback(struct ldb_request *req,
604 struct ldb_reply *ares)
606 struct ldb_context *ldb;
607 struct samldb_ctx *ac;
610 ac = talloc_get_type(req->context, struct samldb_ctx);
611 ldb = ldb_module_get_ctx(ac->module);
614 ret = LDB_ERR_OPERATIONS_ERROR;
617 if (ares->error != LDB_SUCCESS) {
618 return ldb_module_done(ac->req, ares->controls,
619 ares->response, ares->error);
622 switch (ares->type) {
623 case LDB_REPLY_ENTRY:
625 if (ac->res_dn != NULL) {
627 ldb_set_errstring(ldb,
628 "Invalid number of results while searching "
629 "for domain objects!");
630 ret = LDB_ERR_OPERATIONS_ERROR;
633 ac->res_dn = ldb_dn_copy(ac, ares->message->dn);
639 case LDB_REPLY_REFERRAL:
648 /* found or not found, go on */
649 ret = samldb_next_step(ac);
654 if (ret != LDB_SUCCESS) {
655 return ldb_module_done(ac->req, NULL, NULL, ret);
661 /* Finds the DN "res_dn" of an object with a given SID "sid" */
662 static int samldb_dn_from_sid(struct samldb_ctx *ac)
664 struct ldb_context *ldb;
665 static const char * const attrs[] = { NULL };
666 struct ldb_request *req;
670 ldb = ldb_module_get_ctx(ac->module);
673 return LDB_ERR_OPERATIONS_ERROR;
675 filter = talloc_asprintf(ac, "(objectSid=%s)",
676 ldap_encode_ndr_dom_sid(ac, ac->sid));
678 return LDB_ERR_OPERATIONS_ERROR;
680 ret = ldb_build_search_req(&req, ldb, ac,
681 ldb_get_default_basedn(ldb),
685 ac, samldb_dn_from_sid_callback,
687 if (ret != LDB_SUCCESS)
690 return ldb_next_request(ac->module, req);
694 static int samldb_check_primaryGroupID_1(struct samldb_ctx *ac)
696 struct ldb_context *ldb;
699 ldb = ldb_module_get_ctx(ac->module);
701 rid = samdb_result_uint(ac->msg, "primaryGroupID", ~0);
702 ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid);
704 return LDB_ERR_OPERATIONS_ERROR;
707 return samldb_next_step(ac);
710 static int samldb_check_primaryGroupID_2(struct samldb_ctx *ac)
712 if (ac->res_dn == NULL) {
713 struct ldb_context *ldb;
714 ldb = ldb_module_get_ctx(ac->module);
715 ldb_asprintf_errstring(ldb,
716 "Failed to find group sid %s!",
717 dom_sid_string(ac->sid, ac->sid));
718 return LDB_ERR_UNWILLING_TO_PERFORM;
721 return samldb_next_step(ac);
725 static bool samldb_msg_add_sid(struct ldb_message *msg,
727 const struct dom_sid *sid)
730 enum ndr_err_code ndr_err;
732 ndr_err = ndr_push_struct_blob(&v, msg, NULL, sid,
733 (ndr_push_flags_fn_t)ndr_push_dom_sid);
734 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
737 return (ldb_msg_add_value(msg, name, &v, NULL) == 0);
740 static int samldb_new_sid(struct samldb_ctx *ac)
743 if (ac->domain_sid == NULL || ac->next_rid == 0) {
744 return LDB_ERR_OPERATIONS_ERROR;
747 ac->sid = dom_sid_add_rid(ac, ac->domain_sid, ac->next_rid + 1);
748 if (ac->sid == NULL) {
749 return LDB_ERR_OPERATIONS_ERROR;
752 if ( ! samldb_msg_add_sid(ac->msg, "objectSid", ac->sid)) {
753 return LDB_ERR_OPERATIONS_ERROR;
756 return samldb_next_step(ac);
760 * samldb_notice_sid_callback (async)
763 static int samldb_notice_sid_callback(struct ldb_request *req,
764 struct ldb_reply *ares)
766 struct ldb_context *ldb;
767 struct samldb_ctx *ac;
770 ac = talloc_get_type(req->context, struct samldb_ctx);
771 ldb = ldb_module_get_ctx(ac->module);
774 ret = LDB_ERR_OPERATIONS_ERROR;
777 if (ares->error != LDB_SUCCESS) {
778 return ldb_module_done(ac->req, ares->controls,
779 ares->response, ares->error);
781 if (ares->type != LDB_REPLY_DONE) {
782 ldb_set_errstring(ldb,
783 "Invalid reply type!");
784 ret = LDB_ERR_OPERATIONS_ERROR;
788 ret = samldb_next_step(ac);
791 if (ret != LDB_SUCCESS) {
792 return ldb_module_done(ac->req, NULL, NULL, ret);
798 /* If we are adding new users/groups, we need to update the nextRid
799 * attribute to be 'above' the new/incoming RID. Attempt to do it
801 static int samldb_notice_sid(struct samldb_ctx *ac)
803 struct ldb_context *ldb;
804 uint32_t old_id, new_id;
805 struct ldb_request *req;
806 struct ldb_message *msg;
807 struct ldb_message_element *els;
808 struct ldb_val *vals;
811 ldb = ldb_module_get_ctx(ac->module);
812 old_id = ac->next_rid;
813 new_id = ac->sid->sub_auths[ac->sid->num_auths - 1];
815 if (old_id >= new_id) {
816 /* no need to update the domain nextRid attribute */
817 return samldb_next_step(ac);
820 /* we do a delete and add as a single operation. That prevents
821 a race, in case we are not actually on a transaction db */
822 msg = ldb_msg_new(ac);
825 return LDB_ERR_OPERATIONS_ERROR;
827 els = talloc_array(msg, struct ldb_message_element, 2);
830 return LDB_ERR_OPERATIONS_ERROR;
832 vals = talloc_array(msg, struct ldb_val, 2);
835 return LDB_ERR_OPERATIONS_ERROR;
837 msg->dn = ac->domain_dn;
838 msg->num_elements = 2;
841 els[0].num_values = 1;
842 els[0].values = &vals[0];
843 els[0].flags = LDB_FLAG_MOD_DELETE;
844 els[0].name = talloc_strdup(msg, "nextRid");
847 return LDB_ERR_OPERATIONS_ERROR;
850 els[1].num_values = 1;
851 els[1].values = &vals[1];
852 els[1].flags = LDB_FLAG_MOD_ADD;
853 els[1].name = els[0].name;
855 vals[0].data = (uint8_t *)talloc_asprintf(vals, "%u", old_id);
858 return LDB_ERR_OPERATIONS_ERROR;
860 vals[0].length = strlen((char *)vals[0].data);
862 vals[1].data = (uint8_t *)talloc_asprintf(vals, "%u", new_id);
865 return LDB_ERR_OPERATIONS_ERROR;
867 vals[1].length = strlen((char *)vals[1].data);
869 ret = ldb_build_mod_req(&req, ldb, ac,
871 ac, samldb_notice_sid_callback,
873 if (ret != LDB_SUCCESS) {
877 return ldb_next_request(ac->module, req);
881 * samldb_set_defaultObjectCategory_callback (async)
884 static int samldb_set_defaultObjectCategory_callback(struct ldb_request *req,
885 struct ldb_reply *ares)
887 struct ldb_context *ldb;
888 struct samldb_ctx *ac;
891 ac = talloc_get_type(req->context, struct samldb_ctx);
892 ldb = ldb_module_get_ctx(ac->module);
895 ret = LDB_ERR_OPERATIONS_ERROR;
898 if (ares->error != LDB_SUCCESS) {
899 return ldb_module_done(ac->req, ares->controls,
900 ares->response, ares->error);
902 if (ares->type != LDB_REPLY_DONE) {
903 ldb_set_errstring(ldb,
904 "Invalid reply type!");
905 ret = LDB_ERR_OPERATIONS_ERROR;
909 ret = samldb_next_step(ac);
912 if (ret != LDB_SUCCESS) {
913 return ldb_module_done(ac->req, NULL, NULL, ret);
919 static int samldb_set_defaultObjectCategory(struct samldb_ctx *ac)
921 struct ldb_context *ldb;
922 struct ldb_message *msg;
923 struct ldb_request *req;
926 ldb = ldb_module_get_ctx(ac->module);
928 /* (Re)set the default object category to have it set to the DN in the
930 msg = ldb_msg_new(ac);
931 msg->dn = ac->msg->dn;
932 ldb_msg_add_empty(msg, "defaultObjectCategory",
933 LDB_FLAG_MOD_REPLACE, NULL);
934 ldb_msg_add_steal_string(msg, "defaultObjectCategory",
935 ldb_dn_alloc_linearized(msg, ac->dn));
937 ret = ldb_build_mod_req(&req, ldb, ac,
940 samldb_set_defaultObjectCategory_callback,
942 if (ret != LDB_SUCCESS) {
947 return ldb_next_request(ac->module, req);
951 * samldb_find_for_defaultObjectCategory (async)
954 static int samldb_find_for_defaultObjectCategory_callback(struct ldb_request *req,
955 struct ldb_reply *ares)
957 struct ldb_context *ldb;
958 struct samldb_ctx *ac;
961 ac = talloc_get_type(req->context, struct samldb_ctx);
962 ldb = ldb_module_get_ctx(ac->module);
965 ret = LDB_ERR_OPERATIONS_ERROR;
968 if (ares->error != LDB_SUCCESS) {
969 if (ares->error == LDB_ERR_NO_SUCH_OBJECT) {
970 if (ldb_request_get_control(ac->req,
971 LDB_CONTROL_RELAX_OID) != NULL) {
972 /* Don't be pricky when the DN doesn't exist */
973 /* if we have the RELAX control specified */
974 ac->dn = req->op.search.base;
975 return samldb_next_step(ac);
977 ldb_set_errstring(ldb,
978 "samldb_find_defaultObjectCategory: "
979 "Invalid DN for 'defaultObjectCategory'!");
980 ares->error = LDB_ERR_CONSTRAINT_VIOLATION;
984 return ldb_module_done(ac->req, ares->controls,
985 ares->response, ares->error);
988 switch (ares->type) {
989 case LDB_REPLY_ENTRY:
990 ac->dn = talloc_steal(ac, ares->message->dn);
995 case LDB_REPLY_REFERRAL:
996 /* this should not happen */
998 ret = LDB_ERR_OPERATIONS_ERROR;
1001 case LDB_REPLY_DONE:
1004 if (ac->dn != NULL) {
1005 /* when found go on */
1006 ret = samldb_next_step(ac);
1008 ret = LDB_ERR_OPERATIONS_ERROR;
1014 if (ret != LDB_SUCCESS) {
1015 return ldb_module_done(ac->req, NULL, NULL, ret);
1021 static int samldb_find_for_defaultObjectCategory(struct samldb_ctx *ac)
1023 struct ldb_context *ldb;
1024 struct ldb_request *req;
1025 static const char *no_attrs[] = { NULL };
1027 const struct ldb_val *val;
1028 struct ldb_dn *def_obj_cat_dn;
1030 ldb = ldb_module_get_ctx(ac->module);
1034 val = ldb_msg_find_ldb_val(ac->msg, "defaultObjectCategory");
1036 /* "defaultObjectCategory" has been set by the caller. Do some
1037 * checks for consistency.
1038 * NOTE: The real constraint check (that 'defaultObjectCategory'
1039 * is the DN of the new objectclass or any parent of it) is
1041 * For now we say that 'defaultObjectCategory' is valid if it
1042 * exists and it is of objectclass "classSchema". */
1043 def_obj_cat_dn = ldb_dn_from_ldb_val(ac, ldb, val);
1044 if (def_obj_cat_dn == NULL) {
1045 ldb_set_errstring(ldb,
1046 "samldb_find_defaultObjectCategory: Invalid DN "
1047 "for 'defaultObjectCategory'!");
1048 return LDB_ERR_CONSTRAINT_VIOLATION;
1051 /* "defaultObjectCategory" has not been set by the caller. Use
1052 * the entry DN for it. */
1053 def_obj_cat_dn = ac->msg->dn;
1056 ret = ldb_build_search_req(&req, ldb, ac,
1057 def_obj_cat_dn, LDB_SCOPE_BASE,
1058 "objectClass=classSchema", no_attrs,
1060 ac, samldb_find_for_defaultObjectCategory_callback,
1062 if (ret != LDB_SUCCESS) {
1066 ret = dsdb_request_add_controls(ac->module, req,
1067 DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT);
1068 if (ret != LDB_SUCCESS) {
1072 return ldb_next_request(ac->module, req);
1077 * samldb_add_entry (async)
1080 static int samldb_add_entry_callback(struct ldb_request *req,
1081 struct ldb_reply *ares)
1083 struct ldb_context *ldb;
1084 struct samldb_ctx *ac;
1087 ac = talloc_get_type(req->context, struct samldb_ctx);
1088 ldb = ldb_module_get_ctx(ac->module);
1091 return ldb_module_done(ac->req, NULL, NULL,
1092 LDB_ERR_OPERATIONS_ERROR);
1094 if (ares->error != LDB_SUCCESS) {
1095 return ldb_module_done(ac->req, ares->controls,
1096 ares->response, ares->error);
1098 if (ares->type != LDB_REPLY_DONE) {
1099 ldb_set_errstring(ldb,
1100 "Invalid reply type!\n");
1101 return ldb_module_done(ac->req, NULL, NULL,
1102 LDB_ERR_OPERATIONS_ERROR);
1105 /* The caller may wish to get controls back from the add */
1106 ac->ares = talloc_steal(ac, ares);
1108 ret = samldb_next_step(ac);
1109 if (ret != LDB_SUCCESS) {
1110 return ldb_module_done(ac->req, NULL, NULL, ret);
1115 static int samldb_add_entry(struct samldb_ctx *ac)
1117 struct ldb_context *ldb;
1118 struct ldb_request *req;
1121 ldb = ldb_module_get_ctx(ac->module);
1123 ret = ldb_build_add_req(&req, ldb, ac,
1126 ac, samldb_add_entry_callback,
1128 if (ret != LDB_SUCCESS) {
1132 return ldb_next_request(ac->module, req);
1136 static int samldb_fill_object(struct samldb_ctx *ac, const char *type)
1138 struct ldb_context *ldb;
1139 struct loadparm_context *lp_ctx;
1140 enum sid_generator sid_generator;
1143 ldb = ldb_module_get_ctx(ac->module);
1145 /* search for a parent domain objet */
1146 ac->check_dn = ac->req->op.add.message->dn;
1147 ret = samldb_add_step(ac, samldb_get_parent_domain);
1148 if (ret != LDB_SUCCESS) return ret;
1150 /* Add informations for the different account types */
1152 if (strcmp(ac->type, "user") == 0) {
1153 ret = samdb_find_or_add_attribute(ldb, ac->msg,
1154 "userAccountControl", "546");
1155 if (ret != LDB_SUCCESS) return ret;
1156 ret = samdb_find_or_add_attribute(ldb, ac->msg,
1157 "badPwdCount", "0");
1158 if (ret != LDB_SUCCESS) return ret;
1159 ret = samdb_find_or_add_attribute(ldb, ac->msg,
1161 if (ret != LDB_SUCCESS) return ret;
1162 ret = samdb_find_or_add_attribute(ldb, ac->msg,
1163 "countryCode", "0");
1164 if (ret != LDB_SUCCESS) return ret;
1165 ret = samdb_find_or_add_attribute(ldb, ac->msg,
1166 "badPasswordTime", "0");
1167 if (ret != LDB_SUCCESS) return ret;
1168 ret = samdb_find_or_add_attribute(ldb, ac->msg,
1170 if (ret != LDB_SUCCESS) return ret;
1171 ret = samdb_find_or_add_attribute(ldb, ac->msg,
1173 if (ret != LDB_SUCCESS) return ret;
1174 ret = samdb_find_or_add_attribute(ldb, ac->msg,
1176 if (ret != LDB_SUCCESS) return ret;
1177 ret = samdb_find_or_add_attribute(ldb, ac->msg,
1178 "primaryGroupID", "513");
1179 if (ret != LDB_SUCCESS) return ret;
1180 ret = samdb_find_or_add_attribute(ldb, ac->msg,
1181 "accountExpires", "9223372036854775807");
1182 if (ret != LDB_SUCCESS) return ret;
1183 ret = samdb_find_or_add_attribute(ldb, ac->msg,
1185 if (ret != LDB_SUCCESS) return ret;
1186 } else if (strcmp(ac->type, "group") == 0) {
1187 ret = samdb_find_or_add_attribute(ldb, ac->msg,
1188 "groupType", "-2147483646");
1189 if (ret != LDB_SUCCESS) return ret;
1190 } else if (strcmp(ac->type, "classSchema") == 0) {
1191 const struct ldb_val *rdn_value;
1193 ret = samdb_find_or_add_attribute(ldb, ac->msg,
1195 if (ret != LDB_SUCCESS) return ret;
1197 rdn_value = ldb_dn_get_rdn_val(ac->msg->dn);
1198 if (!ldb_msg_find_element(ac->msg, "lDAPDisplayName")) {
1199 /* the RDN has prefix "CN" */
1200 ret = ldb_msg_add_string(ac->msg, "lDAPDisplayName",
1201 samdb_cn_to_lDAPDisplayName(ac,
1202 (const char *) rdn_value->data));
1203 if (ret != LDB_SUCCESS) {
1209 if (!ldb_msg_find_element(ac->msg, "schemaIDGUID")) {
1212 guid = GUID_random();
1213 ret = dsdb_msg_add_guid(ac->msg, &guid, "schemaIDGUID");
1214 if (ret != LDB_SUCCESS) {
1220 ret = samldb_add_step(ac, samldb_add_entry);
1221 if (ret != LDB_SUCCESS) return ret;
1223 ret = samldb_add_step(ac, samldb_find_for_defaultObjectCategory);
1224 if (ret != LDB_SUCCESS) return ret;
1226 ret = samldb_add_step(ac, samldb_set_defaultObjectCategory);
1227 if (ret != LDB_SUCCESS) return ret;
1229 return samldb_first_step(ac);
1230 } else if (strcmp(ac->type, "attributeSchema") == 0) {
1231 const struct ldb_val *rdn_value;
1232 rdn_value = ldb_dn_get_rdn_val(ac->msg->dn);
1233 if (!ldb_msg_find_element(ac->msg, "lDAPDisplayName")) {
1234 /* the RDN has prefix "CN" */
1235 ret = ldb_msg_add_string(ac->msg, "lDAPDisplayName",
1236 samdb_cn_to_lDAPDisplayName(ac,
1237 (const char *) rdn_value->data));
1238 if (ret != LDB_SUCCESS) {
1244 ret = samdb_find_or_add_attribute(ldb, ac->msg,
1245 "isSingleValued", "FALSE");
1246 if (ret != LDB_SUCCESS) return ret;
1248 if (!ldb_msg_find_element(ac->msg, "schemaIDGUID")) {
1251 guid = GUID_random();
1252 ret = dsdb_msg_add_guid(ac->msg, &guid, "schemaIDGUID");
1253 if (ret != LDB_SUCCESS) {
1259 ret = samldb_add_step(ac, samldb_add_entry);
1260 if (ret != LDB_SUCCESS) return ret;
1262 return samldb_first_step(ac);
1264 ldb_asprintf_errstring(ldb,
1265 "Invalid entry type!");
1266 return LDB_ERR_OPERATIONS_ERROR;
1269 /* check if we have a valid samAccountName */
1270 ret = samldb_add_step(ac, samldb_check_samAccountName);
1271 if (ret != LDB_SUCCESS) return ret;
1273 /* check account_type/group_type */
1274 ret = samldb_add_step(ac, samldb_check_samAccountType);
1275 if (ret != LDB_SUCCESS) return ret;
1277 /* check if we have a valid primary group ID */
1278 if (strcmp(ac->type, "user") == 0) {
1279 ret = samldb_add_step(ac, samldb_check_primaryGroupID_1);
1280 if (ret != LDB_SUCCESS) return ret;
1281 ret = samldb_add_step(ac, samldb_dn_from_sid);
1282 if (ret != LDB_SUCCESS) return ret;
1283 ret = samldb_add_step(ac, samldb_check_primaryGroupID_2);
1284 if (ret != LDB_SUCCESS) return ret;
1287 lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
1288 struct loadparm_context);
1290 sid_generator = lp_sid_generator(lp_ctx);
1291 if (sid_generator == SID_GENERATOR_INTERNAL) {
1292 /* check if we have a valid SID */
1293 ac->sid = samdb_result_dom_sid(ac, ac->msg, "objectSid");
1295 ret = samldb_add_step(ac, samldb_new_sid);
1296 if (ret != LDB_SUCCESS) return ret;
1298 ret = samldb_add_step(ac, samldb_get_sid_domain);
1299 if (ret != LDB_SUCCESS) return ret;
1302 ret = samldb_add_step(ac, samldb_notice_sid);
1303 if (ret != LDB_SUCCESS) return ret;
1306 /* finally proceed with adding the entry */
1307 ret = samldb_add_step(ac, samldb_add_entry);
1308 if (ret != LDB_SUCCESS) return ret;
1310 return samldb_first_step(ac);
1314 * samldb_foreign_notice_sid (async)
1317 static int samldb_foreign_notice_sid_callback(struct ldb_request *req,
1318 struct ldb_reply *ares)
1320 struct ldb_context *ldb;
1321 struct samldb_ctx *ac;
1322 const char *nextRid;
1326 ac = talloc_get_type(req->context, struct samldb_ctx);
1327 ldb = ldb_module_get_ctx(ac->module);
1330 ret = LDB_ERR_OPERATIONS_ERROR;
1333 if (ares->error != LDB_SUCCESS) {
1334 return ldb_module_done(ac->req, ares->controls,
1335 ares->response, ares->error);
1338 switch (ares->type) {
1339 case LDB_REPLY_ENTRY:
1341 if (ac->next_rid != 0) {
1343 ldb_set_errstring(ldb,
1344 "Invalid number of results while searching "
1345 "for domain object!");
1346 ret = LDB_ERR_OPERATIONS_ERROR;
1350 nextRid = ldb_msg_find_attr_as_string(ares->message,
1352 if (nextRid == NULL) {
1353 ldb_asprintf_errstring(ldb,
1354 "While looking for foreign SID %s attribute nextRid not found in %s",
1355 dom_sid_string(ares, ac->sid),
1356 ldb_dn_get_linearized(ares->message->dn));
1357 ret = LDB_ERR_OPERATIONS_ERROR;
1361 ac->next_rid = strtol(nextRid, NULL, 0);
1363 ac->domain_dn = ldb_dn_copy(ac, ares->message->dn);
1365 name = samdb_result_string(ares->message, "name", NULL);
1366 ldb_debug(ldb, LDB_DEBUG_TRACE,
1367 "NOTE (strange but valid): Adding foreign SID "
1368 "record with SID %s, but this domain (%s) is "
1369 "not foreign in the database\n",
1370 dom_sid_string(ares, ac->sid), name);
1376 case LDB_REPLY_REFERRAL:
1382 case LDB_REPLY_DONE:
1385 /* if this is a fake foreign SID, notice the SID */
1386 if (ac->domain_dn) {
1387 ret = samldb_notice_sid(ac);
1392 ret = samldb_next_step(ac);
1397 if (ret != LDB_SUCCESS) {
1398 return ldb_module_done(ac->req, NULL, NULL, ret);
1404 /* Find a domain object in the parents of a particular DN. */
1405 static int samldb_foreign_notice_sid(struct samldb_ctx *ac)
1407 struct ldb_context *ldb;
1408 static const char * const attrs[3] = { "nextRid", "name", NULL };
1409 struct ldb_request *req;
1414 ldb = ldb_module_get_ctx(ac->module);
1416 if (ac->sid == NULL) {
1417 return LDB_ERR_OPERATIONS_ERROR;
1420 status = dom_sid_split_rid(ac, ac->sid, &ac->domain_sid, NULL);
1421 if (!NT_STATUS_IS_OK(status)) {
1422 return LDB_ERR_OPERATIONS_ERROR;
1426 filter = talloc_asprintf(ac,
1428 "(|(objectClass=domain)"
1429 "(objectClass=builtinDomain)))",
1430 ldap_encode_ndr_dom_sid(ac, ac->domain_sid));
1431 if (filter == NULL) {
1432 return LDB_ERR_OPERATIONS_ERROR;
1435 ret = ldb_build_search_req(&req, ldb, ac,
1436 ldb_get_default_basedn(ldb),
1440 ac, samldb_foreign_notice_sid_callback,
1443 if (ret != LDB_SUCCESS) {
1447 return ldb_next_request(ac->module, req);
1451 static int samldb_fill_foreignSecurityPrincipal_object(struct samldb_ctx *ac)
1453 struct ldb_context *ldb;
1456 ldb = ldb_module_get_ctx(ac->module);
1460 ac->sid = samdb_result_dom_sid(ac->msg, ac->msg, "objectSid");
1461 if (ac->sid == NULL) {
1462 ac->sid = dom_sid_parse_talloc(ac->msg,
1463 (const char *)ldb_dn_get_rdn_val(ac->msg->dn)->data);
1465 ldb_set_errstring(ldb,
1466 "No valid SID found in "
1467 "ForeignSecurityPrincipal CN!");
1469 return LDB_ERR_CONSTRAINT_VIOLATION;
1471 if ( ! samldb_msg_add_sid(ac->msg, "objectSid", ac->sid)) {
1473 return LDB_ERR_OPERATIONS_ERROR;
1477 /* check if we need to notice this SID */
1478 ret = samldb_add_step(ac, samldb_foreign_notice_sid);
1479 if (ret != LDB_SUCCESS) return ret;
1481 /* finally proceed with adding the entry */
1482 ret = samldb_add_step(ac, samldb_add_entry);
1483 if (ret != LDB_SUCCESS) return ret;
1485 return samldb_first_step(ac);
1488 static int samldb_check_rdn(struct ldb_module *module, struct ldb_dn *dn)
1490 struct ldb_context *ldb;
1491 const char *rdn_name;
1493 ldb = ldb_module_get_ctx(module);
1494 rdn_name = ldb_dn_get_rdn_name(dn);
1496 if (strcasecmp(rdn_name, "cn") != 0) {
1497 ldb_asprintf_errstring(ldb,
1498 "Bad RDN (%s=) for samldb object, "
1499 "should be CN=!", rdn_name);
1500 return LDB_ERR_CONSTRAINT_VIOLATION;
1507 * samldb_sid_from_dn (async)
1510 static int samldb_sid_from_dn(struct samldb_ctx *ac);
1512 static int samldb_sid_from_dn_callback(struct ldb_request *req,
1513 struct ldb_reply *ares)
1515 struct ldb_context *ldb;
1516 struct samldb_ctx *ac;
1519 ac = talloc_get_type(req->context, struct samldb_ctx);
1520 ldb = ldb_module_get_ctx(ac->module);
1523 ret = LDB_ERR_OPERATIONS_ERROR;
1526 if (ares->error != LDB_SUCCESS) {
1527 return ldb_module_done(ac->req, ares->controls,
1528 ares->response, ares->error);
1531 switch (ares->type) {
1532 case LDB_REPLY_ENTRY:
1534 if (ac->res_sid != NULL) {
1536 ldb_set_errstring(ldb,
1537 "Invalid number of results while searching "
1538 "for domain objects!");
1539 ret = LDB_ERR_OPERATIONS_ERROR;
1542 ac->res_sid = samdb_result_dom_sid(ac, ares->message,
1549 case LDB_REPLY_REFERRAL:
1555 case LDB_REPLY_DONE:
1558 /* found or not found, go on */
1559 ret = samldb_next_step(ac);
1564 if (ret != LDB_SUCCESS) {
1565 return ldb_module_done(ac->req, NULL, NULL, ret);
1571 /* Finds the SID "res_sid" of an object with a given DN "dn" */
1572 static int samldb_sid_from_dn(struct samldb_ctx *ac)
1574 struct ldb_context *ldb;
1575 static const char * const attrs[] = { "objectSid", NULL };
1576 struct ldb_request *req;
1579 ldb = ldb_module_get_ctx(ac->module);
1582 return LDB_ERR_OPERATIONS_ERROR;
1584 ret = ldb_build_search_req(&req, ldb, ac,
1589 ac, samldb_sid_from_dn_callback,
1591 if (ret != LDB_SUCCESS)
1594 return ldb_next_request(ac->module, req);
1598 * samldb_user_dn_to_prim_group_rid (async)
1601 static int samldb_user_dn_to_prim_group_rid(struct samldb_ctx *ac);
1603 static int samldb_user_dn_to_prim_group_rid_callback(struct ldb_request *req,
1604 struct ldb_reply *ares)
1606 struct ldb_context *ldb;
1607 struct samldb_ctx *ac;
1610 ac = talloc_get_type(req->context, struct samldb_ctx);
1611 ldb = ldb_module_get_ctx(ac->module);
1614 ret = LDB_ERR_OPERATIONS_ERROR;
1617 if (ares->error != LDB_SUCCESS) {
1618 return ldb_module_done(ac->req, ares->controls,
1619 ares->response, ares->error);
1622 switch (ares->type) {
1623 case LDB_REPLY_ENTRY:
1625 if (ac->prim_group_rid != 0) {
1627 ldb_set_errstring(ldb,
1628 "Invalid number of results while searching "
1629 "for domain objects!");
1630 ret = LDB_ERR_OPERATIONS_ERROR;
1633 ac->prim_group_rid = samdb_result_uint(ares->message,
1634 "primaryGroupID", ~0);
1640 case LDB_REPLY_REFERRAL:
1646 case LDB_REPLY_DONE:
1648 if (ac->prim_group_rid == 0) {
1649 ldb_asprintf_errstring(ldb,
1650 "Unable to get the primary group RID!");
1651 ret = LDB_ERR_OPERATIONS_ERROR;
1656 ret = samldb_next_step(ac);
1661 if (ret != LDB_SUCCESS) {
1662 return ldb_module_done(ac->req, NULL, NULL, ret);
1668 /* Locates the "primaryGroupID" attribute from a certain user specified as
1669 * "user_dn". Saves the result in "prim_group_rid". */
1670 static int samldb_user_dn_to_prim_group_rid(struct samldb_ctx *ac)
1672 struct ldb_context *ldb;
1673 static const char * const attrs[] = { "primaryGroupID", NULL };
1674 struct ldb_request *req;
1677 ldb = ldb_module_get_ctx(ac->module);
1679 if (ac->user_dn == NULL)
1680 return LDB_ERR_OPERATIONS_ERROR;
1682 ret = ldb_build_search_req(&req, ldb, ac,
1687 ac, samldb_user_dn_to_prim_group_rid_callback,
1689 if (ret != LDB_SUCCESS)
1692 return ldb_next_request(ac->module, req);
1696 * samldb_prim_group_rid_to_users_cnt (async)
1699 static int samldb_prim_group_rid_to_users_cnt(struct samldb_ctx *ac);
1701 static int samldb_prim_group_rid_to_users_cnt_callback(struct ldb_request *req,
1702 struct ldb_reply *ares)
1704 struct ldb_context *ldb;
1705 struct samldb_ctx *ac;
1708 ac = talloc_get_type(req->context, struct samldb_ctx);
1709 ldb = ldb_module_get_ctx(ac->module);
1712 ret = LDB_ERR_OPERATIONS_ERROR;
1715 if (ares->error != LDB_SUCCESS) {
1716 return ldb_module_done(ac->req, ares->controls,
1717 ares->response, ares->error);
1720 switch (ares->type) {
1721 case LDB_REPLY_ENTRY:
1729 case LDB_REPLY_REFERRAL:
1735 case LDB_REPLY_DONE:
1738 /* found or not found, go on */
1739 ret = samldb_next_step(ac);
1744 if (ret != LDB_SUCCESS) {
1745 return ldb_module_done(ac->req, NULL, NULL, ret);
1751 /* Finds the amount of users which have the primary group "prim_group_rid" and
1752 * save the result in "users_cnt" */
1753 static int samldb_prim_group_rid_to_users_cnt(struct samldb_ctx *ac)
1755 struct ldb_context *ldb;
1756 static const char * const attrs[] = { NULL };
1757 struct ldb_request *req;
1761 ldb = ldb_module_get_ctx(ac->module);
1763 if ((ac->prim_group_rid == 0) || (ac->users_cnt != 0))
1764 return LDB_ERR_OPERATIONS_ERROR;
1766 filter = talloc_asprintf(ac, "(&(primaryGroupID=%u)(objectclass=user))",
1767 ac->prim_group_rid);
1769 return LDB_ERR_OPERATIONS_ERROR;
1771 ret = ldb_build_search_req(&req, ldb, ac,
1772 ldb_get_default_basedn(ldb),
1777 samldb_prim_group_rid_to_users_cnt_callback,
1779 if (ret != LDB_SUCCESS)
1782 return ldb_next_request(ac->module, req);
1786 * samldb_group_add_member (async)
1787 * samldb_group_del_member (async)
1790 static int samldb_group_add_del_member_callback(struct ldb_request *req,
1791 struct ldb_reply *ares)
1793 struct ldb_context *ldb;
1794 struct samldb_ctx *ac;
1797 ac = talloc_get_type(req->context, struct samldb_ctx);
1798 ldb = ldb_module_get_ctx(ac->module);
1801 ret = LDB_ERR_OPERATIONS_ERROR;
1804 if (ares->error != LDB_SUCCESS) {
1805 if (ares->error == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1806 /* On error "NO_SUCH_ATTRIBUTE" (delete of an invalid
1807 * "member" attribute) return "UNWILLING_TO_PERFORM" */
1808 ares->error = LDB_ERR_UNWILLING_TO_PERFORM;
1810 return ldb_module_done(ac->req, ares->controls,
1811 ares->response, ares->error);
1813 if (ares->type != LDB_REPLY_DONE) {
1814 ldb_set_errstring(ldb,
1815 "Invalid reply type!");
1816 ret = LDB_ERR_OPERATIONS_ERROR;
1820 ret = samldb_next_step(ac);
1823 if (ret != LDB_SUCCESS) {
1824 return ldb_module_done(ac->req, NULL, NULL, ret);
1830 /* Adds a member with DN "member_dn" to a group with DN "group_dn" */
1831 static int samldb_group_add_member(struct samldb_ctx *ac)
1833 struct ldb_context *ldb;
1834 struct ldb_request *req;
1835 struct ldb_message *msg;
1838 ldb = ldb_module_get_ctx(ac->module);
1840 if ((ac->group_dn == NULL) || (ac->member_dn == NULL))
1841 return LDB_ERR_OPERATIONS_ERROR;
1843 msg = ldb_msg_new(ac);
1844 msg->dn = ac->group_dn;
1845 samdb_msg_add_addval(ldb, ac, msg, "member",
1846 ldb_dn_get_linearized(ac->member_dn));
1848 ret = ldb_build_mod_req(&req, ldb, ac,
1850 ac, samldb_group_add_del_member_callback,
1852 if (ret != LDB_SUCCESS)
1855 return ldb_next_request(ac->module, req);
1858 /* Removes a member with DN "member_dn" from a group with DN "group_dn" */
1859 static int samldb_group_del_member(struct samldb_ctx *ac)
1861 struct ldb_context *ldb;
1862 struct ldb_request *req;
1863 struct ldb_message *msg;
1866 ldb = ldb_module_get_ctx(ac->module);
1868 if ((ac->group_dn == NULL) || (ac->member_dn == NULL))
1869 return LDB_ERR_OPERATIONS_ERROR;
1871 msg = ldb_msg_new(ac);
1872 msg->dn = ac->group_dn;
1873 samdb_msg_add_delval(ldb, ac, msg, "member",
1874 ldb_dn_get_linearized(ac->member_dn));
1876 ret = ldb_build_mod_req(&req, ldb, ac,
1878 ac, samldb_group_add_del_member_callback,
1880 if (ret != LDB_SUCCESS)
1883 return ldb_next_request(ac->module, req);
1887 static int samldb_prim_group_change_1(struct samldb_ctx *ac)
1889 struct ldb_context *ldb;
1892 ldb = ldb_module_get_ctx(ac->module);
1894 ac->user_dn = ac->msg->dn;
1896 rid = samdb_result_uint(ac->msg, "primaryGroupID", ~0);
1897 ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid);
1898 if (ac->sid == NULL)
1899 return LDB_ERR_OPERATIONS_ERROR;
1902 ac->prim_group_rid = 0;
1904 return samldb_next_step(ac);
1907 static int samldb_prim_group_change_2(struct samldb_ctx *ac)
1909 struct ldb_context *ldb;
1911 ldb = ldb_module_get_ctx(ac->module);
1913 if (ac->res_dn != NULL)
1914 ac->new_prim_group_dn = ac->res_dn;
1916 return LDB_ERR_UNWILLING_TO_PERFORM;
1918 ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb),
1919 ac->prim_group_rid);
1920 if (ac->sid == NULL)
1921 return LDB_ERR_OPERATIONS_ERROR;
1924 return samldb_next_step(ac);
1927 static int samldb_prim_group_change_4(struct samldb_ctx *ac);
1928 static int samldb_prim_group_change_5(struct samldb_ctx *ac);
1929 static int samldb_prim_group_change_6(struct samldb_ctx *ac);
1931 static int samldb_prim_group_change_3(struct samldb_ctx *ac)
1935 if (ac->res_dn != NULL)
1936 ac->old_prim_group_dn = ac->res_dn;
1938 return LDB_ERR_UNWILLING_TO_PERFORM;
1940 /* Only update when the primary group changed */
1941 if (ldb_dn_compare(ac->old_prim_group_dn, ac->new_prim_group_dn) != 0) {
1942 ac->member_dn = ac->user_dn;
1943 /* Remove the "member" attribute of the actual (new) primary
1946 ret = samldb_add_step(ac, samldb_prim_group_change_4);
1947 if (ret != LDB_SUCCESS) return ret;
1949 ret = samldb_add_step(ac, samldb_group_del_member);
1950 if (ret != LDB_SUCCESS) return ret;
1952 /* Add a "member" attribute for the previous primary group */
1954 ret = samldb_add_step(ac, samldb_prim_group_change_5);
1955 if (ret != LDB_SUCCESS) return ret;
1957 ret = samldb_add_step(ac, samldb_group_add_member);
1958 if (ret != LDB_SUCCESS) return ret;
1961 ret = samldb_add_step(ac, samldb_prim_group_change_6);
1962 if (ret != LDB_SUCCESS) return ret;
1964 return samldb_next_step(ac);
1967 static int samldb_prim_group_change_4(struct samldb_ctx *ac)
1969 ac->group_dn = ac->new_prim_group_dn;
1971 return samldb_next_step(ac);
1974 static int samldb_prim_group_change_5(struct samldb_ctx *ac)
1976 ac->group_dn = ac->old_prim_group_dn;
1978 return samldb_next_step(ac);
1981 static int samldb_prim_group_change_6(struct samldb_ctx *ac)
1983 return ldb_next_request(ac->module, ac->req);
1986 static int samldb_prim_group_change(struct samldb_ctx *ac)
1990 /* Finds out the DN of the new primary group */
1992 ret = samldb_add_step(ac, samldb_prim_group_change_1);
1993 if (ret != LDB_SUCCESS) return ret;
1995 ret = samldb_add_step(ac, samldb_dn_from_sid);
1996 if (ret != LDB_SUCCESS) return ret;
1998 ret = samldb_add_step(ac, samldb_user_dn_to_prim_group_rid);
1999 if (ret != LDB_SUCCESS) return ret;
2001 /* Finds out the DN of the old primary group */
2003 ret = samldb_add_step(ac, samldb_prim_group_change_2);
2004 if (ret != LDB_SUCCESS) return ret;
2006 ret = samldb_add_step(ac, samldb_dn_from_sid);
2007 if (ret != LDB_SUCCESS) return ret;
2009 ret = samldb_add_step(ac, samldb_prim_group_change_3);
2010 if (ret != LDB_SUCCESS) return ret;
2012 return samldb_first_step(ac);
2016 static int samldb_member_check_1(struct samldb_ctx *ac)
2018 struct ldb_context *ldb;
2019 struct ldb_message_element *el;
2021 ldb = ldb_module_get_ctx(ac->module);
2023 el = ldb_msg_find_element(ac->msg, "member");
2025 ac->user_dn = ldb_dn_from_ldb_val(ac, ldb, &el->values[ac->cnt]);
2026 if (!ldb_dn_validate(ac->user_dn))
2027 return LDB_ERR_OPERATIONS_ERROR;
2028 ac->prim_group_rid = 0;
2030 return samldb_next_step(ac);
2033 static int samldb_member_check_2(struct samldb_ctx *ac)
2035 struct ldb_context *ldb;
2037 ldb = ldb_module_get_ctx(ac->module);
2039 ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb),
2040 ac->prim_group_rid);
2041 if (ac->sid == NULL)
2042 return LDB_ERR_OPERATIONS_ERROR;
2045 return samldb_next_step(ac);
2048 static int samldb_member_check_3(struct samldb_ctx *ac)
2050 if (ldb_dn_compare(ac->res_dn, ac->msg->dn) == 0)
2051 return LDB_ERR_ENTRY_ALREADY_EXISTS;
2055 return samldb_next_step(ac);
2058 static int samldb_member_check_4(struct samldb_ctx *ac)
2060 return ldb_next_request(ac->module, ac->req);
2063 static int samldb_member_check(struct samldb_ctx *ac)
2065 struct ldb_message_element *el;
2068 el = ldb_msg_find_element(ac->msg, "member");
2070 for (i = 0; i < el->num_values; i++) {
2071 /* Denies to add "member"s to groups which are primary ones
2073 ret = samldb_add_step(ac, samldb_member_check_1);
2074 if (ret != LDB_SUCCESS) return ret;
2076 ret = samldb_add_step(ac, samldb_user_dn_to_prim_group_rid);
2077 if (ret != LDB_SUCCESS) return ret;
2079 ret = samldb_add_step(ac, samldb_member_check_2);
2080 if (ret != LDB_SUCCESS) return ret;
2082 ret = samldb_add_step(ac, samldb_dn_from_sid);
2083 if (ret != LDB_SUCCESS) return ret;
2085 ret = samldb_add_step(ac, samldb_member_check_3);
2086 if (ret != LDB_SUCCESS) return ret;
2089 ret = samldb_add_step(ac, samldb_member_check_4);
2090 if (ret != LDB_SUCCESS) return ret;
2092 return samldb_first_step(ac);
2096 static int samldb_prim_group_users_check_1(struct samldb_ctx *ac)
2098 ac->dn = ac->req->op.del.dn;
2101 return samldb_next_step(ac);
2104 static int samldb_prim_group_users_check_2(struct samldb_ctx *ac)
2109 if (ac->res_sid == NULL) {
2110 /* No SID - therefore ok here */
2111 return ldb_next_request(ac->module, ac->req);
2113 status = dom_sid_split_rid(ac, ac->res_sid, NULL, &rid);
2114 if (!NT_STATUS_IS_OK(status))
2115 return LDB_ERR_OPERATIONS_ERROR;
2118 /* Special object (security principal?) */
2119 return ldb_next_request(ac->module, ac->req);
2122 ac->prim_group_rid = rid;
2125 return samldb_next_step(ac);
2128 static int samldb_prim_group_users_check_3(struct samldb_ctx *ac)
2130 if (ac->users_cnt > 0)
2131 return LDB_ERR_ENTRY_ALREADY_EXISTS;
2133 return ldb_next_request(ac->module, ac->req);
2136 static int samldb_prim_group_users_check(struct samldb_ctx *ac)
2140 /* Finds out the SID/RID of the domain object */
2142 ret = samldb_add_step(ac, samldb_prim_group_users_check_1);
2143 if (ret != LDB_SUCCESS) return ret;
2145 ret = samldb_add_step(ac, samldb_sid_from_dn);
2146 if (ret != LDB_SUCCESS) return ret;
2148 /* Deny delete requests from groups which are primary ones */
2150 ret = samldb_add_step(ac, samldb_prim_group_users_check_2);
2151 if (ret != LDB_SUCCESS) return ret;
2153 ret = samldb_add_step(ac, samldb_prim_group_rid_to_users_cnt);
2154 if (ret != LDB_SUCCESS) return ret;
2156 ret = samldb_add_step(ac, samldb_prim_group_users_check_3);
2157 if (ret != LDB_SUCCESS) return ret;
2159 return samldb_first_step(ac);
2164 static int samldb_add(struct ldb_module *module, struct ldb_request *req)
2166 struct ldb_context *ldb;
2167 struct samldb_ctx *ac;
2170 ldb = ldb_module_get_ctx(module);
2171 ldb_debug(ldb, LDB_DEBUG_TRACE, "samldb_add\n");
2173 /* do not manipulate our control entries */
2174 if (ldb_dn_is_special(req->op.add.message->dn)) {
2175 return ldb_next_request(module, req);
2178 ac = samldb_ctx_init(module, req);
2180 return LDB_ERR_OPERATIONS_ERROR;
2183 /* build the new msg */
2184 ac->msg = ldb_msg_copy(ac, ac->req->op.add.message);
2187 ldb_debug(ldb, LDB_DEBUG_FATAL,
2188 "samldb_add: ldb_msg_copy failed!\n");
2189 return LDB_ERR_OPERATIONS_ERROR;
2192 if (samdb_find_attribute(ldb, ac->msg,
2193 "objectclass", "computer") != NULL) {
2195 /* make sure the computer object also has the 'user'
2196 * objectclass so it will be handled by the next call */
2197 ret = samdb_find_or_add_value(ldb, ac->msg,
2198 "objectclass", "user");
2199 if (ret != LDB_SUCCESS) {
2205 if (samdb_find_attribute(ldb, ac->msg,
2206 "objectclass", "user") != NULL) {
2208 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
2209 if (ret != LDB_SUCCESS) {
2214 return samldb_fill_object(ac, "user");
2217 if (samdb_find_attribute(ldb, ac->msg,
2218 "objectclass", "group") != NULL) {
2220 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
2221 if (ret != LDB_SUCCESS) {
2226 return samldb_fill_object(ac, "group");
2229 /* perhaps a foreignSecurityPrincipal? */
2230 if (samdb_find_attribute(ldb, ac->msg,
2232 "foreignSecurityPrincipal") != NULL) {
2234 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
2235 if (ret != LDB_SUCCESS) {
2240 return samldb_fill_foreignSecurityPrincipal_object(ac);
2243 if (samdb_find_attribute(ldb, ac->msg,
2244 "objectclass", "classSchema") != NULL) {
2246 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
2247 if (ret != LDB_SUCCESS) {
2252 return samldb_fill_object(ac, "classSchema");
2255 if (samdb_find_attribute(ldb, ac->msg,
2256 "objectclass", "attributeSchema") != NULL) {
2258 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
2259 if (ret != LDB_SUCCESS) {
2264 return samldb_fill_object(ac, "attributeSchema");
2269 /* nothing matched, go on */
2270 return ldb_next_request(module, req);
2274 static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
2276 struct ldb_context *ldb;
2277 struct ldb_message *msg;
2278 struct ldb_message_element *el, *el2;
2280 uint32_t account_type;
2282 if (ldb_dn_is_special(req->op.mod.message->dn)) {
2283 /* do not manipulate our control entries */
2284 return ldb_next_request(module, req);
2287 ldb = ldb_module_get_ctx(module);
2289 if (ldb_msg_find_element(req->op.mod.message, "sAMAccountType") != NULL) {
2290 ldb_asprintf_errstring(ldb,
2291 "sAMAccountType must not be specified!");
2292 return LDB_ERR_UNWILLING_TO_PERFORM;
2295 /* TODO: do not modify original request, create a new one */
2297 el = ldb_msg_find_element(req->op.mod.message, "groupType");
2298 if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
2299 uint32_t group_type;
2301 req->op.mod.message = msg = ldb_msg_copy_shallow(req,
2302 req->op.mod.message);
2304 group_type = strtoul((const char *)el->values[0].data, NULL, 0);
2305 account_type = ds_gtype2atype(group_type);
2306 ret = samdb_msg_add_uint(ldb, msg, msg,
2309 if (ret != LDB_SUCCESS) {
2312 el2 = ldb_msg_find_element(msg, "sAMAccountType");
2313 el2->flags = LDB_FLAG_MOD_REPLACE;
2316 el = ldb_msg_find_element(req->op.mod.message, "userAccountControl");
2317 if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
2318 uint32_t user_account_control;
2320 req->op.mod.message = msg = ldb_msg_copy_shallow(req,
2321 req->op.mod.message);
2323 user_account_control = strtoul((const char *)el->values[0].data,
2325 account_type = ds_uf2atype(user_account_control);
2326 ret = samdb_msg_add_uint(ldb, msg, msg,
2329 if (ret != LDB_SUCCESS) {
2332 el2 = ldb_msg_find_element(msg, "sAMAccountType");
2333 el2->flags = LDB_FLAG_MOD_REPLACE;
2335 if (user_account_control & UF_SERVER_TRUST_ACCOUNT) {
2336 ret = samdb_msg_add_string(ldb, msg, msg,
2337 "isCriticalSystemObject", "TRUE");
2338 if (ret != LDB_SUCCESS) {
2341 el2 = ldb_msg_find_element(msg, "isCriticalSystemObject");
2342 el2->flags = LDB_FLAG_MOD_REPLACE;
2346 el = ldb_msg_find_element(req->op.mod.message, "primaryGroupID");
2347 if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
2348 struct samldb_ctx *ac;
2350 ac = samldb_ctx_init(module, req);
2352 return LDB_ERR_OPERATIONS_ERROR;
2354 req->op.mod.message = ac->msg = ldb_msg_copy_shallow(req,
2355 req->op.mod.message);
2357 return samldb_prim_group_change(ac);
2360 el = ldb_msg_find_element(req->op.mod.message, "member");
2361 if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
2362 struct samldb_ctx *ac;
2364 ac = samldb_ctx_init(module, req);
2366 return LDB_ERR_OPERATIONS_ERROR;
2368 req->op.mod.message = ac->msg = ldb_msg_copy_shallow(req,
2369 req->op.mod.message);
2371 return samldb_member_check(ac);
2374 /* nothing matched, go on */
2375 return ldb_next_request(module, req);
2379 static int samldb_delete(struct ldb_module *module, struct ldb_request *req)
2381 struct samldb_ctx *ac;
2383 if (ldb_dn_is_special(req->op.del.dn)) {
2384 /* do not manipulate our control entries */
2385 return ldb_next_request(module, req);
2388 ac = samldb_ctx_init(module, req);
2390 return LDB_ERR_OPERATIONS_ERROR;
2392 return samldb_prim_group_users_check(ac);
2396 static int samldb_init(struct ldb_module *module)
2398 return ldb_next_init(module);
2401 _PUBLIC_ const struct ldb_module_ops ldb_samldb_module_ops = {
2403 .init_context = samldb_init,
2405 .modify = samldb_modify,
2406 .del = samldb_delete