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 "libcli/security/security.h"
37 #include "librpc/gen_ndr/ndr_security.h"
38 #include "../lib/util/util_ldb.h"
43 typedef int (*samldb_step_fn_t)(struct samldb_ctx *);
46 struct samldb_step *next;
51 struct ldb_module *module;
52 struct ldb_request *req;
54 /* used for add operations */
57 /* the resulting message */
58 struct ldb_message *msg;
60 /* used to find parent domain */
61 struct ldb_dn *check_dn;
62 struct ldb_dn *domain_dn;
63 struct dom_sid *domain_sid;
66 /* holds the entry SID */
69 /* holds a generic dn */
72 /* used in conjunction with "sid" in "samldb_dn_from_sid" */
73 struct ldb_dn *res_dn;
75 /* used in conjunction with "dn" in "samldb_sid_from_dn" */
76 struct dom_sid *res_sid;
78 /* used in "samldb_user_dn_to_prim_group_rid" */
79 uint32_t prim_group_rid;
81 /* used in conjunction with "prim_group_rid" in
82 * "samldb_prim_group_rid_to_users_cnt" */
83 unsigned int users_cnt;
85 /* used in "samldb_group_add_member" and "samldb_group_del_member" */
86 struct ldb_dn *group_dn;
87 struct ldb_dn *member_dn;
89 /* used in "samldb_primary_group_change" */
90 struct ldb_dn *user_dn;
91 struct ldb_dn *old_prim_group_dn, *new_prim_group_dn;
93 /* generic counter - used in "samldb_member_check" */
96 /* all the async steps necessary to complete the operation */
97 struct samldb_step *steps;
98 struct samldb_step *curstep;
101 static struct samldb_ctx *samldb_ctx_init(struct ldb_module *module,
102 struct ldb_request *req)
104 struct ldb_context *ldb;
105 struct samldb_ctx *ac;
107 ldb = ldb_module_get_ctx(module);
109 ac = talloc_zero(req, struct samldb_ctx);
121 static int samldb_add_step(struct samldb_ctx *ac, samldb_step_fn_t fn)
123 struct samldb_step *step, *stepper;
125 step = talloc_zero(ac, struct samldb_step);
127 return LDB_ERR_OPERATIONS_ERROR;
132 if (ac->steps == NULL) {
136 if (ac->curstep == NULL)
137 return LDB_ERR_OPERATIONS_ERROR;
138 for (stepper = ac->curstep; stepper->next != NULL;
139 stepper = stepper->next);
140 stepper->next = step;
146 static int samldb_first_step(struct samldb_ctx *ac)
148 if (ac->steps == NULL) {
149 return LDB_ERR_OPERATIONS_ERROR;
152 ac->curstep = ac->steps;
153 return ac->curstep->fn(ac);
156 static int samldb_next_step(struct samldb_ctx *ac)
158 if (ac->curstep->next) {
159 ac->curstep = ac->curstep->next;
160 return ac->curstep->fn(ac);
163 /* it is an error if the last step does not properly
164 * return to the upper module by itself */
165 return LDB_ERR_OPERATIONS_ERROR;
169 * samldb_get_parent_domain (async)
172 static int samldb_get_parent_domain(struct samldb_ctx *ac);
174 static int samldb_get_parent_domain_callback(struct ldb_request *req,
175 struct ldb_reply *ares)
177 struct ldb_context *ldb;
178 struct samldb_ctx *ac;
182 ac = talloc_get_type(req->context, struct samldb_ctx);
183 ldb = ldb_module_get_ctx(ac->module);
186 ret = LDB_ERR_OPERATIONS_ERROR;
189 if (ares->error != LDB_SUCCESS) {
190 return ldb_module_done(ac->req, ares->controls,
191 ares->response, ares->error);
194 switch (ares->type) {
195 case LDB_REPLY_ENTRY:
197 if ((ac->domain_dn != NULL) || (ac->domain_sid != NULL)) {
199 ldb_set_errstring(ldb,
200 "Invalid number of results while searching "
201 "for domain object!");
202 ret = LDB_ERR_OPERATIONS_ERROR;
206 nextRid = ldb_msg_find_attr_as_string(ares->message,
208 if (nextRid == NULL) {
209 ldb_asprintf_errstring(ldb,
210 "While looking for domain above %s attribute nextRid not found in %s!\n",
211 ldb_dn_get_linearized(
212 ac->req->op.add.message->dn),
213 ldb_dn_get_linearized(ares->message->dn));
214 ret = LDB_ERR_OPERATIONS_ERROR;
218 ac->next_rid = strtol(nextRid, NULL, 0);
220 ac->domain_sid = samdb_result_dom_sid(ac, ares->message,
222 if (ac->domain_sid == NULL) {
223 ldb_set_errstring(ldb,
224 "Unable to get the parent domain SID!\n");
225 ret = LDB_ERR_CONSTRAINT_VIOLATION;
228 ac->domain_dn = ldb_dn_copy(ac, ares->message->dn);
234 case LDB_REPLY_REFERRAL:
242 if ((ac->domain_dn == NULL) || (ac->domain_sid == NULL)) {
243 /* not found -> retry */
244 ret = samldb_get_parent_domain(ac);
247 ret = samldb_next_step(ac);
253 if (ret != LDB_SUCCESS) {
254 return ldb_module_done(ac->req, NULL, NULL, ret);
260 /* Find a domain object in the parents of a particular DN. */
261 static int samldb_get_parent_domain(struct samldb_ctx *ac)
263 struct ldb_context *ldb;
264 static const char * const attrs[] = { "objectSid", "nextRid", NULL };
265 struct ldb_request *req;
269 ldb = ldb_module_get_ctx(ac->module);
271 if (ac->check_dn == NULL) {
272 return LDB_ERR_OPERATIONS_ERROR;
275 dn = ldb_dn_get_parent(ac, ac->check_dn);
277 ldb_set_errstring(ldb,
278 "Unable to find parent domain object!");
279 return LDB_ERR_CONSTRAINT_VIOLATION;
284 ret = ldb_build_search_req(&req, ldb, ac,
286 "(|(objectClass=domain)"
287 "(objectClass=builtinDomain)"
288 "(objectClass=samba4LocalDomain))",
291 ac, samldb_get_parent_domain_callback,
294 if (ret != LDB_SUCCESS) {
298 return ldb_next_request(ac->module, req);
302 static int samldb_generate_samAccountName(struct ldb_message *msg)
306 /* Format: $000000-000000000000 */
308 name = talloc_asprintf(msg, "$%.6X-%.6X%.6X",
309 (unsigned int)generate_random(),
310 (unsigned int)generate_random(),
311 (unsigned int)generate_random());
313 return LDB_ERR_OPERATIONS_ERROR;
315 return ldb_msg_add_steal_string(msg, "samAccountName", name);
319 * samldb_check_samAccountName (async)
322 static int samldb_check_samAccountName_callback(struct ldb_request *req,
323 struct ldb_reply *ares)
325 struct samldb_ctx *ac;
328 ac = talloc_get_type(req->context, struct samldb_ctx);
330 if (ares->error != LDB_SUCCESS) {
331 return ldb_module_done(ac->req, ares->controls,
332 ares->response, ares->error);
335 switch (ares->type) {
336 case LDB_REPLY_ENTRY:
337 /* if we get an entry it means this samAccountName
339 return ldb_module_done(ac->req, NULL, NULL,
340 LDB_ERR_ENTRY_ALREADY_EXISTS);
342 case LDB_REPLY_REFERRAL:
343 /* this should not happen */
344 return ldb_module_done(ac->req, NULL, NULL,
345 LDB_ERR_OPERATIONS_ERROR);
348 /* not found, go on */
350 ret = samldb_next_step(ac);
354 if (ret != LDB_SUCCESS) {
355 return ldb_module_done(ac->req, NULL, NULL, ret);
361 static int samldb_check_samAccountName(struct samldb_ctx *ac)
363 struct ldb_context *ldb;
364 struct ldb_request *req;
369 ldb = ldb_module_get_ctx(ac->module);
371 if (ldb_msg_find_element(ac->msg, "samAccountName") == NULL) {
372 ret = samldb_generate_samAccountName(ac->msg);
373 if (ret != LDB_SUCCESS) {
378 name = ldb_msg_find_attr_as_string(ac->msg, "samAccountName", NULL);
380 return LDB_ERR_OPERATIONS_ERROR;
382 filter = talloc_asprintf(ac, "samAccountName=%s", ldb_binary_encode_string(ac, name));
383 if (filter == NULL) {
384 return LDB_ERR_OPERATIONS_ERROR;
387 ret = ldb_build_search_req(&req, ldb, ac,
388 ac->domain_dn, LDB_SCOPE_SUBTREE,
391 ac, samldb_check_samAccountName_callback,
394 if (ret != LDB_SUCCESS) {
397 return ldb_next_request(ac->module, req);
401 static int samldb_check_samAccountType(struct samldb_ctx *ac)
403 struct ldb_context *ldb;
404 unsigned int account_type;
405 unsigned int group_type;
409 ldb = ldb_module_get_ctx(ac->module);
411 /* make sure sAMAccountType is not specified */
412 if (ldb_msg_find_element(ac->msg, "sAMAccountType") != NULL) {
413 ldb_asprintf_errstring(ldb,
414 "sAMAccountType must not be specified!");
415 return LDB_ERR_UNWILLING_TO_PERFORM;
418 if (strcmp("user", ac->type) == 0) {
419 uac = samdb_result_uint(ac->msg, "userAccountControl", 0);
421 ldb_asprintf_errstring(ldb,
422 "userAccountControl invalid!");
423 return LDB_ERR_UNWILLING_TO_PERFORM;
425 account_type = ds_uf2atype(uac);
426 ret = samdb_msg_add_uint(ldb,
430 if (ret != LDB_SUCCESS) {
435 if (strcmp("group", ac->type) == 0) {
437 group_type = samdb_result_uint(ac->msg, "groupType", 0);
438 if (group_type == 0) {
439 ldb_asprintf_errstring(ldb,
440 "groupType invalid!");
441 return LDB_ERR_UNWILLING_TO_PERFORM;
443 account_type = ds_gtype2atype(group_type);
444 ret = samdb_msg_add_uint(ldb,
448 if (ret != LDB_SUCCESS) {
454 return samldb_next_step(ac);
459 * samldb_get_sid_domain (async)
462 static int samldb_get_sid_domain_callback(struct ldb_request *req,
463 struct ldb_reply *ares)
465 struct ldb_context *ldb;
466 struct samldb_ctx *ac;
470 ac = talloc_get_type(req->context, struct samldb_ctx);
471 ldb = ldb_module_get_ctx(ac->module);
474 ret = LDB_ERR_OPERATIONS_ERROR;
477 if (ares->error != LDB_SUCCESS) {
478 return ldb_module_done(ac->req, ares->controls,
479 ares->response, ares->error);
482 switch (ares->type) {
483 case LDB_REPLY_ENTRY:
485 if (ac->next_rid != 0) {
487 ldb_set_errstring(ldb,
488 "Invalid number of results while searching "
489 "for domain object!");
490 ret = LDB_ERR_OPERATIONS_ERROR;
494 nextRid = ldb_msg_find_attr_as_string(ares->message,
496 if (nextRid == NULL) {
497 ldb_asprintf_errstring(ldb,
498 "Attribute nextRid not found in %s!\n",
499 ldb_dn_get_linearized(ares->message->dn));
500 ret = LDB_ERR_OPERATIONS_ERROR;
504 ac->next_rid = strtol(nextRid, NULL, 0);
506 ac->domain_dn = ldb_dn_copy(ac, ares->message->dn);
512 case LDB_REPLY_REFERRAL:
520 if (ac->next_rid == 0) {
521 ldb_asprintf_errstring(ldb,
522 "Unable to get nextRid from domain entry!\n");
523 ret = LDB_ERR_OPERATIONS_ERROR;
528 ret = samldb_next_step(ac);
533 if (ret != LDB_SUCCESS) {
534 return ldb_module_done(ac->req, NULL, NULL, ret);
540 /* Find a domain object in the parents of a particular DN. */
541 static int samldb_get_sid_domain(struct samldb_ctx *ac)
543 struct ldb_context *ldb;
544 static const char * const attrs[2] = { "nextRid", NULL };
545 struct ldb_request *req;
549 ldb = ldb_module_get_ctx(ac->module);
551 if (ac->sid == NULL) {
552 return LDB_ERR_OPERATIONS_ERROR;
555 ac->domain_sid = dom_sid_dup(ac, ac->sid);
556 if (!ac->domain_sid) {
557 return LDB_ERR_OPERATIONS_ERROR;
559 /* get the domain component part of the provided SID */
560 ac->domain_sid->num_auths--;
562 filter = talloc_asprintf(ac, "(&(objectSid=%s)"
563 "(|(objectClass=domain)"
564 "(objectClass=builtinDomain)"
565 "(objectClass=samba4LocalDomain)))",
566 ldap_encode_ndr_dom_sid(ac, ac->domain_sid));
567 if (filter == NULL) {
568 return LDB_ERR_OPERATIONS_ERROR;
571 ret = ldb_build_search_req(&req, ldb, ac,
572 ldb_get_default_basedn(ldb),
576 ac, samldb_get_sid_domain_callback,
579 if (ret != LDB_SUCCESS) {
584 return ldb_next_request(ac->module, req);
588 * samldb_dn_from_sid (async)
591 static int samldb_dn_from_sid(struct samldb_ctx *ac);
593 static int samldb_dn_from_sid_callback(struct ldb_request *req,
594 struct ldb_reply *ares)
596 struct ldb_context *ldb;
597 struct samldb_ctx *ac;
600 ac = talloc_get_type(req->context, struct samldb_ctx);
601 ldb = ldb_module_get_ctx(ac->module);
604 ret = LDB_ERR_OPERATIONS_ERROR;
607 if (ares->error != LDB_SUCCESS) {
608 return ldb_module_done(ac->req, ares->controls,
609 ares->response, ares->error);
612 switch (ares->type) {
613 case LDB_REPLY_ENTRY:
615 if (ac->res_dn != NULL) {
617 ldb_set_errstring(ldb,
618 "Invalid number of results while searching "
619 "for domain objects!");
620 ret = LDB_ERR_OPERATIONS_ERROR;
623 ac->res_dn = ldb_dn_copy(ac, ares->message->dn);
629 case LDB_REPLY_REFERRAL:
638 /* found or not found, go on */
639 ret = samldb_next_step(ac);
644 if (ret != LDB_SUCCESS) {
645 return ldb_module_done(ac->req, NULL, NULL, ret);
651 /* Finds the DN "res_dn" of an object with a given SID "sid" */
652 static int samldb_dn_from_sid(struct samldb_ctx *ac)
654 struct ldb_context *ldb;
655 static const char * const attrs[] = { NULL };
656 struct ldb_request *req;
660 ldb = ldb_module_get_ctx(ac->module);
663 return LDB_ERR_OPERATIONS_ERROR;
665 filter = talloc_asprintf(ac, "(objectSid=%s)",
666 ldap_encode_ndr_dom_sid(ac, ac->sid));
668 return LDB_ERR_OPERATIONS_ERROR;
670 ret = ldb_build_search_req(&req, ldb, ac,
671 ldb_get_default_basedn(ldb),
675 ac, samldb_dn_from_sid_callback,
677 if (ret != LDB_SUCCESS)
680 return ldb_next_request(ac->module, req);
684 static int samldb_check_primaryGroupID_1(struct samldb_ctx *ac)
686 struct ldb_context *ldb;
689 ldb = ldb_module_get_ctx(ac->module);
691 rid = samdb_result_uint(ac->msg, "primaryGroupID", ~0);
692 ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid);
694 return LDB_ERR_OPERATIONS_ERROR;
697 return samldb_next_step(ac);
700 static int samldb_check_primaryGroupID_2(struct samldb_ctx *ac)
702 if (ac->res_dn == NULL) {
703 struct ldb_context *ldb;
704 ldb = ldb_module_get_ctx(ac->module);
705 ldb_asprintf_errstring(ldb,
706 "Failed to find group sid %s",
707 dom_sid_string(ac->sid, ac->sid));
708 return LDB_ERR_UNWILLING_TO_PERFORM;
711 return samldb_next_step(ac);
715 static bool samldb_msg_add_sid(struct ldb_message *msg,
717 const struct dom_sid *sid)
720 enum ndr_err_code ndr_err;
722 ndr_err = ndr_push_struct_blob(&v, msg, NULL, sid,
723 (ndr_push_flags_fn_t)ndr_push_dom_sid);
724 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
727 return (ldb_msg_add_value(msg, name, &v, NULL) == 0);
730 static int samldb_new_sid(struct samldb_ctx *ac)
733 if (ac->domain_sid == NULL || ac->next_rid == 0) {
734 return LDB_ERR_OPERATIONS_ERROR;
737 ac->sid = dom_sid_add_rid(ac, ac->domain_sid, ac->next_rid + 1);
738 if (ac->sid == NULL) {
739 return LDB_ERR_OPERATIONS_ERROR;
742 if ( ! samldb_msg_add_sid(ac->msg, "objectSid", ac->sid)) {
743 return LDB_ERR_OPERATIONS_ERROR;
746 return samldb_next_step(ac);
750 * samldb_notice_sid_callback (async)
753 static int samldb_notice_sid_callback(struct ldb_request *req,
754 struct ldb_reply *ares)
756 struct ldb_context *ldb;
757 struct samldb_ctx *ac;
760 ac = talloc_get_type(req->context, struct samldb_ctx);
761 ldb = ldb_module_get_ctx(ac->module);
764 ret = LDB_ERR_OPERATIONS_ERROR;
767 if (ares->error != LDB_SUCCESS) {
768 return ldb_module_done(ac->req, ares->controls,
769 ares->response, ares->error);
771 if (ares->type != LDB_REPLY_DONE) {
772 ldb_set_errstring(ldb,
773 "Invalid reply type!\n");
774 ret = LDB_ERR_OPERATIONS_ERROR;
778 ret = samldb_next_step(ac);
781 if (ret != LDB_SUCCESS) {
782 return ldb_module_done(ac->req, NULL, NULL, ret);
788 /* If we are adding new users/groups, we need to update the nextRid
789 * attribute to be 'above' the new/incoming RID. Attempt to do it
791 static int samldb_notice_sid(struct samldb_ctx *ac)
793 struct ldb_context *ldb;
794 uint32_t old_id, new_id;
795 struct ldb_request *req;
796 struct ldb_message *msg;
797 struct ldb_message_element *els;
798 struct ldb_val *vals;
801 ldb = ldb_module_get_ctx(ac->module);
802 old_id = ac->next_rid;
803 new_id = ac->sid->sub_auths[ac->sid->num_auths - 1];
805 if (old_id >= new_id) {
806 /* no need to update the domain nextRid attribute */
807 return samldb_next_step(ac);
810 /* we do a delete and add as a single operation. That prevents
811 a race, in case we are not actually on a transaction db */
812 msg = ldb_msg_new(ac);
815 return LDB_ERR_OPERATIONS_ERROR;
817 els = talloc_array(msg, struct ldb_message_element, 2);
820 return LDB_ERR_OPERATIONS_ERROR;
822 vals = talloc_array(msg, struct ldb_val, 2);
825 return LDB_ERR_OPERATIONS_ERROR;
827 msg->dn = ac->domain_dn;
828 msg->num_elements = 2;
831 els[0].num_values = 1;
832 els[0].values = &vals[0];
833 els[0].flags = LDB_FLAG_MOD_DELETE;
834 els[0].name = talloc_strdup(msg, "nextRid");
837 return LDB_ERR_OPERATIONS_ERROR;
840 els[1].num_values = 1;
841 els[1].values = &vals[1];
842 els[1].flags = LDB_FLAG_MOD_ADD;
843 els[1].name = els[0].name;
845 vals[0].data = (uint8_t *)talloc_asprintf(vals, "%u", old_id);
848 return LDB_ERR_OPERATIONS_ERROR;
850 vals[0].length = strlen((char *)vals[0].data);
852 vals[1].data = (uint8_t *)talloc_asprintf(vals, "%u", new_id);
855 return LDB_ERR_OPERATIONS_ERROR;
857 vals[1].length = strlen((char *)vals[1].data);
859 ret = ldb_build_mod_req(&req, ldb, ac,
861 ac, samldb_notice_sid_callback,
863 if (ret != LDB_SUCCESS) {
867 return ldb_next_request(ac->module, req);
871 * samldb_add_entry (async)
874 static int samldb_add_entry_callback(struct ldb_request *req,
875 struct ldb_reply *ares)
877 struct ldb_context *ldb;
878 struct samldb_ctx *ac;
880 ac = talloc_get_type(req->context, struct samldb_ctx);
881 ldb = ldb_module_get_ctx(ac->module);
884 return ldb_module_done(ac->req, NULL, NULL,
885 LDB_ERR_OPERATIONS_ERROR);
887 if (ares->error != LDB_SUCCESS) {
888 return ldb_module_done(ac->req, ares->controls,
889 ares->response, ares->error);
891 if (ares->type != LDB_REPLY_DONE) {
892 ldb_set_errstring(ldb,
893 "Invalid reply type!\n");
894 return ldb_module_done(ac->req, NULL, NULL,
895 LDB_ERR_OPERATIONS_ERROR);
898 /* we exit the samldb module here */
899 return ldb_module_done(ac->req, ares->controls,
900 ares->response, LDB_SUCCESS);
903 static int samldb_add_entry(struct samldb_ctx *ac)
905 struct ldb_context *ldb;
906 struct ldb_request *req;
909 ldb = ldb_module_get_ctx(ac->module);
911 ret = ldb_build_add_req(&req, ldb, ac,
914 ac, samldb_add_entry_callback,
916 if (ret != LDB_SUCCESS) {
920 return ldb_next_request(ac->module, req);
924 static int samldb_fill_object(struct samldb_ctx *ac, const char *type)
926 struct ldb_context *ldb;
929 ldb = ldb_module_get_ctx(ac->module);
931 /* search for a parent domain objet */
932 ac->check_dn = ac->req->op.add.message->dn;
933 ret = samldb_add_step(ac, samldb_get_parent_domain);
934 if (ret != LDB_SUCCESS) return ret;
936 /* Add informations for the different account types */
938 if (strcmp(ac->type, "user") == 0) {
939 ret = samdb_find_or_add_attribute(ldb, ac->msg,
940 "userAccountControl", "546");
941 if (ret != LDB_SUCCESS) return ret;
942 ret = samdb_find_or_add_attribute(ldb, ac->msg,
944 if (ret != LDB_SUCCESS) return ret;
945 ret = samdb_find_or_add_attribute(ldb, ac->msg,
947 if (ret != LDB_SUCCESS) return ret;
948 ret = samdb_find_or_add_attribute(ldb, ac->msg,
950 if (ret != LDB_SUCCESS) return ret;
951 ret = samdb_find_or_add_attribute(ldb, ac->msg,
952 "badPasswordTime", "0");
953 if (ret != LDB_SUCCESS) return ret;
954 ret = samdb_find_or_add_attribute(ldb, ac->msg,
956 if (ret != LDB_SUCCESS) return ret;
957 ret = samdb_find_or_add_attribute(ldb, ac->msg,
959 if (ret != LDB_SUCCESS) return ret;
960 ret = samdb_find_or_add_attribute(ldb, ac->msg,
962 if (ret != LDB_SUCCESS) return ret;
963 ret = samdb_find_or_add_attribute(ldb, ac->msg,
964 "primaryGroupID", "513");
965 if (ret != LDB_SUCCESS) return ret;
966 ret = samdb_find_or_add_attribute(ldb, ac->msg,
967 "accountExpires", "9223372036854775807");
968 if (ret != LDB_SUCCESS) return ret;
969 ret = samdb_find_or_add_attribute(ldb, ac->msg,
971 if (ret != LDB_SUCCESS) return ret;
972 } else if (strcmp(ac->type, "group") == 0) {
973 ret = samdb_find_or_add_attribute(ldb, ac->msg,
974 "groupType", "-2147483646");
975 if (ret != LDB_SUCCESS) return ret;
977 /* we should only have "user" and "group" */
978 ldb_asprintf_errstring(ldb,
979 "Invalid entry type!\n");
980 return LDB_ERR_OPERATIONS_ERROR;
983 /* check if we have a valid samAccountName */
984 ret = samldb_add_step(ac, samldb_check_samAccountName);
985 if (ret != LDB_SUCCESS) return ret;
987 /* check account_type/group_type */
988 ret = samldb_add_step(ac, samldb_check_samAccountType);
989 if (ret != LDB_SUCCESS) return ret;
991 /* check if we have a valid primary group ID */
992 if (strcmp(ac->type, "user") == 0) {
993 ret = samldb_add_step(ac, samldb_check_primaryGroupID_1);
994 if (ret != LDB_SUCCESS) return ret;
995 ret = samldb_add_step(ac, samldb_dn_from_sid);
996 if (ret != LDB_SUCCESS) return ret;
997 ret = samldb_add_step(ac, samldb_check_primaryGroupID_2);
998 if (ret != LDB_SUCCESS) return ret;
1001 /* check if we have a valid SID */
1002 ac->sid = samdb_result_dom_sid(ac, ac->msg, "objectSid");
1004 ret = samldb_add_step(ac, samldb_new_sid);
1005 if (ret != LDB_SUCCESS) return ret;
1007 ret = samldb_add_step(ac, samldb_get_sid_domain);
1008 if (ret != LDB_SUCCESS) return ret;
1011 ret = samldb_add_step(ac, samldb_notice_sid);
1012 if (ret != LDB_SUCCESS) return ret;
1014 /* finally proceed with adding the entry */
1015 ret = samldb_add_step(ac, samldb_add_entry);
1016 if (ret != LDB_SUCCESS) return ret;
1018 return samldb_first_step(ac);
1022 * samldb_foreign_notice_sid (async)
1025 static int samldb_foreign_notice_sid_callback(struct ldb_request *req,
1026 struct ldb_reply *ares)
1028 struct ldb_context *ldb;
1029 struct samldb_ctx *ac;
1030 const char *nextRid;
1034 ac = talloc_get_type(req->context, struct samldb_ctx);
1035 ldb = ldb_module_get_ctx(ac->module);
1038 ret = LDB_ERR_OPERATIONS_ERROR;
1041 if (ares->error != LDB_SUCCESS) {
1042 return ldb_module_done(ac->req, ares->controls,
1043 ares->response, ares->error);
1046 switch (ares->type) {
1047 case LDB_REPLY_ENTRY:
1049 if (ac->next_rid != 0) {
1051 ldb_set_errstring(ldb,
1052 "Invalid number of results while searching "
1053 "for domain object!");
1054 ret = LDB_ERR_OPERATIONS_ERROR;
1058 nextRid = ldb_msg_find_attr_as_string(ares->message,
1060 if (nextRid == NULL) {
1061 ldb_asprintf_errstring(ldb,
1062 "while looking for forign sid %s attribute nextRid not found in %s\n",
1063 dom_sid_string(ares, ac->sid),
1064 ldb_dn_get_linearized(ares->message->dn));
1065 ret = LDB_ERR_OPERATIONS_ERROR;
1069 ac->next_rid = strtol(nextRid, NULL, 0);
1071 ac->domain_dn = ldb_dn_copy(ac, ares->message->dn);
1073 name = samdb_result_string(ares->message, "name", NULL);
1074 ldb_debug(ldb, LDB_DEBUG_TRACE,
1075 "NOTE (strange but valid): Adding foreign SID "
1076 "record with SID %s, but this domain (%s) is "
1077 "not foreign in the database",
1078 dom_sid_string(ares, ac->sid), name);
1084 case LDB_REPLY_REFERRAL:
1090 case LDB_REPLY_DONE:
1093 /* if this is a fake foreign SID, notice the SID */
1094 if (ac->domain_dn) {
1095 ret = samldb_notice_sid(ac);
1100 ret = samldb_next_step(ac);
1105 if (ret != LDB_SUCCESS) {
1106 return ldb_module_done(ac->req, NULL, NULL, ret);
1112 /* Find a domain object in the parents of a particular DN. */
1113 static int samldb_foreign_notice_sid(struct samldb_ctx *ac)
1115 struct ldb_context *ldb;
1116 static const char * const attrs[3] = { "nextRid", "name", NULL };
1117 struct ldb_request *req;
1122 ldb = ldb_module_get_ctx(ac->module);
1124 if (ac->sid == NULL) {
1125 return LDB_ERR_OPERATIONS_ERROR;
1128 status = dom_sid_split_rid(ac, ac->sid, &ac->domain_sid, NULL);
1129 if (!NT_STATUS_IS_OK(status)) {
1130 return LDB_ERR_OPERATIONS_ERROR;
1133 filter = talloc_asprintf(ac, "(&(objectSid=%s)(objectclass=domain))",
1134 ldap_encode_ndr_dom_sid(ac, ac->domain_sid));
1135 if (filter == NULL) {
1136 return LDB_ERR_OPERATIONS_ERROR;
1139 ret = ldb_build_search_req(&req, ldb, ac,
1140 ldb_get_default_basedn(ldb),
1144 ac, samldb_foreign_notice_sid_callback,
1147 if (ret != LDB_SUCCESS) {
1151 return ldb_next_request(ac->module, req);
1155 static int samldb_fill_foreignSecurityPrincipal_object(struct samldb_ctx *ac)
1157 struct ldb_context *ldb;
1160 ldb = ldb_module_get_ctx(ac->module);
1164 ac->sid = samdb_result_dom_sid(ac->msg, ac->msg, "objectSid");
1165 if (ac->sid == NULL) {
1166 ac->sid = dom_sid_parse_talloc(ac->msg,
1167 (const char *)ldb_dn_get_rdn_val(ac->msg->dn)->data);
1169 ldb_set_errstring(ldb,
1170 "No valid SID found in "
1171 "ForeignSecurityPrincipal CN!");
1173 return LDB_ERR_CONSTRAINT_VIOLATION;
1175 if ( ! samldb_msg_add_sid(ac->msg, "objectSid", ac->sid)) {
1177 return LDB_ERR_OPERATIONS_ERROR;
1181 /* check if we need to notice this SID */
1182 ret = samldb_add_step(ac, samldb_foreign_notice_sid);
1183 if (ret != LDB_SUCCESS) return ret;
1185 /* finally proceed with adding the entry */
1186 ret = samldb_add_step(ac, samldb_add_entry);
1187 if (ret != LDB_SUCCESS) return ret;
1189 return samldb_first_step(ac);
1192 static int samldb_check_rdn(struct ldb_module *module, struct ldb_dn *dn)
1194 struct ldb_context *ldb;
1195 const char *rdn_name;
1197 ldb = ldb_module_get_ctx(module);
1198 rdn_name = ldb_dn_get_rdn_name(dn);
1200 if (strcasecmp(rdn_name, "cn") != 0) {
1201 ldb_asprintf_errstring(ldb,
1202 "Bad RDN (%s=) for samldb object, "
1203 "should be CN=!\n", rdn_name);
1204 return LDB_ERR_CONSTRAINT_VIOLATION;
1211 * samldb_sid_from_dn (async)
1214 static int samldb_sid_from_dn(struct samldb_ctx *ac);
1216 static int samldb_sid_from_dn_callback(struct ldb_request *req,
1217 struct ldb_reply *ares)
1219 struct ldb_context *ldb;
1220 struct samldb_ctx *ac;
1223 ac = talloc_get_type(req->context, struct samldb_ctx);
1224 ldb = ldb_module_get_ctx(ac->module);
1227 ret = LDB_ERR_OPERATIONS_ERROR;
1230 if (ares->error != LDB_SUCCESS) {
1231 return ldb_module_done(ac->req, ares->controls,
1232 ares->response, ares->error);
1235 switch (ares->type) {
1236 case LDB_REPLY_ENTRY:
1238 if (ac->res_sid != NULL) {
1240 ldb_set_errstring(ldb,
1241 "Invalid number of results while searching "
1242 "for domain objects!");
1243 ret = LDB_ERR_OPERATIONS_ERROR;
1246 ac->res_sid = samdb_result_dom_sid(ac, ares->message,
1253 case LDB_REPLY_REFERRAL:
1259 case LDB_REPLY_DONE:
1262 /* found or not found, go on */
1263 ret = samldb_next_step(ac);
1268 if (ret != LDB_SUCCESS) {
1269 return ldb_module_done(ac->req, NULL, NULL, ret);
1275 /* Finds the SID "res_sid" of an object with a given DN "dn" */
1276 static int samldb_sid_from_dn(struct samldb_ctx *ac)
1278 struct ldb_context *ldb;
1279 static const char * const attrs[] = { "objectSid" };
1280 struct ldb_request *req;
1283 ldb = ldb_module_get_ctx(ac->module);
1286 return LDB_ERR_OPERATIONS_ERROR;
1288 ret = ldb_build_search_req(&req, ldb, ac,
1293 ac, samldb_sid_from_dn_callback,
1295 if (ret != LDB_SUCCESS)
1298 return ldb_next_request(ac->module, req);
1302 * samldb_user_dn_to_prim_group_rid (async)
1305 static int samldb_user_dn_to_prim_group_rid(struct samldb_ctx *ac);
1307 static int samldb_user_dn_to_prim_group_rid_callback(struct ldb_request *req,
1308 struct ldb_reply *ares)
1310 struct ldb_context *ldb;
1311 struct samldb_ctx *ac;
1314 ac = talloc_get_type(req->context, struct samldb_ctx);
1315 ldb = ldb_module_get_ctx(ac->module);
1318 ret = LDB_ERR_OPERATIONS_ERROR;
1321 if (ares->error != LDB_SUCCESS) {
1322 return ldb_module_done(ac->req, ares->controls,
1323 ares->response, ares->error);
1326 switch (ares->type) {
1327 case LDB_REPLY_ENTRY:
1329 if (ac->prim_group_rid != 0) {
1331 ldb_set_errstring(ldb,
1332 "Invalid number of results while searching "
1333 "for domain objects!");
1334 ret = LDB_ERR_OPERATIONS_ERROR;
1337 ac->prim_group_rid = samdb_result_uint(ares->message,
1338 "primaryGroupID", ~0);
1344 case LDB_REPLY_REFERRAL:
1350 case LDB_REPLY_DONE:
1352 if (ac->prim_group_rid == 0) {
1353 ldb_asprintf_errstring(ldb,
1354 "Unable to get the primary group RID!\n");
1355 ret = LDB_ERR_OPERATIONS_ERROR;
1360 ret = samldb_next_step(ac);
1365 if (ret != LDB_SUCCESS) {
1366 return ldb_module_done(ac->req, NULL, NULL, ret);
1372 /* Locates the "primaryGroupID" attribute from a certain user specified as
1373 * "user_dn". Saves the result in "prim_group_rid". */
1374 static int samldb_user_dn_to_prim_group_rid(struct samldb_ctx *ac)
1376 struct ldb_context *ldb;
1377 static const char * const attrs[] = { "primaryGroupID", NULL };
1378 struct ldb_request *req;
1381 ldb = ldb_module_get_ctx(ac->module);
1383 if (ac->user_dn == NULL)
1384 return LDB_ERR_OPERATIONS_ERROR;
1386 ret = ldb_build_search_req(&req, ldb, ac,
1391 ac, samldb_user_dn_to_prim_group_rid_callback,
1393 if (ret != LDB_SUCCESS)
1396 return ldb_next_request(ac->module, req);
1400 * samldb_prim_group_rid_to_users_cnt (async)
1403 static int samldb_prim_group_rid_to_users_cnt(struct samldb_ctx *ac);
1405 static int samldb_prim_group_rid_to_users_cnt_callback(struct ldb_request *req,
1406 struct ldb_reply *ares)
1408 struct ldb_context *ldb;
1409 struct samldb_ctx *ac;
1412 ac = talloc_get_type(req->context, struct samldb_ctx);
1413 ldb = ldb_module_get_ctx(ac->module);
1416 ret = LDB_ERR_OPERATIONS_ERROR;
1419 if (ares->error != LDB_SUCCESS) {
1420 return ldb_module_done(ac->req, ares->controls,
1421 ares->response, ares->error);
1424 switch (ares->type) {
1425 case LDB_REPLY_ENTRY:
1433 case LDB_REPLY_REFERRAL:
1439 case LDB_REPLY_DONE:
1442 /* found or not found, go on */
1443 ret = samldb_next_step(ac);
1448 if (ret != LDB_SUCCESS) {
1449 return ldb_module_done(ac->req, NULL, NULL, ret);
1455 /* Finds the amount of users which have the primary group "prim_group_rid" and
1456 * save the result in "users_cnt" */
1457 static int samldb_prim_group_rid_to_users_cnt(struct samldb_ctx *ac)
1459 struct ldb_context *ldb;
1460 static const char * const attrs[] = { NULL };
1461 struct ldb_request *req;
1465 ldb = ldb_module_get_ctx(ac->module);
1467 if ((ac->prim_group_rid == 0) || (ac->users_cnt != 0))
1468 return LDB_ERR_OPERATIONS_ERROR;
1470 filter = talloc_asprintf(ac, "(&(primaryGroupID=%u)(objectclass=user))",
1471 ac->prim_group_rid);
1473 return LDB_ERR_OPERATIONS_ERROR;
1475 ret = ldb_build_search_req(&req, ldb, ac,
1476 ldb_get_default_basedn(ldb),
1481 samldb_prim_group_rid_to_users_cnt_callback,
1483 if (ret != LDB_SUCCESS)
1486 return ldb_next_request(ac->module, req);
1490 * samldb_group_add_member (async)
1491 * samldb_group_del_member (async)
1494 static int samldb_group_add_del_member_callback(struct ldb_request *req,
1495 struct ldb_reply *ares)
1497 struct ldb_context *ldb;
1498 struct samldb_ctx *ac;
1501 ac = talloc_get_type(req->context, struct samldb_ctx);
1502 ldb = ldb_module_get_ctx(ac->module);
1505 ret = LDB_ERR_OPERATIONS_ERROR;
1508 if (ares->error != LDB_SUCCESS) {
1509 if (ares->error == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1510 /* On error "NO_SUCH_ATTRIBUTE" (delete of an invalid
1511 * "member" attribute) return "UNWILLING_TO_PERFORM" */
1512 ares->error = LDB_ERR_UNWILLING_TO_PERFORM;
1514 return ldb_module_done(ac->req, ares->controls,
1515 ares->response, ares->error);
1517 if (ares->type != LDB_REPLY_DONE) {
1518 ldb_set_errstring(ldb,
1519 "Invalid reply type!\n");
1520 ret = LDB_ERR_OPERATIONS_ERROR;
1524 ret = samldb_next_step(ac);
1527 if (ret != LDB_SUCCESS) {
1528 return ldb_module_done(ac->req, NULL, NULL, ret);
1534 /* Adds a member with DN "member_dn" to a group with DN "group_dn" */
1535 static int samldb_group_add_member(struct samldb_ctx *ac)
1537 struct ldb_context *ldb;
1538 struct ldb_request *req;
1539 struct ldb_message *msg;
1542 ldb = ldb_module_get_ctx(ac->module);
1544 if ((ac->group_dn == NULL) || (ac->member_dn == NULL))
1545 return LDB_ERR_OPERATIONS_ERROR;
1547 msg = ldb_msg_new(ac);
1548 msg->dn = ac->group_dn;
1549 samdb_msg_add_addval(ldb, ac, msg, "member",
1550 ldb_dn_get_linearized(ac->member_dn));
1552 ret = ldb_build_mod_req(&req, ldb, ac,
1554 ac, samldb_group_add_del_member_callback,
1556 if (ret != LDB_SUCCESS)
1559 return ldb_next_request(ac->module, req);
1562 /* Removes a member with DN "member_dn" from a group with DN "group_dn" */
1563 static int samldb_group_del_member(struct samldb_ctx *ac)
1565 struct ldb_context *ldb;
1566 struct ldb_request *req;
1567 struct ldb_message *msg;
1570 ldb = ldb_module_get_ctx(ac->module);
1572 if ((ac->group_dn == NULL) || (ac->member_dn == NULL))
1573 return LDB_ERR_OPERATIONS_ERROR;
1575 msg = ldb_msg_new(ac);
1576 msg->dn = ac->group_dn;
1577 samdb_msg_add_delval(ldb, ac, msg, "member",
1578 ldb_dn_get_linearized(ac->member_dn));
1580 ret = ldb_build_mod_req(&req, ldb, ac,
1582 ac, samldb_group_add_del_member_callback,
1584 if (ret != LDB_SUCCESS)
1587 return ldb_next_request(ac->module, req);
1591 static int samldb_prim_group_change_1(struct samldb_ctx *ac)
1593 struct ldb_context *ldb;
1596 ldb = ldb_module_get_ctx(ac->module);
1598 ac->user_dn = ac->msg->dn;
1600 rid = samdb_result_uint(ac->msg, "primaryGroupID", ~0);
1601 ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid);
1602 if (ac->sid == NULL)
1603 return LDB_ERR_OPERATIONS_ERROR;
1606 ac->prim_group_rid = 0;
1608 return samldb_next_step(ac);
1611 static int samldb_prim_group_change_2(struct samldb_ctx *ac)
1613 struct ldb_context *ldb;
1615 ldb = ldb_module_get_ctx(ac->module);
1617 if (ac->res_dn != NULL)
1618 ac->new_prim_group_dn = ac->res_dn;
1620 return LDB_ERR_UNWILLING_TO_PERFORM;
1622 ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb),
1623 ac->prim_group_rid);
1624 if (ac->sid == NULL)
1625 return LDB_ERR_OPERATIONS_ERROR;
1628 return samldb_next_step(ac);
1631 static int samldb_prim_group_change_4(struct samldb_ctx *ac);
1632 static int samldb_prim_group_change_5(struct samldb_ctx *ac);
1633 static int samldb_prim_group_change_6(struct samldb_ctx *ac);
1635 static int samldb_prim_group_change_3(struct samldb_ctx *ac)
1639 if (ac->res_dn != NULL)
1640 ac->old_prim_group_dn = ac->res_dn;
1642 return LDB_ERR_UNWILLING_TO_PERFORM;
1644 /* Only update when the primary group changed */
1645 if (ldb_dn_compare(ac->old_prim_group_dn, ac->new_prim_group_dn) != 0) {
1646 ac->member_dn = ac->user_dn;
1647 /* Remove the "member" attribute of the actual (new) primary
1650 ret = samldb_add_step(ac, samldb_prim_group_change_4);
1651 if (ret != LDB_SUCCESS) return ret;
1653 ret = samldb_add_step(ac, samldb_group_del_member);
1654 if (ret != LDB_SUCCESS) return ret;
1656 /* Add a "member" attribute for the previous primary group */
1658 ret = samldb_add_step(ac, samldb_prim_group_change_5);
1659 if (ret != LDB_SUCCESS) return ret;
1661 ret = samldb_add_step(ac, samldb_group_add_member);
1662 if (ret != LDB_SUCCESS) return ret;
1665 ret = samldb_add_step(ac, samldb_prim_group_change_6);
1666 if (ret != LDB_SUCCESS) return ret;
1668 return samldb_next_step(ac);
1671 static int samldb_prim_group_change_4(struct samldb_ctx *ac)
1673 ac->group_dn = ac->new_prim_group_dn;
1675 return samldb_next_step(ac);
1678 static int samldb_prim_group_change_5(struct samldb_ctx *ac)
1680 ac->group_dn = ac->old_prim_group_dn;
1682 return samldb_next_step(ac);
1685 static int samldb_prim_group_change_6(struct samldb_ctx *ac)
1687 return ldb_next_request(ac->module, ac->req);
1690 static int samldb_prim_group_change(struct samldb_ctx *ac)
1694 /* Finds out the DN of the new primary group */
1696 ret = samldb_add_step(ac, samldb_prim_group_change_1);
1697 if (ret != LDB_SUCCESS) return ret;
1699 ret = samldb_add_step(ac, samldb_dn_from_sid);
1700 if (ret != LDB_SUCCESS) return ret;
1702 ret = samldb_add_step(ac, samldb_user_dn_to_prim_group_rid);
1703 if (ret != LDB_SUCCESS) return ret;
1705 /* Finds out the DN of the old primary group */
1707 ret = samldb_add_step(ac, samldb_prim_group_change_2);
1708 if (ret != LDB_SUCCESS) return ret;
1710 ret = samldb_add_step(ac, samldb_dn_from_sid);
1711 if (ret != LDB_SUCCESS) return ret;
1713 ret = samldb_add_step(ac, samldb_prim_group_change_3);
1714 if (ret != LDB_SUCCESS) return ret;
1716 return samldb_first_step(ac);
1720 static int samldb_member_check_1(struct samldb_ctx *ac)
1722 struct ldb_context *ldb;
1723 struct ldb_message_element *el;
1725 ldb = ldb_module_get_ctx(ac->module);
1727 el = ldb_msg_find_element(ac->msg, "member");
1729 ac->user_dn = ldb_dn_from_ldb_val(ac, ldb, &el->values[ac->cnt]);
1730 if (!ldb_dn_validate(ac->user_dn))
1731 return LDB_ERR_OPERATIONS_ERROR;
1732 ac->prim_group_rid = 0;
1734 return samldb_next_step(ac);
1737 static int samldb_member_check_2(struct samldb_ctx *ac)
1739 struct ldb_context *ldb;
1741 ldb = ldb_module_get_ctx(ac->module);
1743 ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb),
1744 ac->prim_group_rid);
1745 if (ac->sid == NULL)
1746 return LDB_ERR_OPERATIONS_ERROR;
1749 return samldb_next_step(ac);
1752 static int samldb_member_check_3(struct samldb_ctx *ac)
1754 if (ldb_dn_compare(ac->res_dn, ac->msg->dn) == 0)
1755 return LDB_ERR_ENTRY_ALREADY_EXISTS;
1759 return samldb_next_step(ac);
1762 static int samldb_member_check_4(struct samldb_ctx *ac)
1764 return ldb_next_request(ac->module, ac->req);
1767 static int samldb_member_check(struct samldb_ctx *ac)
1769 struct ldb_message_element *el;
1772 el = ldb_msg_find_element(ac->msg, "member");
1774 for (i = 0; i < el->num_values; i++) {
1775 /* Denies to add "member"s to groups which are primary ones
1777 ret = samldb_add_step(ac, samldb_member_check_1);
1778 if (ret != LDB_SUCCESS) return ret;
1780 ret = samldb_add_step(ac, samldb_user_dn_to_prim_group_rid);
1781 if (ret != LDB_SUCCESS) return ret;
1783 ret = samldb_add_step(ac, samldb_member_check_2);
1784 if (ret != LDB_SUCCESS) return ret;
1786 ret = samldb_add_step(ac, samldb_dn_from_sid);
1787 if (ret != LDB_SUCCESS) return ret;
1789 ret = samldb_add_step(ac, samldb_member_check_3);
1790 if (ret != LDB_SUCCESS) return ret;
1793 ret = samldb_add_step(ac, samldb_member_check_4);
1794 if (ret != LDB_SUCCESS) return ret;
1796 return samldb_first_step(ac);
1800 static int samldb_prim_group_users_check_1(struct samldb_ctx *ac)
1802 ac->dn = ac->req->op.del.dn;
1805 return samldb_next_step(ac);
1808 static int samldb_prim_group_users_check_2(struct samldb_ctx *ac)
1813 if (ac->res_sid == NULL) {
1814 /* No SID - therefore ok here */
1815 return ldb_next_request(ac->module, ac->req);
1817 status = dom_sid_split_rid(ac, ac->res_sid, NULL, &rid);
1818 if (!NT_STATUS_IS_OK(status))
1819 return LDB_ERR_OPERATIONS_ERROR;
1822 /* Special object (security principal?) */
1823 return ldb_next_request(ac->module, ac->req);
1826 ac->prim_group_rid = rid;
1829 return samldb_next_step(ac);
1832 static int samldb_prim_group_users_check_3(struct samldb_ctx *ac)
1834 if (ac->users_cnt > 0)
1835 return LDB_ERR_ENTRY_ALREADY_EXISTS;
1837 return ldb_next_request(ac->module, ac->req);
1840 static int samldb_prim_group_users_check(struct samldb_ctx *ac)
1844 /* Finds out the SID/RID of the domain object */
1846 ret = samldb_add_step(ac, samldb_prim_group_users_check_1);
1847 if (ret != LDB_SUCCESS) return ret;
1849 ret = samldb_add_step(ac, samldb_sid_from_dn);
1850 if (ret != LDB_SUCCESS) return ret;
1852 /* Deny delete requests from groups which are primary ones */
1854 ret = samldb_add_step(ac, samldb_prim_group_users_check_2);
1855 if (ret != LDB_SUCCESS) return ret;
1857 ret = samldb_add_step(ac, samldb_prim_group_rid_to_users_cnt);
1858 if (ret != LDB_SUCCESS) return ret;
1860 ret = samldb_add_step(ac, samldb_prim_group_users_check_3);
1861 if (ret != LDB_SUCCESS) return ret;
1863 return samldb_first_step(ac);
1868 static int samldb_add(struct ldb_module *module, struct ldb_request *req)
1870 struct ldb_context *ldb;
1871 struct samldb_ctx *ac;
1874 ldb = ldb_module_get_ctx(module);
1875 ldb_debug(ldb, LDB_DEBUG_TRACE, "samldb_add\n");
1877 /* do not manipulate our control entries */
1878 if (ldb_dn_is_special(req->op.add.message->dn)) {
1879 return ldb_next_request(module, req);
1882 ac = samldb_ctx_init(module, req);
1884 return LDB_ERR_OPERATIONS_ERROR;
1887 /* build the new msg */
1888 ac->msg = ldb_msg_copy(ac, ac->req->op.add.message);
1891 ldb_debug(ldb, LDB_DEBUG_FATAL,
1892 "samldb_add: ldb_msg_copy failed!\n");
1893 return LDB_ERR_OPERATIONS_ERROR;
1896 if (samdb_find_attribute(ldb, ac->msg,
1897 "objectclass", "computer") != NULL) {
1899 /* make sure the computer object also has the 'user'
1900 * objectclass so it will be handled by the next call */
1901 ret = samdb_find_or_add_value(ldb, ac->msg,
1902 "objectclass", "user");
1903 if (ret != LDB_SUCCESS) {
1909 if (samdb_find_attribute(ldb, ac->msg,
1910 "objectclass", "user") != NULL) {
1912 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
1913 if (ret != LDB_SUCCESS) {
1918 return samldb_fill_object(ac, "user");
1921 if (samdb_find_attribute(ldb, ac->msg,
1922 "objectclass", "group") != NULL) {
1924 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
1925 if (ret != LDB_SUCCESS) {
1930 return samldb_fill_object(ac, "group");
1933 /* perhaps a foreignSecurityPrincipal? */
1934 if (samdb_find_attribute(ldb, ac->msg,
1936 "foreignSecurityPrincipal") != NULL) {
1938 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
1939 if (ret != LDB_SUCCESS) {
1944 return samldb_fill_foreignSecurityPrincipal_object(ac);
1949 /* nothing matched, go on */
1950 return ldb_next_request(module, req);
1954 static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
1956 struct ldb_context *ldb;
1957 struct ldb_message *msg;
1958 struct ldb_message_element *el, *el2;
1960 uint32_t account_type;
1962 if (ldb_dn_is_special(req->op.mod.message->dn)) {
1963 /* do not manipulate our control entries */
1964 return ldb_next_request(module, req);
1967 ldb = ldb_module_get_ctx(module);
1969 if (ldb_msg_find_element(req->op.mod.message, "sAMAccountType") != NULL) {
1970 ldb_asprintf_errstring(ldb,
1971 "sAMAccountType must not be specified!");
1972 return LDB_ERR_UNWILLING_TO_PERFORM;
1975 /* TODO: do not modify original request, create a new one */
1977 el = ldb_msg_find_element(req->op.mod.message, "groupType");
1978 if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
1979 uint32_t group_type;
1981 req->op.mod.message = msg = ldb_msg_copy_shallow(req,
1982 req->op.mod.message);
1984 group_type = strtoul((const char *)el->values[0].data, NULL, 0);
1985 account_type = ds_gtype2atype(group_type);
1986 ret = samdb_msg_add_uint(ldb, msg, msg,
1989 if (ret != LDB_SUCCESS) {
1992 el2 = ldb_msg_find_element(msg, "sAMAccountType");
1993 el2->flags = LDB_FLAG_MOD_REPLACE;
1996 el = ldb_msg_find_element(req->op.mod.message, "userAccountControl");
1997 if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
1998 uint32_t user_account_control;
2000 req->op.mod.message = msg = ldb_msg_copy_shallow(req,
2001 req->op.mod.message);
2003 user_account_control = strtoul((const char *)el->values[0].data,
2005 account_type = ds_uf2atype(user_account_control);
2006 ret = samdb_msg_add_uint(ldb, msg, msg,
2009 if (ret != LDB_SUCCESS) {
2012 el2 = ldb_msg_find_element(msg, "sAMAccountType");
2013 el2->flags = LDB_FLAG_MOD_REPLACE;
2015 if (user_account_control & UF_SERVER_TRUST_ACCOUNT) {
2016 ret = samdb_msg_add_string(ldb, msg, msg,
2017 "isCriticalSystemObject", "TRUE");
2018 if (ret != LDB_SUCCESS) {
2021 el2 = ldb_msg_find_element(msg, "isCriticalSystemObject");
2022 el2->flags = LDB_FLAG_MOD_REPLACE;
2026 el = ldb_msg_find_element(req->op.mod.message, "primaryGroupID");
2027 if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
2028 struct samldb_ctx *ac;
2030 ac = samldb_ctx_init(module, req);
2032 return LDB_ERR_OPERATIONS_ERROR;
2034 req->op.mod.message = ac->msg = ldb_msg_copy_shallow(req,
2035 req->op.mod.message);
2037 return samldb_prim_group_change(ac);
2040 el = ldb_msg_find_element(req->op.mod.message, "member");
2041 if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
2042 struct samldb_ctx *ac;
2044 ac = samldb_ctx_init(module, req);
2046 return LDB_ERR_OPERATIONS_ERROR;
2048 req->op.mod.message = ac->msg = ldb_msg_copy_shallow(req,
2049 req->op.mod.message);
2051 return samldb_member_check(ac);
2054 /* nothing matched, go on */
2055 return ldb_next_request(module, req);
2059 static int samldb_delete(struct ldb_module *module, struct ldb_request *req)
2061 struct samldb_ctx *ac;
2063 if (ldb_dn_is_special(req->op.del.dn)) {
2064 /* do not manipulate our control entries */
2065 return ldb_next_request(module, req);
2068 ac = samldb_ctx_init(module, req);
2070 return LDB_ERR_OPERATIONS_ERROR;
2072 return samldb_prim_group_users_check(ac);
2076 static int samldb_init(struct ldb_module *module)
2078 return ldb_next_init(module);
2081 _PUBLIC_ const struct ldb_module_ops ldb_samldb_module_ops = {
2083 .init_context = samldb_init,
2085 .modify = samldb_modify,
2086 .del = samldb_delete