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"
40 #include "param/param.h"
44 typedef int (*samldb_step_fn_t)(struct samldb_ctx *);
47 struct samldb_step *next;
52 struct ldb_module *module;
53 struct ldb_request *req;
55 /* used for add operations */
58 /* the resulting message */
59 struct ldb_message *msg;
61 /* used to find parent domain */
62 struct ldb_dn *check_dn;
63 struct ldb_dn *domain_dn;
64 struct dom_sid *domain_sid;
67 /* holds the entry SID */
70 /* holds a generic dn */
73 /* used in conjunction with "sid" in "samldb_dn_from_sid" */
74 struct ldb_dn *res_dn;
76 /* used in conjunction with "dn" in "samldb_sid_from_dn" */
77 struct dom_sid *res_sid;
79 /* used in "samldb_user_dn_to_prim_group_rid" */
80 uint32_t prim_group_rid;
82 /* used in conjunction with "prim_group_rid" in
83 * "samldb_prim_group_rid_to_users_cnt" */
84 unsigned int users_cnt;
86 /* used in "samldb_group_add_member" and "samldb_group_del_member" */
87 struct ldb_dn *group_dn;
88 struct ldb_dn *member_dn;
90 /* used in "samldb_primary_group_change" */
91 struct ldb_dn *user_dn;
92 struct ldb_dn *old_prim_group_dn, *new_prim_group_dn;
94 /* generic counter - used in "samldb_member_check" */
97 /* all the async steps necessary to complete the operation */
98 struct samldb_step *steps;
99 struct samldb_step *curstep;
102 static struct samldb_ctx *samldb_ctx_init(struct ldb_module *module,
103 struct ldb_request *req)
105 struct ldb_context *ldb;
106 struct samldb_ctx *ac;
108 ldb = ldb_module_get_ctx(module);
110 ac = talloc_zero(req, struct samldb_ctx);
122 static int samldb_add_step(struct samldb_ctx *ac, samldb_step_fn_t fn)
124 struct samldb_step *step, *stepper;
126 step = talloc_zero(ac, struct samldb_step);
128 return LDB_ERR_OPERATIONS_ERROR;
133 if (ac->steps == NULL) {
137 if (ac->curstep == NULL)
138 return LDB_ERR_OPERATIONS_ERROR;
139 for (stepper = ac->curstep; stepper->next != NULL;
140 stepper = stepper->next);
141 stepper->next = step;
147 static int samldb_first_step(struct samldb_ctx *ac)
149 if (ac->steps == NULL) {
150 return LDB_ERR_OPERATIONS_ERROR;
153 ac->curstep = ac->steps;
154 return ac->curstep->fn(ac);
157 static int samldb_next_step(struct samldb_ctx *ac)
159 if (ac->curstep->next) {
160 ac->curstep = ac->curstep->next;
161 return ac->curstep->fn(ac);
164 /* it is an error if the last step does not properly
165 * return to the upper module by itself */
166 return LDB_ERR_OPERATIONS_ERROR;
170 * samldb_get_parent_domain (async)
173 static int samldb_get_parent_domain(struct samldb_ctx *ac);
175 static int samldb_get_parent_domain_callback(struct ldb_request *req,
176 struct ldb_reply *ares)
178 struct ldb_context *ldb;
179 struct samldb_ctx *ac;
183 ac = talloc_get_type(req->context, struct samldb_ctx);
184 ldb = ldb_module_get_ctx(ac->module);
187 ret = LDB_ERR_OPERATIONS_ERROR;
190 if (ares->error != LDB_SUCCESS) {
191 return ldb_module_done(ac->req, ares->controls,
192 ares->response, ares->error);
195 switch (ares->type) {
196 case LDB_REPLY_ENTRY:
198 if ((ac->domain_dn != NULL) || (ac->domain_sid != NULL)) {
200 ldb_set_errstring(ldb,
201 "Invalid number of results while searching "
202 "for domain object!");
203 ret = LDB_ERR_OPERATIONS_ERROR;
207 nextRid = ldb_msg_find_attr_as_string(ares->message,
209 if (nextRid == NULL) {
210 ldb_asprintf_errstring(ldb,
211 "While looking for domain above %s attribute nextRid not found in %s!\n",
212 ldb_dn_get_linearized(
213 ac->req->op.add.message->dn),
214 ldb_dn_get_linearized(ares->message->dn));
215 ret = LDB_ERR_OPERATIONS_ERROR;
219 ac->next_rid = strtol(nextRid, NULL, 0);
221 ac->domain_sid = samdb_result_dom_sid(ac, ares->message,
223 if (ac->domain_sid == NULL) {
224 ldb_set_errstring(ldb,
225 "Unable to get the parent domain SID!\n");
226 ret = LDB_ERR_CONSTRAINT_VIOLATION;
229 ac->domain_dn = ldb_dn_copy(ac, ares->message->dn);
235 case LDB_REPLY_REFERRAL:
243 if ((ac->domain_dn == NULL) || (ac->domain_sid == NULL)) {
244 /* not found -> retry */
245 ret = samldb_get_parent_domain(ac);
248 ret = samldb_next_step(ac);
254 if (ret != LDB_SUCCESS) {
255 return ldb_module_done(ac->req, NULL, NULL, ret);
261 /* Find a domain object in the parents of a particular DN. */
262 static int samldb_get_parent_domain(struct samldb_ctx *ac)
264 struct ldb_context *ldb;
265 static const char * const attrs[] = { "objectSid", "nextRid", NULL };
266 struct ldb_request *req;
270 ldb = ldb_module_get_ctx(ac->module);
272 if (ac->check_dn == NULL) {
273 return LDB_ERR_OPERATIONS_ERROR;
276 dn = ldb_dn_get_parent(ac, ac->check_dn);
278 ldb_set_errstring(ldb,
279 "Unable to find parent domain object!");
280 return LDB_ERR_CONSTRAINT_VIOLATION;
285 ret = ldb_build_search_req(&req, ldb, ac,
287 "(|(objectClass=domain)"
288 "(objectClass=builtinDomain))",
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,
564 "(|(objectClass=domain)"
565 "(objectClass=builtinDomain)))",
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;
927 struct loadparm_context *lp_ctx;
928 enum sid_generator sid_generator;
931 ldb = ldb_module_get_ctx(ac->module);
933 /* search for a parent domain objet */
934 ac->check_dn = ac->req->op.add.message->dn;
935 ret = samldb_add_step(ac, samldb_get_parent_domain);
936 if (ret != LDB_SUCCESS) return ret;
938 /* Add informations for the different account types */
940 if (strcmp(ac->type, "user") == 0) {
941 ret = samdb_find_or_add_attribute(ldb, ac->msg,
942 "userAccountControl", "546");
943 if (ret != LDB_SUCCESS) return ret;
944 ret = samdb_find_or_add_attribute(ldb, ac->msg,
946 if (ret != LDB_SUCCESS) return ret;
947 ret = samdb_find_or_add_attribute(ldb, ac->msg,
949 if (ret != LDB_SUCCESS) return ret;
950 ret = samdb_find_or_add_attribute(ldb, ac->msg,
952 if (ret != LDB_SUCCESS) return ret;
953 ret = samdb_find_or_add_attribute(ldb, ac->msg,
954 "badPasswordTime", "0");
955 if (ret != LDB_SUCCESS) return ret;
956 ret = samdb_find_or_add_attribute(ldb, ac->msg,
958 if (ret != LDB_SUCCESS) return ret;
959 ret = samdb_find_or_add_attribute(ldb, ac->msg,
961 if (ret != LDB_SUCCESS) return ret;
962 ret = samdb_find_or_add_attribute(ldb, ac->msg,
964 if (ret != LDB_SUCCESS) return ret;
965 ret = samdb_find_or_add_attribute(ldb, ac->msg,
966 "primaryGroupID", "513");
967 if (ret != LDB_SUCCESS) return ret;
968 ret = samdb_find_or_add_attribute(ldb, ac->msg,
969 "accountExpires", "9223372036854775807");
970 if (ret != LDB_SUCCESS) return ret;
971 ret = samdb_find_or_add_attribute(ldb, ac->msg,
973 if (ret != LDB_SUCCESS) return ret;
974 } else if (strcmp(ac->type, "group") == 0) {
975 ret = samdb_find_or_add_attribute(ldb, ac->msg,
976 "groupType", "-2147483646");
977 if (ret != LDB_SUCCESS) return ret;
979 /* we should only have "user" and "group" */
980 ldb_asprintf_errstring(ldb,
981 "Invalid entry type!\n");
982 return LDB_ERR_OPERATIONS_ERROR;
985 /* check if we have a valid samAccountName */
986 ret = samldb_add_step(ac, samldb_check_samAccountName);
987 if (ret != LDB_SUCCESS) return ret;
989 /* check account_type/group_type */
990 ret = samldb_add_step(ac, samldb_check_samAccountType);
991 if (ret != LDB_SUCCESS) return ret;
993 /* check if we have a valid primary group ID */
994 if (strcmp(ac->type, "user") == 0) {
995 ret = samldb_add_step(ac, samldb_check_primaryGroupID_1);
996 if (ret != LDB_SUCCESS) return ret;
997 ret = samldb_add_step(ac, samldb_dn_from_sid);
998 if (ret != LDB_SUCCESS) return ret;
999 ret = samldb_add_step(ac, samldb_check_primaryGroupID_2);
1000 if (ret != LDB_SUCCESS) return ret;
1003 lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
1004 struct loadparm_context);
1006 sid_generator = lp_sid_generator(lp_ctx);
1007 if (sid_generator == SID_GENERATOR_INTERNAL) {
1008 /* check if we have a valid SID */
1009 ac->sid = samdb_result_dom_sid(ac, ac->msg, "objectSid");
1011 ret = samldb_add_step(ac, samldb_new_sid);
1012 if (ret != LDB_SUCCESS) return ret;
1014 ret = samldb_add_step(ac, samldb_get_sid_domain);
1015 if (ret != LDB_SUCCESS) return ret;
1018 ret = samldb_add_step(ac, samldb_notice_sid);
1019 if (ret != LDB_SUCCESS) return ret;
1022 /* finally proceed with adding the entry */
1023 ret = samldb_add_step(ac, samldb_add_entry);
1024 if (ret != LDB_SUCCESS) return ret;
1026 return samldb_first_step(ac);
1030 * samldb_foreign_notice_sid (async)
1033 static int samldb_foreign_notice_sid_callback(struct ldb_request *req,
1034 struct ldb_reply *ares)
1036 struct ldb_context *ldb;
1037 struct samldb_ctx *ac;
1038 const char *nextRid;
1042 ac = talloc_get_type(req->context, struct samldb_ctx);
1043 ldb = ldb_module_get_ctx(ac->module);
1046 ret = LDB_ERR_OPERATIONS_ERROR;
1049 if (ares->error != LDB_SUCCESS) {
1050 return ldb_module_done(ac->req, ares->controls,
1051 ares->response, ares->error);
1054 switch (ares->type) {
1055 case LDB_REPLY_ENTRY:
1057 if (ac->next_rid != 0) {
1059 ldb_set_errstring(ldb,
1060 "Invalid number of results while searching "
1061 "for domain object!");
1062 ret = LDB_ERR_OPERATIONS_ERROR;
1066 nextRid = ldb_msg_find_attr_as_string(ares->message,
1068 if (nextRid == NULL) {
1069 ldb_asprintf_errstring(ldb,
1070 "while looking for forign sid %s attribute nextRid not found in %s\n",
1071 dom_sid_string(ares, ac->sid),
1072 ldb_dn_get_linearized(ares->message->dn));
1073 ret = LDB_ERR_OPERATIONS_ERROR;
1077 ac->next_rid = strtol(nextRid, NULL, 0);
1079 ac->domain_dn = ldb_dn_copy(ac, ares->message->dn);
1081 name = samdb_result_string(ares->message, "name", NULL);
1082 ldb_debug(ldb, LDB_DEBUG_TRACE,
1083 "NOTE (strange but valid): Adding foreign SID "
1084 "record with SID %s, but this domain (%s) is "
1085 "not foreign in the database",
1086 dom_sid_string(ares, ac->sid), name);
1092 case LDB_REPLY_REFERRAL:
1098 case LDB_REPLY_DONE:
1101 /* if this is a fake foreign SID, notice the SID */
1102 if (ac->domain_dn) {
1103 ret = samldb_notice_sid(ac);
1108 ret = samldb_next_step(ac);
1113 if (ret != LDB_SUCCESS) {
1114 return ldb_module_done(ac->req, NULL, NULL, ret);
1120 /* Find a domain object in the parents of a particular DN. */
1121 static int samldb_foreign_notice_sid(struct samldb_ctx *ac)
1123 struct ldb_context *ldb;
1124 static const char * const attrs[3] = { "nextRid", "name", NULL };
1125 struct ldb_request *req;
1130 ldb = ldb_module_get_ctx(ac->module);
1132 if (ac->sid == NULL) {
1133 return LDB_ERR_OPERATIONS_ERROR;
1136 status = dom_sid_split_rid(ac, ac->sid, &ac->domain_sid, NULL);
1137 if (!NT_STATUS_IS_OK(status)) {
1138 return LDB_ERR_OPERATIONS_ERROR;
1141 filter = talloc_asprintf(ac, "(&(objectSid=%s)(objectclass=domain))",
1142 ldap_encode_ndr_dom_sid(ac, ac->domain_sid));
1143 if (filter == NULL) {
1144 return LDB_ERR_OPERATIONS_ERROR;
1147 ret = ldb_build_search_req(&req, ldb, ac,
1148 ldb_get_default_basedn(ldb),
1152 ac, samldb_foreign_notice_sid_callback,
1155 if (ret != LDB_SUCCESS) {
1159 return ldb_next_request(ac->module, req);
1163 static int samldb_fill_foreignSecurityPrincipal_object(struct samldb_ctx *ac)
1165 struct ldb_context *ldb;
1168 ldb = ldb_module_get_ctx(ac->module);
1172 ac->sid = samdb_result_dom_sid(ac->msg, ac->msg, "objectSid");
1173 if (ac->sid == NULL) {
1174 ac->sid = dom_sid_parse_talloc(ac->msg,
1175 (const char *)ldb_dn_get_rdn_val(ac->msg->dn)->data);
1177 ldb_set_errstring(ldb,
1178 "No valid SID found in "
1179 "ForeignSecurityPrincipal CN!");
1181 return LDB_ERR_CONSTRAINT_VIOLATION;
1183 if ( ! samldb_msg_add_sid(ac->msg, "objectSid", ac->sid)) {
1185 return LDB_ERR_OPERATIONS_ERROR;
1189 /* check if we need to notice this SID */
1190 ret = samldb_add_step(ac, samldb_foreign_notice_sid);
1191 if (ret != LDB_SUCCESS) return ret;
1193 /* finally proceed with adding the entry */
1194 ret = samldb_add_step(ac, samldb_add_entry);
1195 if (ret != LDB_SUCCESS) return ret;
1197 return samldb_first_step(ac);
1200 static int samldb_check_rdn(struct ldb_module *module, struct ldb_dn *dn)
1202 struct ldb_context *ldb;
1203 const char *rdn_name;
1205 ldb = ldb_module_get_ctx(module);
1206 rdn_name = ldb_dn_get_rdn_name(dn);
1208 if (strcasecmp(rdn_name, "cn") != 0) {
1209 ldb_asprintf_errstring(ldb,
1210 "Bad RDN (%s=) for samldb object, "
1211 "should be CN=!\n", rdn_name);
1212 return LDB_ERR_CONSTRAINT_VIOLATION;
1219 * samldb_sid_from_dn (async)
1222 static int samldb_sid_from_dn(struct samldb_ctx *ac);
1224 static int samldb_sid_from_dn_callback(struct ldb_request *req,
1225 struct ldb_reply *ares)
1227 struct ldb_context *ldb;
1228 struct samldb_ctx *ac;
1231 ac = talloc_get_type(req->context, struct samldb_ctx);
1232 ldb = ldb_module_get_ctx(ac->module);
1235 ret = LDB_ERR_OPERATIONS_ERROR;
1238 if (ares->error != LDB_SUCCESS) {
1239 return ldb_module_done(ac->req, ares->controls,
1240 ares->response, ares->error);
1243 switch (ares->type) {
1244 case LDB_REPLY_ENTRY:
1246 if (ac->res_sid != NULL) {
1248 ldb_set_errstring(ldb,
1249 "Invalid number of results while searching "
1250 "for domain objects!");
1251 ret = LDB_ERR_OPERATIONS_ERROR;
1254 ac->res_sid = samdb_result_dom_sid(ac, ares->message,
1261 case LDB_REPLY_REFERRAL:
1267 case LDB_REPLY_DONE:
1270 /* found or not found, go on */
1271 ret = samldb_next_step(ac);
1276 if (ret != LDB_SUCCESS) {
1277 return ldb_module_done(ac->req, NULL, NULL, ret);
1283 /* Finds the SID "res_sid" of an object with a given DN "dn" */
1284 static int samldb_sid_from_dn(struct samldb_ctx *ac)
1286 struct ldb_context *ldb;
1287 static const char * const attrs[] = { "objectSid" };
1288 struct ldb_request *req;
1291 ldb = ldb_module_get_ctx(ac->module);
1294 return LDB_ERR_OPERATIONS_ERROR;
1296 ret = ldb_build_search_req(&req, ldb, ac,
1301 ac, samldb_sid_from_dn_callback,
1303 if (ret != LDB_SUCCESS)
1306 return ldb_next_request(ac->module, req);
1310 * samldb_user_dn_to_prim_group_rid (async)
1313 static int samldb_user_dn_to_prim_group_rid(struct samldb_ctx *ac);
1315 static int samldb_user_dn_to_prim_group_rid_callback(struct ldb_request *req,
1316 struct ldb_reply *ares)
1318 struct ldb_context *ldb;
1319 struct samldb_ctx *ac;
1322 ac = talloc_get_type(req->context, struct samldb_ctx);
1323 ldb = ldb_module_get_ctx(ac->module);
1326 ret = LDB_ERR_OPERATIONS_ERROR;
1329 if (ares->error != LDB_SUCCESS) {
1330 return ldb_module_done(ac->req, ares->controls,
1331 ares->response, ares->error);
1334 switch (ares->type) {
1335 case LDB_REPLY_ENTRY:
1337 if (ac->prim_group_rid != 0) {
1339 ldb_set_errstring(ldb,
1340 "Invalid number of results while searching "
1341 "for domain objects!");
1342 ret = LDB_ERR_OPERATIONS_ERROR;
1345 ac->prim_group_rid = samdb_result_uint(ares->message,
1346 "primaryGroupID", ~0);
1352 case LDB_REPLY_REFERRAL:
1358 case LDB_REPLY_DONE:
1360 if (ac->prim_group_rid == 0) {
1361 ldb_asprintf_errstring(ldb,
1362 "Unable to get the primary group RID!\n");
1363 ret = LDB_ERR_OPERATIONS_ERROR;
1368 ret = samldb_next_step(ac);
1373 if (ret != LDB_SUCCESS) {
1374 return ldb_module_done(ac->req, NULL, NULL, ret);
1380 /* Locates the "primaryGroupID" attribute from a certain user specified as
1381 * "user_dn". Saves the result in "prim_group_rid". */
1382 static int samldb_user_dn_to_prim_group_rid(struct samldb_ctx *ac)
1384 struct ldb_context *ldb;
1385 static const char * const attrs[] = { "primaryGroupID", NULL };
1386 struct ldb_request *req;
1389 ldb = ldb_module_get_ctx(ac->module);
1391 if (ac->user_dn == NULL)
1392 return LDB_ERR_OPERATIONS_ERROR;
1394 ret = ldb_build_search_req(&req, ldb, ac,
1399 ac, samldb_user_dn_to_prim_group_rid_callback,
1401 if (ret != LDB_SUCCESS)
1404 return ldb_next_request(ac->module, req);
1408 * samldb_prim_group_rid_to_users_cnt (async)
1411 static int samldb_prim_group_rid_to_users_cnt(struct samldb_ctx *ac);
1413 static int samldb_prim_group_rid_to_users_cnt_callback(struct ldb_request *req,
1414 struct ldb_reply *ares)
1416 struct ldb_context *ldb;
1417 struct samldb_ctx *ac;
1420 ac = talloc_get_type(req->context, struct samldb_ctx);
1421 ldb = ldb_module_get_ctx(ac->module);
1424 ret = LDB_ERR_OPERATIONS_ERROR;
1427 if (ares->error != LDB_SUCCESS) {
1428 return ldb_module_done(ac->req, ares->controls,
1429 ares->response, ares->error);
1432 switch (ares->type) {
1433 case LDB_REPLY_ENTRY:
1441 case LDB_REPLY_REFERRAL:
1447 case LDB_REPLY_DONE:
1450 /* found or not found, go on */
1451 ret = samldb_next_step(ac);
1456 if (ret != LDB_SUCCESS) {
1457 return ldb_module_done(ac->req, NULL, NULL, ret);
1463 /* Finds the amount of users which have the primary group "prim_group_rid" and
1464 * save the result in "users_cnt" */
1465 static int samldb_prim_group_rid_to_users_cnt(struct samldb_ctx *ac)
1467 struct ldb_context *ldb;
1468 static const char * const attrs[] = { NULL };
1469 struct ldb_request *req;
1473 ldb = ldb_module_get_ctx(ac->module);
1475 if ((ac->prim_group_rid == 0) || (ac->users_cnt != 0))
1476 return LDB_ERR_OPERATIONS_ERROR;
1478 filter = talloc_asprintf(ac, "(&(primaryGroupID=%u)(objectclass=user))",
1479 ac->prim_group_rid);
1481 return LDB_ERR_OPERATIONS_ERROR;
1483 ret = ldb_build_search_req(&req, ldb, ac,
1484 ldb_get_default_basedn(ldb),
1489 samldb_prim_group_rid_to_users_cnt_callback,
1491 if (ret != LDB_SUCCESS)
1494 return ldb_next_request(ac->module, req);
1498 * samldb_group_add_member (async)
1499 * samldb_group_del_member (async)
1502 static int samldb_group_add_del_member_callback(struct ldb_request *req,
1503 struct ldb_reply *ares)
1505 struct ldb_context *ldb;
1506 struct samldb_ctx *ac;
1509 ac = talloc_get_type(req->context, struct samldb_ctx);
1510 ldb = ldb_module_get_ctx(ac->module);
1513 ret = LDB_ERR_OPERATIONS_ERROR;
1516 if (ares->error != LDB_SUCCESS) {
1517 if (ares->error == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1518 /* On error "NO_SUCH_ATTRIBUTE" (delete of an invalid
1519 * "member" attribute) return "UNWILLING_TO_PERFORM" */
1520 ares->error = LDB_ERR_UNWILLING_TO_PERFORM;
1522 return ldb_module_done(ac->req, ares->controls,
1523 ares->response, ares->error);
1525 if (ares->type != LDB_REPLY_DONE) {
1526 ldb_set_errstring(ldb,
1527 "Invalid reply type!\n");
1528 ret = LDB_ERR_OPERATIONS_ERROR;
1532 ret = samldb_next_step(ac);
1535 if (ret != LDB_SUCCESS) {
1536 return ldb_module_done(ac->req, NULL, NULL, ret);
1542 /* Adds a member with DN "member_dn" to a group with DN "group_dn" */
1543 static int samldb_group_add_member(struct samldb_ctx *ac)
1545 struct ldb_context *ldb;
1546 struct ldb_request *req;
1547 struct ldb_message *msg;
1550 ldb = ldb_module_get_ctx(ac->module);
1552 if ((ac->group_dn == NULL) || (ac->member_dn == NULL))
1553 return LDB_ERR_OPERATIONS_ERROR;
1555 msg = ldb_msg_new(ac);
1556 msg->dn = ac->group_dn;
1557 samdb_msg_add_addval(ldb, ac, msg, "member",
1558 ldb_dn_get_linearized(ac->member_dn));
1560 ret = ldb_build_mod_req(&req, ldb, ac,
1562 ac, samldb_group_add_del_member_callback,
1564 if (ret != LDB_SUCCESS)
1567 return ldb_next_request(ac->module, req);
1570 /* Removes a member with DN "member_dn" from a group with DN "group_dn" */
1571 static int samldb_group_del_member(struct samldb_ctx *ac)
1573 struct ldb_context *ldb;
1574 struct ldb_request *req;
1575 struct ldb_message *msg;
1578 ldb = ldb_module_get_ctx(ac->module);
1580 if ((ac->group_dn == NULL) || (ac->member_dn == NULL))
1581 return LDB_ERR_OPERATIONS_ERROR;
1583 msg = ldb_msg_new(ac);
1584 msg->dn = ac->group_dn;
1585 samdb_msg_add_delval(ldb, ac, msg, "member",
1586 ldb_dn_get_linearized(ac->member_dn));
1588 ret = ldb_build_mod_req(&req, ldb, ac,
1590 ac, samldb_group_add_del_member_callback,
1592 if (ret != LDB_SUCCESS)
1595 return ldb_next_request(ac->module, req);
1599 static int samldb_prim_group_change_1(struct samldb_ctx *ac)
1601 struct ldb_context *ldb;
1604 ldb = ldb_module_get_ctx(ac->module);
1606 ac->user_dn = ac->msg->dn;
1608 rid = samdb_result_uint(ac->msg, "primaryGroupID", ~0);
1609 ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid);
1610 if (ac->sid == NULL)
1611 return LDB_ERR_OPERATIONS_ERROR;
1614 ac->prim_group_rid = 0;
1616 return samldb_next_step(ac);
1619 static int samldb_prim_group_change_2(struct samldb_ctx *ac)
1621 struct ldb_context *ldb;
1623 ldb = ldb_module_get_ctx(ac->module);
1625 if (ac->res_dn != NULL)
1626 ac->new_prim_group_dn = ac->res_dn;
1628 return LDB_ERR_UNWILLING_TO_PERFORM;
1630 ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb),
1631 ac->prim_group_rid);
1632 if (ac->sid == NULL)
1633 return LDB_ERR_OPERATIONS_ERROR;
1636 return samldb_next_step(ac);
1639 static int samldb_prim_group_change_4(struct samldb_ctx *ac);
1640 static int samldb_prim_group_change_5(struct samldb_ctx *ac);
1641 static int samldb_prim_group_change_6(struct samldb_ctx *ac);
1643 static int samldb_prim_group_change_3(struct samldb_ctx *ac)
1647 if (ac->res_dn != NULL)
1648 ac->old_prim_group_dn = ac->res_dn;
1650 return LDB_ERR_UNWILLING_TO_PERFORM;
1652 /* Only update when the primary group changed */
1653 if (ldb_dn_compare(ac->old_prim_group_dn, ac->new_prim_group_dn) != 0) {
1654 ac->member_dn = ac->user_dn;
1655 /* Remove the "member" attribute of the actual (new) primary
1658 ret = samldb_add_step(ac, samldb_prim_group_change_4);
1659 if (ret != LDB_SUCCESS) return ret;
1661 ret = samldb_add_step(ac, samldb_group_del_member);
1662 if (ret != LDB_SUCCESS) return ret;
1664 /* Add a "member" attribute for the previous primary group */
1666 ret = samldb_add_step(ac, samldb_prim_group_change_5);
1667 if (ret != LDB_SUCCESS) return ret;
1669 ret = samldb_add_step(ac, samldb_group_add_member);
1670 if (ret != LDB_SUCCESS) return ret;
1673 ret = samldb_add_step(ac, samldb_prim_group_change_6);
1674 if (ret != LDB_SUCCESS) return ret;
1676 return samldb_next_step(ac);
1679 static int samldb_prim_group_change_4(struct samldb_ctx *ac)
1681 ac->group_dn = ac->new_prim_group_dn;
1683 return samldb_next_step(ac);
1686 static int samldb_prim_group_change_5(struct samldb_ctx *ac)
1688 ac->group_dn = ac->old_prim_group_dn;
1690 return samldb_next_step(ac);
1693 static int samldb_prim_group_change_6(struct samldb_ctx *ac)
1695 return ldb_next_request(ac->module, ac->req);
1698 static int samldb_prim_group_change(struct samldb_ctx *ac)
1702 /* Finds out the DN of the new primary group */
1704 ret = samldb_add_step(ac, samldb_prim_group_change_1);
1705 if (ret != LDB_SUCCESS) return ret;
1707 ret = samldb_add_step(ac, samldb_dn_from_sid);
1708 if (ret != LDB_SUCCESS) return ret;
1710 ret = samldb_add_step(ac, samldb_user_dn_to_prim_group_rid);
1711 if (ret != LDB_SUCCESS) return ret;
1713 /* Finds out the DN of the old primary group */
1715 ret = samldb_add_step(ac, samldb_prim_group_change_2);
1716 if (ret != LDB_SUCCESS) return ret;
1718 ret = samldb_add_step(ac, samldb_dn_from_sid);
1719 if (ret != LDB_SUCCESS) return ret;
1721 ret = samldb_add_step(ac, samldb_prim_group_change_3);
1722 if (ret != LDB_SUCCESS) return ret;
1724 return samldb_first_step(ac);
1728 static int samldb_member_check_1(struct samldb_ctx *ac)
1730 struct ldb_context *ldb;
1731 struct ldb_message_element *el;
1733 ldb = ldb_module_get_ctx(ac->module);
1735 el = ldb_msg_find_element(ac->msg, "member");
1737 ac->user_dn = ldb_dn_from_ldb_val(ac, ldb, &el->values[ac->cnt]);
1738 if (!ldb_dn_validate(ac->user_dn))
1739 return LDB_ERR_OPERATIONS_ERROR;
1740 ac->prim_group_rid = 0;
1742 return samldb_next_step(ac);
1745 static int samldb_member_check_2(struct samldb_ctx *ac)
1747 struct ldb_context *ldb;
1749 ldb = ldb_module_get_ctx(ac->module);
1751 ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb),
1752 ac->prim_group_rid);
1753 if (ac->sid == NULL)
1754 return LDB_ERR_OPERATIONS_ERROR;
1757 return samldb_next_step(ac);
1760 static int samldb_member_check_3(struct samldb_ctx *ac)
1762 if (ldb_dn_compare(ac->res_dn, ac->msg->dn) == 0)
1763 return LDB_ERR_ENTRY_ALREADY_EXISTS;
1767 return samldb_next_step(ac);
1770 static int samldb_member_check_4(struct samldb_ctx *ac)
1772 return ldb_next_request(ac->module, ac->req);
1775 static int samldb_member_check(struct samldb_ctx *ac)
1777 struct ldb_message_element *el;
1780 el = ldb_msg_find_element(ac->msg, "member");
1782 for (i = 0; i < el->num_values; i++) {
1783 /* Denies to add "member"s to groups which are primary ones
1785 ret = samldb_add_step(ac, samldb_member_check_1);
1786 if (ret != LDB_SUCCESS) return ret;
1788 ret = samldb_add_step(ac, samldb_user_dn_to_prim_group_rid);
1789 if (ret != LDB_SUCCESS) return ret;
1791 ret = samldb_add_step(ac, samldb_member_check_2);
1792 if (ret != LDB_SUCCESS) return ret;
1794 ret = samldb_add_step(ac, samldb_dn_from_sid);
1795 if (ret != LDB_SUCCESS) return ret;
1797 ret = samldb_add_step(ac, samldb_member_check_3);
1798 if (ret != LDB_SUCCESS) return ret;
1801 ret = samldb_add_step(ac, samldb_member_check_4);
1802 if (ret != LDB_SUCCESS) return ret;
1804 return samldb_first_step(ac);
1808 static int samldb_prim_group_users_check_1(struct samldb_ctx *ac)
1810 ac->dn = ac->req->op.del.dn;
1813 return samldb_next_step(ac);
1816 static int samldb_prim_group_users_check_2(struct samldb_ctx *ac)
1821 if (ac->res_sid == NULL) {
1822 /* No SID - therefore ok here */
1823 return ldb_next_request(ac->module, ac->req);
1825 status = dom_sid_split_rid(ac, ac->res_sid, NULL, &rid);
1826 if (!NT_STATUS_IS_OK(status))
1827 return LDB_ERR_OPERATIONS_ERROR;
1830 /* Special object (security principal?) */
1831 return ldb_next_request(ac->module, ac->req);
1834 ac->prim_group_rid = rid;
1837 return samldb_next_step(ac);
1840 static int samldb_prim_group_users_check_3(struct samldb_ctx *ac)
1842 if (ac->users_cnt > 0)
1843 return LDB_ERR_ENTRY_ALREADY_EXISTS;
1845 return ldb_next_request(ac->module, ac->req);
1848 static int samldb_prim_group_users_check(struct samldb_ctx *ac)
1852 /* Finds out the SID/RID of the domain object */
1854 ret = samldb_add_step(ac, samldb_prim_group_users_check_1);
1855 if (ret != LDB_SUCCESS) return ret;
1857 ret = samldb_add_step(ac, samldb_sid_from_dn);
1858 if (ret != LDB_SUCCESS) return ret;
1860 /* Deny delete requests from groups which are primary ones */
1862 ret = samldb_add_step(ac, samldb_prim_group_users_check_2);
1863 if (ret != LDB_SUCCESS) return ret;
1865 ret = samldb_add_step(ac, samldb_prim_group_rid_to_users_cnt);
1866 if (ret != LDB_SUCCESS) return ret;
1868 ret = samldb_add_step(ac, samldb_prim_group_users_check_3);
1869 if (ret != LDB_SUCCESS) return ret;
1871 return samldb_first_step(ac);
1876 static int samldb_add(struct ldb_module *module, struct ldb_request *req)
1878 struct ldb_context *ldb;
1879 struct samldb_ctx *ac;
1882 ldb = ldb_module_get_ctx(module);
1883 ldb_debug(ldb, LDB_DEBUG_TRACE, "samldb_add\n");
1885 /* do not manipulate our control entries */
1886 if (ldb_dn_is_special(req->op.add.message->dn)) {
1887 return ldb_next_request(module, req);
1890 ac = samldb_ctx_init(module, req);
1892 return LDB_ERR_OPERATIONS_ERROR;
1895 /* build the new msg */
1896 ac->msg = ldb_msg_copy(ac, ac->req->op.add.message);
1899 ldb_debug(ldb, LDB_DEBUG_FATAL,
1900 "samldb_add: ldb_msg_copy failed!\n");
1901 return LDB_ERR_OPERATIONS_ERROR;
1904 if (samdb_find_attribute(ldb, ac->msg,
1905 "objectclass", "computer") != NULL) {
1907 /* make sure the computer object also has the 'user'
1908 * objectclass so it will be handled by the next call */
1909 ret = samdb_find_or_add_value(ldb, ac->msg,
1910 "objectclass", "user");
1911 if (ret != LDB_SUCCESS) {
1917 if (samdb_find_attribute(ldb, ac->msg,
1918 "objectclass", "user") != NULL) {
1920 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
1921 if (ret != LDB_SUCCESS) {
1926 return samldb_fill_object(ac, "user");
1929 if (samdb_find_attribute(ldb, ac->msg,
1930 "objectclass", "group") != NULL) {
1932 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
1933 if (ret != LDB_SUCCESS) {
1938 return samldb_fill_object(ac, "group");
1941 /* perhaps a foreignSecurityPrincipal? */
1942 if (samdb_find_attribute(ldb, ac->msg,
1944 "foreignSecurityPrincipal") != NULL) {
1946 ret = samldb_check_rdn(module, ac->req->op.add.message->dn);
1947 if (ret != LDB_SUCCESS) {
1952 return samldb_fill_foreignSecurityPrincipal_object(ac);
1957 /* nothing matched, go on */
1958 return ldb_next_request(module, req);
1962 static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
1964 struct ldb_context *ldb;
1965 struct ldb_message *msg;
1966 struct ldb_message_element *el, *el2;
1968 uint32_t account_type;
1970 if (ldb_dn_is_special(req->op.mod.message->dn)) {
1971 /* do not manipulate our control entries */
1972 return ldb_next_request(module, req);
1975 ldb = ldb_module_get_ctx(module);
1977 if (ldb_msg_find_element(req->op.mod.message, "sAMAccountType") != NULL) {
1978 ldb_asprintf_errstring(ldb,
1979 "sAMAccountType must not be specified!");
1980 return LDB_ERR_UNWILLING_TO_PERFORM;
1983 /* TODO: do not modify original request, create a new one */
1985 el = ldb_msg_find_element(req->op.mod.message, "groupType");
1986 if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
1987 uint32_t group_type;
1989 req->op.mod.message = msg = ldb_msg_copy_shallow(req,
1990 req->op.mod.message);
1992 group_type = strtoul((const char *)el->values[0].data, NULL, 0);
1993 account_type = ds_gtype2atype(group_type);
1994 ret = samdb_msg_add_uint(ldb, msg, msg,
1997 if (ret != LDB_SUCCESS) {
2000 el2 = ldb_msg_find_element(msg, "sAMAccountType");
2001 el2->flags = LDB_FLAG_MOD_REPLACE;
2004 el = ldb_msg_find_element(req->op.mod.message, "userAccountControl");
2005 if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
2006 uint32_t user_account_control;
2008 req->op.mod.message = msg = ldb_msg_copy_shallow(req,
2009 req->op.mod.message);
2011 user_account_control = strtoul((const char *)el->values[0].data,
2013 account_type = ds_uf2atype(user_account_control);
2014 ret = samdb_msg_add_uint(ldb, msg, msg,
2017 if (ret != LDB_SUCCESS) {
2020 el2 = ldb_msg_find_element(msg, "sAMAccountType");
2021 el2->flags = LDB_FLAG_MOD_REPLACE;
2023 if (user_account_control & UF_SERVER_TRUST_ACCOUNT) {
2024 ret = samdb_msg_add_string(ldb, msg, msg,
2025 "isCriticalSystemObject", "TRUE");
2026 if (ret != LDB_SUCCESS) {
2029 el2 = ldb_msg_find_element(msg, "isCriticalSystemObject");
2030 el2->flags = LDB_FLAG_MOD_REPLACE;
2034 el = ldb_msg_find_element(req->op.mod.message, "primaryGroupID");
2035 if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
2036 struct samldb_ctx *ac;
2038 ac = samldb_ctx_init(module, req);
2040 return LDB_ERR_OPERATIONS_ERROR;
2042 req->op.mod.message = ac->msg = ldb_msg_copy_shallow(req,
2043 req->op.mod.message);
2045 return samldb_prim_group_change(ac);
2048 el = ldb_msg_find_element(req->op.mod.message, "member");
2049 if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
2050 struct samldb_ctx *ac;
2052 ac = samldb_ctx_init(module, req);
2054 return LDB_ERR_OPERATIONS_ERROR;
2056 req->op.mod.message = ac->msg = ldb_msg_copy_shallow(req,
2057 req->op.mod.message);
2059 return samldb_member_check(ac);
2062 /* nothing matched, go on */
2063 return ldb_next_request(module, req);
2067 static int samldb_delete(struct ldb_module *module, struct ldb_request *req)
2069 struct samldb_ctx *ac;
2071 if (ldb_dn_is_special(req->op.del.dn)) {
2072 /* do not manipulate our control entries */
2073 return ldb_next_request(module, req);
2076 ac = samldb_ctx_init(module, req);
2078 return LDB_ERR_OPERATIONS_ERROR;
2080 return samldb_prim_group_users_check(ac);
2084 static int samldb_init(struct ldb_module *module)
2086 return ldb_next_init(module);
2089 _PUBLIC_ const struct ldb_module_ops ldb_samldb_module_ops = {
2091 .init_context = samldb_init,
2093 .modify = samldb_modify,
2094 .del = samldb_delete