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
;
101 /* If someone set an ares to forward controls and response back to the caller */
102 struct ldb_reply
*ares
;
105 static struct samldb_ctx
*samldb_ctx_init(struct ldb_module
*module
,
106 struct ldb_request
*req
)
108 struct ldb_context
*ldb
;
109 struct samldb_ctx
*ac
;
111 ldb
= ldb_module_get_ctx(module
);
113 ac
= talloc_zero(req
, struct samldb_ctx
);
125 static int samldb_add_step(struct samldb_ctx
*ac
, samldb_step_fn_t fn
)
127 struct samldb_step
*step
, *stepper
;
129 step
= talloc_zero(ac
, struct samldb_step
);
131 return LDB_ERR_OPERATIONS_ERROR
;
136 if (ac
->steps
== NULL
) {
140 if (ac
->curstep
== NULL
)
141 return LDB_ERR_OPERATIONS_ERROR
;
142 for (stepper
= ac
->curstep
; stepper
->next
!= NULL
;
143 stepper
= stepper
->next
);
144 stepper
->next
= step
;
150 static int samldb_first_step(struct samldb_ctx
*ac
)
152 if (ac
->steps
== NULL
) {
153 return LDB_ERR_OPERATIONS_ERROR
;
156 ac
->curstep
= ac
->steps
;
157 return ac
->curstep
->fn(ac
);
160 static int samldb_next_step(struct samldb_ctx
*ac
)
162 if (ac
->curstep
->next
) {
163 ac
->curstep
= ac
->curstep
->next
;
164 return ac
->curstep
->fn(ac
);
167 /* we exit the samldb module here */
168 /* If someone set an ares to forward controls and response back to the caller, use them */
170 return ldb_module_done(ac
->req
, ac
->ares
->controls
,
171 ac
->ares
->response
, LDB_SUCCESS
);
173 return ldb_module_done(ac
->req
, NULL
, NULL
, LDB_SUCCESS
);
178 * samldb_get_parent_domain (async)
181 static int samldb_get_parent_domain(struct samldb_ctx
*ac
);
183 static int samldb_get_parent_domain_callback(struct ldb_request
*req
,
184 struct ldb_reply
*ares
)
186 struct ldb_context
*ldb
;
187 struct samldb_ctx
*ac
;
191 ac
= talloc_get_type(req
->context
, struct samldb_ctx
);
192 ldb
= ldb_module_get_ctx(ac
->module
);
195 ret
= LDB_ERR_OPERATIONS_ERROR
;
198 if (ares
->error
!= LDB_SUCCESS
) {
199 return ldb_module_done(ac
->req
, ares
->controls
,
200 ares
->response
, ares
->error
);
203 switch (ares
->type
) {
204 case LDB_REPLY_ENTRY
:
206 if ((ac
->domain_dn
!= NULL
) || (ac
->domain_sid
!= NULL
)) {
208 ldb_set_errstring(ldb
,
209 "Invalid number of results while searching "
210 "for domain object!");
211 ret
= LDB_ERR_OPERATIONS_ERROR
;
215 nextRid
= ldb_msg_find_attr_as_string(ares
->message
,
217 if (nextRid
== NULL
) {
218 ldb_asprintf_errstring(ldb
,
219 "While looking for domain above %s attribute nextRid not found in %s!\n",
220 ldb_dn_get_linearized(
221 ac
->req
->op
.add
.message
->dn
),
222 ldb_dn_get_linearized(ares
->message
->dn
));
223 ret
= LDB_ERR_OPERATIONS_ERROR
;
227 ac
->next_rid
= strtol(nextRid
, NULL
, 0);
229 ac
->domain_sid
= samdb_result_dom_sid(ac
, ares
->message
,
231 if (ac
->domain_sid
== NULL
) {
232 ldb_set_errstring(ldb
,
233 "Unable to get the parent domain SID!\n");
234 ret
= LDB_ERR_CONSTRAINT_VIOLATION
;
237 ac
->domain_dn
= ldb_dn_copy(ac
, ares
->message
->dn
);
243 case LDB_REPLY_REFERRAL
:
251 if ((ac
->domain_dn
== NULL
) || (ac
->domain_sid
== NULL
)) {
252 /* not found -> retry */
253 ret
= samldb_get_parent_domain(ac
);
256 ret
= samldb_next_step(ac
);
262 if (ret
!= LDB_SUCCESS
) {
263 return ldb_module_done(ac
->req
, NULL
, NULL
, ret
);
269 /* Find a domain object in the parents of a particular DN. */
270 static int samldb_get_parent_domain(struct samldb_ctx
*ac
)
272 struct ldb_context
*ldb
;
273 static const char * const attrs
[] = { "objectSid", "nextRid", NULL
};
274 struct ldb_request
*req
;
278 ldb
= ldb_module_get_ctx(ac
->module
);
280 if (ac
->check_dn
== NULL
) {
281 return LDB_ERR_OPERATIONS_ERROR
;
284 dn
= ldb_dn_get_parent(ac
, ac
->check_dn
);
286 ldb_set_errstring(ldb
,
287 "Unable to find parent domain object!");
288 return LDB_ERR_CONSTRAINT_VIOLATION
;
293 ret
= ldb_build_search_req(&req
, ldb
, ac
,
295 "(|(objectClass=domain)"
296 "(objectClass=builtinDomain))",
299 ac
, samldb_get_parent_domain_callback
,
302 if (ret
!= LDB_SUCCESS
) {
306 return ldb_next_request(ac
->module
, req
);
310 static int samldb_generate_samAccountName(struct ldb_message
*msg
)
314 /* Format: $000000-000000000000 */
316 name
= talloc_asprintf(msg
, "$%.6X-%.6X%.6X",
317 (unsigned int)generate_random(),
318 (unsigned int)generate_random(),
319 (unsigned int)generate_random());
321 return LDB_ERR_OPERATIONS_ERROR
;
323 return ldb_msg_add_steal_string(msg
, "samAccountName", name
);
327 * samldb_check_samAccountName (async)
330 static int samldb_check_samAccountName_callback(struct ldb_request
*req
,
331 struct ldb_reply
*ares
)
333 struct samldb_ctx
*ac
;
336 ac
= talloc_get_type(req
->context
, struct samldb_ctx
);
338 if (ares
->error
!= LDB_SUCCESS
) {
339 return ldb_module_done(ac
->req
, ares
->controls
,
340 ares
->response
, ares
->error
);
343 switch (ares
->type
) {
344 case LDB_REPLY_ENTRY
:
345 /* if we get an entry it means this samAccountName
347 return ldb_module_done(ac
->req
, NULL
, NULL
,
348 LDB_ERR_ENTRY_ALREADY_EXISTS
);
350 case LDB_REPLY_REFERRAL
:
351 /* this should not happen */
352 return ldb_module_done(ac
->req
, NULL
, NULL
,
353 LDB_ERR_OPERATIONS_ERROR
);
356 /* not found, go on */
358 ret
= samldb_next_step(ac
);
362 if (ret
!= LDB_SUCCESS
) {
363 return ldb_module_done(ac
->req
, NULL
, NULL
, ret
);
369 static int samldb_check_samAccountName(struct samldb_ctx
*ac
)
371 struct ldb_context
*ldb
;
372 struct ldb_request
*req
;
377 ldb
= ldb_module_get_ctx(ac
->module
);
379 if (ldb_msg_find_element(ac
->msg
, "samAccountName") == NULL
) {
380 ret
= samldb_generate_samAccountName(ac
->msg
);
381 if (ret
!= LDB_SUCCESS
) {
386 name
= ldb_msg_find_attr_as_string(ac
->msg
, "samAccountName", NULL
);
388 return LDB_ERR_OPERATIONS_ERROR
;
390 filter
= talloc_asprintf(ac
, "samAccountName=%s", ldb_binary_encode_string(ac
, name
));
391 if (filter
== NULL
) {
392 return LDB_ERR_OPERATIONS_ERROR
;
395 ret
= ldb_build_search_req(&req
, ldb
, ac
,
396 ac
->domain_dn
, LDB_SCOPE_SUBTREE
,
399 ac
, samldb_check_samAccountName_callback
,
402 if (ret
!= LDB_SUCCESS
) {
405 return ldb_next_request(ac
->module
, req
);
409 static int samldb_check_samAccountType(struct samldb_ctx
*ac
)
411 struct ldb_context
*ldb
;
412 unsigned int account_type
;
413 unsigned int group_type
;
417 ldb
= ldb_module_get_ctx(ac
->module
);
419 /* make sure sAMAccountType is not specified */
420 if (ldb_msg_find_element(ac
->msg
, "sAMAccountType") != NULL
) {
421 ldb_asprintf_errstring(ldb
,
422 "sAMAccountType must not be specified!");
423 return LDB_ERR_UNWILLING_TO_PERFORM
;
426 if (strcmp("user", ac
->type
) == 0) {
427 uac
= samdb_result_uint(ac
->msg
, "userAccountControl", 0);
429 ldb_asprintf_errstring(ldb
,
430 "userAccountControl invalid!");
431 return LDB_ERR_UNWILLING_TO_PERFORM
;
433 account_type
= ds_uf2atype(uac
);
434 ret
= samdb_msg_add_uint(ldb
,
438 if (ret
!= LDB_SUCCESS
) {
443 if (strcmp("group", ac
->type
) == 0) {
445 group_type
= samdb_result_uint(ac
->msg
, "groupType", 0);
446 if (group_type
== 0) {
447 ldb_asprintf_errstring(ldb
,
448 "groupType invalid!");
449 return LDB_ERR_UNWILLING_TO_PERFORM
;
451 account_type
= ds_gtype2atype(group_type
);
452 ret
= samdb_msg_add_uint(ldb
,
456 if (ret
!= LDB_SUCCESS
) {
462 return samldb_next_step(ac
);
467 * samldb_get_sid_domain (async)
470 static int samldb_get_sid_domain_callback(struct ldb_request
*req
,
471 struct ldb_reply
*ares
)
473 struct ldb_context
*ldb
;
474 struct samldb_ctx
*ac
;
478 ac
= talloc_get_type(req
->context
, struct samldb_ctx
);
479 ldb
= ldb_module_get_ctx(ac
->module
);
482 ret
= LDB_ERR_OPERATIONS_ERROR
;
485 if (ares
->error
!= LDB_SUCCESS
) {
486 return ldb_module_done(ac
->req
, ares
->controls
,
487 ares
->response
, ares
->error
);
490 switch (ares
->type
) {
491 case LDB_REPLY_ENTRY
:
493 if (ac
->next_rid
!= 0) {
495 ldb_set_errstring(ldb
,
496 "Invalid number of results while searching "
497 "for domain object!");
498 ret
= LDB_ERR_OPERATIONS_ERROR
;
502 nextRid
= ldb_msg_find_attr_as_string(ares
->message
,
504 if (nextRid
== NULL
) {
505 ldb_asprintf_errstring(ldb
,
506 "Attribute nextRid not found in %s!\n",
507 ldb_dn_get_linearized(ares
->message
->dn
));
508 ret
= LDB_ERR_OPERATIONS_ERROR
;
512 ac
->next_rid
= strtol(nextRid
, NULL
, 0);
514 ac
->domain_dn
= ldb_dn_copy(ac
, ares
->message
->dn
);
520 case LDB_REPLY_REFERRAL
:
528 if (ac
->next_rid
== 0) {
529 ldb_asprintf_errstring(ldb
,
530 "Unable to get nextRid from domain entry!\n");
531 ret
= LDB_ERR_OPERATIONS_ERROR
;
536 ret
= samldb_next_step(ac
);
541 if (ret
!= LDB_SUCCESS
) {
542 return ldb_module_done(ac
->req
, NULL
, NULL
, ret
);
548 /* Find a domain object in the parents of a particular DN. */
549 static int samldb_get_sid_domain(struct samldb_ctx
*ac
)
551 struct ldb_context
*ldb
;
552 static const char * const attrs
[2] = { "nextRid", NULL
};
553 struct ldb_request
*req
;
557 ldb
= ldb_module_get_ctx(ac
->module
);
559 if (ac
->sid
== NULL
) {
560 return LDB_ERR_OPERATIONS_ERROR
;
563 ac
->domain_sid
= dom_sid_dup(ac
, ac
->sid
);
564 if (!ac
->domain_sid
) {
565 return LDB_ERR_OPERATIONS_ERROR
;
567 /* get the domain component part of the provided SID */
568 ac
->domain_sid
->num_auths
--;
570 filter
= talloc_asprintf(ac
,
572 "(|(objectClass=domain)"
573 "(objectClass=builtinDomain)))",
574 ldap_encode_ndr_dom_sid(ac
, ac
->domain_sid
));
575 if (filter
== NULL
) {
576 return LDB_ERR_OPERATIONS_ERROR
;
579 ret
= ldb_build_search_req(&req
, ldb
, ac
,
580 ldb_get_default_basedn(ldb
),
584 ac
, samldb_get_sid_domain_callback
,
587 if (ret
!= LDB_SUCCESS
) {
592 return ldb_next_request(ac
->module
, req
);
596 * samldb_dn_from_sid (async)
599 static int samldb_dn_from_sid(struct samldb_ctx
*ac
);
601 static int samldb_dn_from_sid_callback(struct ldb_request
*req
,
602 struct ldb_reply
*ares
)
604 struct ldb_context
*ldb
;
605 struct samldb_ctx
*ac
;
608 ac
= talloc_get_type(req
->context
, struct samldb_ctx
);
609 ldb
= ldb_module_get_ctx(ac
->module
);
612 ret
= LDB_ERR_OPERATIONS_ERROR
;
615 if (ares
->error
!= LDB_SUCCESS
) {
616 return ldb_module_done(ac
->req
, ares
->controls
,
617 ares
->response
, ares
->error
);
620 switch (ares
->type
) {
621 case LDB_REPLY_ENTRY
:
623 if (ac
->res_dn
!= NULL
) {
625 ldb_set_errstring(ldb
,
626 "Invalid number of results while searching "
627 "for domain objects!");
628 ret
= LDB_ERR_OPERATIONS_ERROR
;
631 ac
->res_dn
= ldb_dn_copy(ac
, ares
->message
->dn
);
637 case LDB_REPLY_REFERRAL
:
646 /* found or not found, go on */
647 ret
= samldb_next_step(ac
);
652 if (ret
!= LDB_SUCCESS
) {
653 return ldb_module_done(ac
->req
, NULL
, NULL
, ret
);
659 /* Finds the DN "res_dn" of an object with a given SID "sid" */
660 static int samldb_dn_from_sid(struct samldb_ctx
*ac
)
662 struct ldb_context
*ldb
;
663 static const char * const attrs
[] = { NULL
};
664 struct ldb_request
*req
;
668 ldb
= ldb_module_get_ctx(ac
->module
);
671 return LDB_ERR_OPERATIONS_ERROR
;
673 filter
= talloc_asprintf(ac
, "(objectSid=%s)",
674 ldap_encode_ndr_dom_sid(ac
, ac
->sid
));
676 return LDB_ERR_OPERATIONS_ERROR
;
678 ret
= ldb_build_search_req(&req
, ldb
, ac
,
679 ldb_get_default_basedn(ldb
),
683 ac
, samldb_dn_from_sid_callback
,
685 if (ret
!= LDB_SUCCESS
)
688 return ldb_next_request(ac
->module
, req
);
692 static int samldb_check_primaryGroupID_1(struct samldb_ctx
*ac
)
694 struct ldb_context
*ldb
;
697 ldb
= ldb_module_get_ctx(ac
->module
);
699 rid
= samdb_result_uint(ac
->msg
, "primaryGroupID", ~0);
700 ac
->sid
= dom_sid_add_rid(ac
, samdb_domain_sid(ldb
), rid
);
702 return LDB_ERR_OPERATIONS_ERROR
;
705 return samldb_next_step(ac
);
708 static int samldb_check_primaryGroupID_2(struct samldb_ctx
*ac
)
710 if (ac
->res_dn
== NULL
) {
711 struct ldb_context
*ldb
;
712 ldb
= ldb_module_get_ctx(ac
->module
);
713 ldb_asprintf_errstring(ldb
,
714 "Failed to find group sid %s",
715 dom_sid_string(ac
->sid
, ac
->sid
));
716 return LDB_ERR_UNWILLING_TO_PERFORM
;
719 return samldb_next_step(ac
);
723 static bool samldb_msg_add_sid(struct ldb_message
*msg
,
725 const struct dom_sid
*sid
)
728 enum ndr_err_code ndr_err
;
730 ndr_err
= ndr_push_struct_blob(&v
, msg
, NULL
, sid
,
731 (ndr_push_flags_fn_t
)ndr_push_dom_sid
);
732 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
735 return (ldb_msg_add_value(msg
, name
, &v
, NULL
) == 0);
738 static int samldb_new_sid(struct samldb_ctx
*ac
)
741 if (ac
->domain_sid
== NULL
|| ac
->next_rid
== 0) {
742 return LDB_ERR_OPERATIONS_ERROR
;
745 ac
->sid
= dom_sid_add_rid(ac
, ac
->domain_sid
, ac
->next_rid
+ 1);
746 if (ac
->sid
== NULL
) {
747 return LDB_ERR_OPERATIONS_ERROR
;
750 if ( ! samldb_msg_add_sid(ac
->msg
, "objectSid", ac
->sid
)) {
751 return LDB_ERR_OPERATIONS_ERROR
;
754 return samldb_next_step(ac
);
758 * samldb_notice_sid_callback (async)
761 static int samldb_notice_sid_callback(struct ldb_request
*req
,
762 struct ldb_reply
*ares
)
764 struct ldb_context
*ldb
;
765 struct samldb_ctx
*ac
;
768 ac
= talloc_get_type(req
->context
, struct samldb_ctx
);
769 ldb
= ldb_module_get_ctx(ac
->module
);
772 ret
= LDB_ERR_OPERATIONS_ERROR
;
775 if (ares
->error
!= LDB_SUCCESS
) {
776 return ldb_module_done(ac
->req
, ares
->controls
,
777 ares
->response
, ares
->error
);
779 if (ares
->type
!= LDB_REPLY_DONE
) {
780 ldb_set_errstring(ldb
,
781 "Invalid reply type!\n");
782 ret
= LDB_ERR_OPERATIONS_ERROR
;
786 ret
= samldb_next_step(ac
);
789 if (ret
!= LDB_SUCCESS
) {
790 return ldb_module_done(ac
->req
, NULL
, NULL
, ret
);
796 /* If we are adding new users/groups, we need to update the nextRid
797 * attribute to be 'above' the new/incoming RID. Attempt to do it
799 static int samldb_notice_sid(struct samldb_ctx
*ac
)
801 struct ldb_context
*ldb
;
802 uint32_t old_id
, new_id
;
803 struct ldb_request
*req
;
804 struct ldb_message
*msg
;
805 struct ldb_message_element
*els
;
806 struct ldb_val
*vals
;
809 ldb
= ldb_module_get_ctx(ac
->module
);
810 old_id
= ac
->next_rid
;
811 new_id
= ac
->sid
->sub_auths
[ac
->sid
->num_auths
- 1];
813 if (old_id
>= new_id
) {
814 /* no need to update the domain nextRid attribute */
815 return samldb_next_step(ac
);
818 /* we do a delete and add as a single operation. That prevents
819 a race, in case we are not actually on a transaction db */
820 msg
= ldb_msg_new(ac
);
823 return LDB_ERR_OPERATIONS_ERROR
;
825 els
= talloc_array(msg
, struct ldb_message_element
, 2);
828 return LDB_ERR_OPERATIONS_ERROR
;
830 vals
= talloc_array(msg
, struct ldb_val
, 2);
833 return LDB_ERR_OPERATIONS_ERROR
;
835 msg
->dn
= ac
->domain_dn
;
836 msg
->num_elements
= 2;
839 els
[0].num_values
= 1;
840 els
[0].values
= &vals
[0];
841 els
[0].flags
= LDB_FLAG_MOD_DELETE
;
842 els
[0].name
= talloc_strdup(msg
, "nextRid");
845 return LDB_ERR_OPERATIONS_ERROR
;
848 els
[1].num_values
= 1;
849 els
[1].values
= &vals
[1];
850 els
[1].flags
= LDB_FLAG_MOD_ADD
;
851 els
[1].name
= els
[0].name
;
853 vals
[0].data
= (uint8_t *)talloc_asprintf(vals
, "%u", old_id
);
856 return LDB_ERR_OPERATIONS_ERROR
;
858 vals
[0].length
= strlen((char *)vals
[0].data
);
860 vals
[1].data
= (uint8_t *)talloc_asprintf(vals
, "%u", new_id
);
863 return LDB_ERR_OPERATIONS_ERROR
;
865 vals
[1].length
= strlen((char *)vals
[1].data
);
867 ret
= ldb_build_mod_req(&req
, ldb
, ac
,
869 ac
, samldb_notice_sid_callback
,
871 if (ret
!= LDB_SUCCESS
) {
875 return ldb_next_request(ac
->module
, req
);
879 * samldb_set_defaultObjectCategory_callback (async)
882 static int samldb_set_defaultObjectCategory_callback(struct ldb_request
*req
,
883 struct ldb_reply
*ares
)
885 struct ldb_context
*ldb
;
886 struct samldb_ctx
*ac
;
889 ac
= talloc_get_type(req
->context
, struct samldb_ctx
);
890 ldb
= ldb_module_get_ctx(ac
->module
);
893 ret
= LDB_ERR_OPERATIONS_ERROR
;
896 if (ares
->error
!= LDB_SUCCESS
) {
897 return ldb_module_done(ac
->req
, ares
->controls
,
898 ares
->response
, ares
->error
);
900 if (ares
->type
!= LDB_REPLY_DONE
) {
901 ldb_set_errstring(ldb
,
902 "Invalid reply type!\n");
903 ret
= LDB_ERR_OPERATIONS_ERROR
;
907 ret
= samldb_next_step(ac
);
910 if (ret
!= LDB_SUCCESS
) {
911 return ldb_module_done(ac
->req
, NULL
, NULL
, ret
);
917 static int samldb_set_defaultObjectCategory(struct samldb_ctx
*ac
)
921 struct ldb_request
*req
;
922 struct ldb_context
*ldb
;
923 struct ldb_message
*msg
= ldb_msg_new(ac
);
927 ldb_msg_add_empty(msg
, "defaultObjectCategory", LDB_FLAG_MOD_REPLACE
, NULL
);
929 ldb_msg_add_steal_string(msg
, "defaultObjectCategory", ldb_dn_alloc_linearized(msg
, ac
->dn
));
931 ldb
= ldb_module_get_ctx(ac
->module
);
933 ret
= ldb_build_mod_req(&req
, ldb
, ac
,
935 ac
, samldb_set_defaultObjectCategory_callback
,
937 if (ret
!= LDB_SUCCESS
) {
941 return ldb_next_request(ac
->module
, req
);
944 ret
= samldb_next_step(ac
);
945 if (ret
!= LDB_SUCCESS
) {
946 return ldb_module_done(ac
->req
, NULL
, NULL
, ret
);
952 * samldb_find_for_defaultObjectCategory (async)
955 static int samldb_find_for_defaultObjectCategory_callback(struct ldb_request
*req
,
956 struct ldb_reply
*ares
)
958 struct samldb_ctx
*ac
;
961 ac
= talloc_get_type(req
->context
, struct samldb_ctx
);
963 if (ares
->error
!= LDB_SUCCESS
) {
964 return ldb_module_done(ac
->req
, ares
->controls
,
965 ares
->response
, ares
->error
);
968 switch (ares
->type
) {
969 case LDB_REPLY_ENTRY
:
970 ac
->dn
= talloc_steal(ac
, ares
->message
->dn
);
972 case LDB_REPLY_REFERRAL
:
973 /* this should not happen */
974 return ldb_module_done(ac
->req
, NULL
, NULL
,
975 LDB_ERR_OPERATIONS_ERROR
);
978 /* found or not found, go on */
980 ret
= samldb_next_step(ac
);
981 if (ret
!= LDB_SUCCESS
) {
982 return ldb_module_done(ac
->req
, NULL
, NULL
, ret
);
990 static int samldb_find_for_defaultObjectCategory(struct samldb_ctx
*ac
)
992 struct ldb_context
*ldb
;
993 struct ldb_request
*req
;
995 const char *no_attrs
[] = { NULL
};
997 ldb
= ldb_module_get_ctx(ac
->module
);
1001 if (ldb_msg_find_element(ac
->msg
, "defaultObjectCategory") == NULL
) {
1002 ret
= ldb_build_search_req(&req
, ldb
, ac
,
1003 ac
->msg
->dn
, LDB_SCOPE_BASE
,
1004 "objectClass=classSchema", no_attrs
,
1006 ac
, samldb_find_for_defaultObjectCategory_callback
,
1008 if (ret
!= LDB_SUCCESS
) {
1011 return ldb_next_request(ac
->module
, req
);
1014 ret
= samldb_next_step(ac
);
1015 if (ret
!= LDB_SUCCESS
) {
1016 return ldb_module_done(ac
->req
, NULL
, NULL
, ret
);
1025 * samldb_add_entry (async)
1028 static int samldb_add_entry_callback(struct ldb_request
*req
,
1029 struct ldb_reply
*ares
)
1031 struct ldb_context
*ldb
;
1032 struct samldb_ctx
*ac
;
1035 ac
= talloc_get_type(req
->context
, struct samldb_ctx
);
1036 ldb
= ldb_module_get_ctx(ac
->module
);
1039 return ldb_module_done(ac
->req
, NULL
, NULL
,
1040 LDB_ERR_OPERATIONS_ERROR
);
1042 if (ares
->error
!= LDB_SUCCESS
) {
1043 return ldb_module_done(ac
->req
, ares
->controls
,
1044 ares
->response
, ares
->error
);
1046 if (ares
->type
!= LDB_REPLY_DONE
) {
1047 ldb_set_errstring(ldb
,
1048 "Invalid reply type!\n");
1049 return ldb_module_done(ac
->req
, NULL
, NULL
,
1050 LDB_ERR_OPERATIONS_ERROR
);
1053 /* The caller may wish to get controls back from the add */
1054 ac
->ares
= talloc_steal(ac
, ares
);
1056 ret
= samldb_next_step(ac
);
1057 if (ret
!= LDB_SUCCESS
) {
1058 return ldb_module_done(ac
->req
, NULL
, NULL
, ret
);
1063 static int samldb_add_entry(struct samldb_ctx
*ac
)
1065 struct ldb_context
*ldb
;
1066 struct ldb_request
*req
;
1069 ldb
= ldb_module_get_ctx(ac
->module
);
1071 ret
= ldb_build_add_req(&req
, ldb
, ac
,
1074 ac
, samldb_add_entry_callback
,
1076 if (ret
!= LDB_SUCCESS
) {
1080 return ldb_next_request(ac
->module
, req
);
1084 static int samldb_fill_object(struct samldb_ctx
*ac
, const char *type
)
1086 struct ldb_context
*ldb
;
1087 struct loadparm_context
*lp_ctx
;
1088 enum sid_generator sid_generator
;
1091 ldb
= ldb_module_get_ctx(ac
->module
);
1093 /* search for a parent domain objet */
1094 ac
->check_dn
= ac
->req
->op
.add
.message
->dn
;
1095 ret
= samldb_add_step(ac
, samldb_get_parent_domain
);
1096 if (ret
!= LDB_SUCCESS
) return ret
;
1098 /* Add informations for the different account types */
1100 if (strcmp(ac
->type
, "user") == 0) {
1101 ret
= samdb_find_or_add_attribute(ldb
, ac
->msg
,
1102 "userAccountControl", "546");
1103 if (ret
!= LDB_SUCCESS
) return ret
;
1104 ret
= samdb_find_or_add_attribute(ldb
, ac
->msg
,
1105 "badPwdCount", "0");
1106 if (ret
!= LDB_SUCCESS
) return ret
;
1107 ret
= samdb_find_or_add_attribute(ldb
, ac
->msg
,
1109 if (ret
!= LDB_SUCCESS
) return ret
;
1110 ret
= samdb_find_or_add_attribute(ldb
, ac
->msg
,
1111 "countryCode", "0");
1112 if (ret
!= LDB_SUCCESS
) return ret
;
1113 ret
= samdb_find_or_add_attribute(ldb
, ac
->msg
,
1114 "badPasswordTime", "0");
1115 if (ret
!= LDB_SUCCESS
) return ret
;
1116 ret
= samdb_find_or_add_attribute(ldb
, ac
->msg
,
1118 if (ret
!= LDB_SUCCESS
) return ret
;
1119 ret
= samdb_find_or_add_attribute(ldb
, ac
->msg
,
1121 if (ret
!= LDB_SUCCESS
) return ret
;
1122 ret
= samdb_find_or_add_attribute(ldb
, ac
->msg
,
1124 if (ret
!= LDB_SUCCESS
) return ret
;
1125 ret
= samdb_find_or_add_attribute(ldb
, ac
->msg
,
1126 "primaryGroupID", "513");
1127 if (ret
!= LDB_SUCCESS
) return ret
;
1128 ret
= samdb_find_or_add_attribute(ldb
, ac
->msg
,
1129 "accountExpires", "9223372036854775807");
1130 if (ret
!= LDB_SUCCESS
) return ret
;
1131 ret
= samdb_find_or_add_attribute(ldb
, ac
->msg
,
1133 if (ret
!= LDB_SUCCESS
) return ret
;
1134 } else if (strcmp(ac
->type
, "group") == 0) {
1135 ret
= samdb_find_or_add_attribute(ldb
, ac
->msg
,
1136 "groupType", "-2147483646");
1137 if (ret
!= LDB_SUCCESS
) return ret
;
1138 } else if (strcmp(ac
->type
, "classSchema") == 0) {
1139 const struct ldb_val
*rdn_value
;
1141 ret
= samdb_find_or_add_attribute(ldb
, ac
->msg
,
1143 if (ret
!= LDB_SUCCESS
) return ret
;
1145 rdn_value
= ldb_dn_get_rdn_val(ac
->msg
->dn
);
1146 if (!ldb_msg_find_element(ac
->msg
, "lDAPDisplayName")) {
1147 /* the RDN has prefix "CN" */
1148 ret
= ldb_msg_add_string(ac
->msg
, "lDAPDisplayName",
1149 samdb_cn_to_lDAPDisplayName(ac
,
1150 (const char *) rdn_value
->data
));
1151 if (ret
!= LDB_SUCCESS
) {
1157 if (!ldb_msg_find_element(ac
->msg
, "schemaIDGUID")) {
1158 enum ndr_err_code ndr_err
;
1159 struct ldb_val guid_value
;
1162 guid
= GUID_random();
1163 /* generated NDR encoded values */
1164 ndr_err
= ndr_push_struct_blob(&guid_value
, ac
->msg
,
1167 (ndr_push_flags_fn_t
)ndr_push_GUID
);
1168 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1170 return LDB_ERR_OPERATIONS_ERROR
;
1172 ret
= ldb_msg_add_value(ac
->msg
, "schemaIDGUID", &guid_value
, NULL
);
1173 if (ret
!= LDB_SUCCESS
) {
1179 ret
= samldb_add_step(ac
, samldb_add_entry
);
1180 if (ret
!= LDB_SUCCESS
) return ret
;
1182 ret
= samldb_add_step(ac
, samldb_find_for_defaultObjectCategory
);
1183 if (ret
!= LDB_SUCCESS
) return ret
;
1185 ret
= samldb_add_step(ac
, samldb_set_defaultObjectCategory
);
1186 if (ret
!= LDB_SUCCESS
) return ret
;
1188 return samldb_first_step(ac
);
1189 } else if (strcmp(ac
->type
, "attributeSchema") == 0) {
1190 const struct ldb_val
*rdn_value
;
1191 rdn_value
= ldb_dn_get_rdn_val(ac
->msg
->dn
);
1192 if (!ldb_msg_find_element(ac
->msg
, "lDAPDisplayName")) {
1193 /* the RDN has prefix "CN" */
1194 ret
= ldb_msg_add_string(ac
->msg
, "lDAPDisplayName",
1195 samdb_cn_to_lDAPDisplayName(ac
,
1196 (const char *) rdn_value
->data
));
1197 if (ret
!= LDB_SUCCESS
) {
1203 ret
= samdb_find_or_add_attribute(ldb
, ac
->msg
,
1204 "isSingleValued", "FALSE");
1205 if (ret
!= LDB_SUCCESS
) return ret
;
1207 if (!ldb_msg_find_element(ac
->msg
, "schemaIDGUID")) {
1208 enum ndr_err_code ndr_err
;
1209 struct ldb_val guid_value
;
1212 guid
= GUID_random();
1213 /* generated NDR encoded values */
1214 ndr_err
= ndr_push_struct_blob(&guid_value
, ac
->msg
,
1217 (ndr_push_flags_fn_t
)ndr_push_GUID
);
1218 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1220 return LDB_ERR_OPERATIONS_ERROR
;
1222 ret
= ldb_msg_add_value(ac
->msg
, "schemaIDGUID", &guid_value
, NULL
);
1223 if (ret
!= LDB_SUCCESS
) {
1229 ret
= samldb_add_step(ac
, samldb_add_entry
);
1230 if (ret
!= LDB_SUCCESS
) return ret
;
1232 return samldb_first_step(ac
);
1234 ldb_asprintf_errstring(ldb
,
1235 "Invalid entry type!\n");
1236 return LDB_ERR_OPERATIONS_ERROR
;
1239 /* check if we have a valid samAccountName */
1240 ret
= samldb_add_step(ac
, samldb_check_samAccountName
);
1241 if (ret
!= LDB_SUCCESS
) return ret
;
1243 /* check account_type/group_type */
1244 ret
= samldb_add_step(ac
, samldb_check_samAccountType
);
1245 if (ret
!= LDB_SUCCESS
) return ret
;
1247 /* check if we have a valid primary group ID */
1248 if (strcmp(ac
->type
, "user") == 0) {
1249 ret
= samldb_add_step(ac
, samldb_check_primaryGroupID_1
);
1250 if (ret
!= LDB_SUCCESS
) return ret
;
1251 ret
= samldb_add_step(ac
, samldb_dn_from_sid
);
1252 if (ret
!= LDB_SUCCESS
) return ret
;
1253 ret
= samldb_add_step(ac
, samldb_check_primaryGroupID_2
);
1254 if (ret
!= LDB_SUCCESS
) return ret
;
1257 lp_ctx
= talloc_get_type(ldb_get_opaque(ldb
, "loadparm"),
1258 struct loadparm_context
);
1260 sid_generator
= lp_sid_generator(lp_ctx
);
1261 if (sid_generator
== SID_GENERATOR_INTERNAL
) {
1262 /* check if we have a valid SID */
1263 ac
->sid
= samdb_result_dom_sid(ac
, ac
->msg
, "objectSid");
1265 ret
= samldb_add_step(ac
, samldb_new_sid
);
1266 if (ret
!= LDB_SUCCESS
) return ret
;
1268 ret
= samldb_add_step(ac
, samldb_get_sid_domain
);
1269 if (ret
!= LDB_SUCCESS
) return ret
;
1272 ret
= samldb_add_step(ac
, samldb_notice_sid
);
1273 if (ret
!= LDB_SUCCESS
) return ret
;
1276 /* finally proceed with adding the entry */
1277 ret
= samldb_add_step(ac
, samldb_add_entry
);
1278 if (ret
!= LDB_SUCCESS
) return ret
;
1280 return samldb_first_step(ac
);
1284 * samldb_foreign_notice_sid (async)
1287 static int samldb_foreign_notice_sid_callback(struct ldb_request
*req
,
1288 struct ldb_reply
*ares
)
1290 struct ldb_context
*ldb
;
1291 struct samldb_ctx
*ac
;
1292 const char *nextRid
;
1296 ac
= talloc_get_type(req
->context
, struct samldb_ctx
);
1297 ldb
= ldb_module_get_ctx(ac
->module
);
1300 ret
= LDB_ERR_OPERATIONS_ERROR
;
1303 if (ares
->error
!= LDB_SUCCESS
) {
1304 return ldb_module_done(ac
->req
, ares
->controls
,
1305 ares
->response
, ares
->error
);
1308 switch (ares
->type
) {
1309 case LDB_REPLY_ENTRY
:
1311 if (ac
->next_rid
!= 0) {
1313 ldb_set_errstring(ldb
,
1314 "Invalid number of results while searching "
1315 "for domain object!");
1316 ret
= LDB_ERR_OPERATIONS_ERROR
;
1320 nextRid
= ldb_msg_find_attr_as_string(ares
->message
,
1322 if (nextRid
== NULL
) {
1323 ldb_asprintf_errstring(ldb
,
1324 "while looking for forign sid %s attribute nextRid not found in %s\n",
1325 dom_sid_string(ares
, ac
->sid
),
1326 ldb_dn_get_linearized(ares
->message
->dn
));
1327 ret
= LDB_ERR_OPERATIONS_ERROR
;
1331 ac
->next_rid
= strtol(nextRid
, NULL
, 0);
1333 ac
->domain_dn
= ldb_dn_copy(ac
, ares
->message
->dn
);
1335 name
= samdb_result_string(ares
->message
, "name", NULL
);
1336 ldb_debug(ldb
, LDB_DEBUG_TRACE
,
1337 "NOTE (strange but valid): Adding foreign SID "
1338 "record with SID %s, but this domain (%s) is "
1339 "not foreign in the database",
1340 dom_sid_string(ares
, ac
->sid
), name
);
1346 case LDB_REPLY_REFERRAL
:
1352 case LDB_REPLY_DONE
:
1355 /* if this is a fake foreign SID, notice the SID */
1356 if (ac
->domain_dn
) {
1357 ret
= samldb_notice_sid(ac
);
1362 ret
= samldb_next_step(ac
);
1367 if (ret
!= LDB_SUCCESS
) {
1368 return ldb_module_done(ac
->req
, NULL
, NULL
, ret
);
1374 /* Find a domain object in the parents of a particular DN. */
1375 static int samldb_foreign_notice_sid(struct samldb_ctx
*ac
)
1377 struct ldb_context
*ldb
;
1378 static const char * const attrs
[3] = { "nextRid", "name", NULL
};
1379 struct ldb_request
*req
;
1384 ldb
= ldb_module_get_ctx(ac
->module
);
1386 if (ac
->sid
== NULL
) {
1387 return LDB_ERR_OPERATIONS_ERROR
;
1390 status
= dom_sid_split_rid(ac
, ac
->sid
, &ac
->domain_sid
, NULL
);
1391 if (!NT_STATUS_IS_OK(status
)) {
1392 return LDB_ERR_OPERATIONS_ERROR
;
1395 filter
= talloc_asprintf(ac
, "(&(objectSid=%s)(objectclass=domain))",
1396 ldap_encode_ndr_dom_sid(ac
, ac
->domain_sid
));
1397 if (filter
== NULL
) {
1398 return LDB_ERR_OPERATIONS_ERROR
;
1401 ret
= ldb_build_search_req(&req
, ldb
, ac
,
1402 ldb_get_default_basedn(ldb
),
1406 ac
, samldb_foreign_notice_sid_callback
,
1409 if (ret
!= LDB_SUCCESS
) {
1413 return ldb_next_request(ac
->module
, req
);
1417 static int samldb_fill_foreignSecurityPrincipal_object(struct samldb_ctx
*ac
)
1419 struct ldb_context
*ldb
;
1422 ldb
= ldb_module_get_ctx(ac
->module
);
1426 ac
->sid
= samdb_result_dom_sid(ac
->msg
, ac
->msg
, "objectSid");
1427 if (ac
->sid
== NULL
) {
1428 ac
->sid
= dom_sid_parse_talloc(ac
->msg
,
1429 (const char *)ldb_dn_get_rdn_val(ac
->msg
->dn
)->data
);
1431 ldb_set_errstring(ldb
,
1432 "No valid SID found in "
1433 "ForeignSecurityPrincipal CN!");
1435 return LDB_ERR_CONSTRAINT_VIOLATION
;
1437 if ( ! samldb_msg_add_sid(ac
->msg
, "objectSid", ac
->sid
)) {
1439 return LDB_ERR_OPERATIONS_ERROR
;
1443 /* check if we need to notice this SID */
1444 ret
= samldb_add_step(ac
, samldb_foreign_notice_sid
);
1445 if (ret
!= LDB_SUCCESS
) return ret
;
1447 /* finally proceed with adding the entry */
1448 ret
= samldb_add_step(ac
, samldb_add_entry
);
1449 if (ret
!= LDB_SUCCESS
) return ret
;
1451 return samldb_first_step(ac
);
1454 static int samldb_check_rdn(struct ldb_module
*module
, struct ldb_dn
*dn
)
1456 struct ldb_context
*ldb
;
1457 const char *rdn_name
;
1459 ldb
= ldb_module_get_ctx(module
);
1460 rdn_name
= ldb_dn_get_rdn_name(dn
);
1462 if (strcasecmp(rdn_name
, "cn") != 0) {
1463 ldb_asprintf_errstring(ldb
,
1464 "Bad RDN (%s=) for samldb object, "
1465 "should be CN=!\n", rdn_name
);
1466 return LDB_ERR_CONSTRAINT_VIOLATION
;
1473 * samldb_sid_from_dn (async)
1476 static int samldb_sid_from_dn(struct samldb_ctx
*ac
);
1478 static int samldb_sid_from_dn_callback(struct ldb_request
*req
,
1479 struct ldb_reply
*ares
)
1481 struct ldb_context
*ldb
;
1482 struct samldb_ctx
*ac
;
1485 ac
= talloc_get_type(req
->context
, struct samldb_ctx
);
1486 ldb
= ldb_module_get_ctx(ac
->module
);
1489 ret
= LDB_ERR_OPERATIONS_ERROR
;
1492 if (ares
->error
!= LDB_SUCCESS
) {
1493 return ldb_module_done(ac
->req
, ares
->controls
,
1494 ares
->response
, ares
->error
);
1497 switch (ares
->type
) {
1498 case LDB_REPLY_ENTRY
:
1500 if (ac
->res_sid
!= NULL
) {
1502 ldb_set_errstring(ldb
,
1503 "Invalid number of results while searching "
1504 "for domain objects!");
1505 ret
= LDB_ERR_OPERATIONS_ERROR
;
1508 ac
->res_sid
= samdb_result_dom_sid(ac
, ares
->message
,
1515 case LDB_REPLY_REFERRAL
:
1521 case LDB_REPLY_DONE
:
1524 /* found or not found, go on */
1525 ret
= samldb_next_step(ac
);
1530 if (ret
!= LDB_SUCCESS
) {
1531 return ldb_module_done(ac
->req
, NULL
, NULL
, ret
);
1537 /* Finds the SID "res_sid" of an object with a given DN "dn" */
1538 static int samldb_sid_from_dn(struct samldb_ctx
*ac
)
1540 struct ldb_context
*ldb
;
1541 static const char * const attrs
[] = { "objectSid" };
1542 struct ldb_request
*req
;
1545 ldb
= ldb_module_get_ctx(ac
->module
);
1548 return LDB_ERR_OPERATIONS_ERROR
;
1550 ret
= ldb_build_search_req(&req
, ldb
, ac
,
1555 ac
, samldb_sid_from_dn_callback
,
1557 if (ret
!= LDB_SUCCESS
)
1560 return ldb_next_request(ac
->module
, req
);
1564 * samldb_user_dn_to_prim_group_rid (async)
1567 static int samldb_user_dn_to_prim_group_rid(struct samldb_ctx
*ac
);
1569 static int samldb_user_dn_to_prim_group_rid_callback(struct ldb_request
*req
,
1570 struct ldb_reply
*ares
)
1572 struct ldb_context
*ldb
;
1573 struct samldb_ctx
*ac
;
1576 ac
= talloc_get_type(req
->context
, struct samldb_ctx
);
1577 ldb
= ldb_module_get_ctx(ac
->module
);
1580 ret
= LDB_ERR_OPERATIONS_ERROR
;
1583 if (ares
->error
!= LDB_SUCCESS
) {
1584 return ldb_module_done(ac
->req
, ares
->controls
,
1585 ares
->response
, ares
->error
);
1588 switch (ares
->type
) {
1589 case LDB_REPLY_ENTRY
:
1591 if (ac
->prim_group_rid
!= 0) {
1593 ldb_set_errstring(ldb
,
1594 "Invalid number of results while searching "
1595 "for domain objects!");
1596 ret
= LDB_ERR_OPERATIONS_ERROR
;
1599 ac
->prim_group_rid
= samdb_result_uint(ares
->message
,
1600 "primaryGroupID", ~0);
1606 case LDB_REPLY_REFERRAL
:
1612 case LDB_REPLY_DONE
:
1614 if (ac
->prim_group_rid
== 0) {
1615 ldb_asprintf_errstring(ldb
,
1616 "Unable to get the primary group RID!\n");
1617 ret
= LDB_ERR_OPERATIONS_ERROR
;
1622 ret
= samldb_next_step(ac
);
1627 if (ret
!= LDB_SUCCESS
) {
1628 return ldb_module_done(ac
->req
, NULL
, NULL
, ret
);
1634 /* Locates the "primaryGroupID" attribute from a certain user specified as
1635 * "user_dn". Saves the result in "prim_group_rid". */
1636 static int samldb_user_dn_to_prim_group_rid(struct samldb_ctx
*ac
)
1638 struct ldb_context
*ldb
;
1639 static const char * const attrs
[] = { "primaryGroupID", NULL
};
1640 struct ldb_request
*req
;
1643 ldb
= ldb_module_get_ctx(ac
->module
);
1645 if (ac
->user_dn
== NULL
)
1646 return LDB_ERR_OPERATIONS_ERROR
;
1648 ret
= ldb_build_search_req(&req
, ldb
, ac
,
1653 ac
, samldb_user_dn_to_prim_group_rid_callback
,
1655 if (ret
!= LDB_SUCCESS
)
1658 return ldb_next_request(ac
->module
, req
);
1662 * samldb_prim_group_rid_to_users_cnt (async)
1665 static int samldb_prim_group_rid_to_users_cnt(struct samldb_ctx
*ac
);
1667 static int samldb_prim_group_rid_to_users_cnt_callback(struct ldb_request
*req
,
1668 struct ldb_reply
*ares
)
1670 struct ldb_context
*ldb
;
1671 struct samldb_ctx
*ac
;
1674 ac
= talloc_get_type(req
->context
, struct samldb_ctx
);
1675 ldb
= ldb_module_get_ctx(ac
->module
);
1678 ret
= LDB_ERR_OPERATIONS_ERROR
;
1681 if (ares
->error
!= LDB_SUCCESS
) {
1682 return ldb_module_done(ac
->req
, ares
->controls
,
1683 ares
->response
, ares
->error
);
1686 switch (ares
->type
) {
1687 case LDB_REPLY_ENTRY
:
1695 case LDB_REPLY_REFERRAL
:
1701 case LDB_REPLY_DONE
:
1704 /* found or not found, go on */
1705 ret
= samldb_next_step(ac
);
1710 if (ret
!= LDB_SUCCESS
) {
1711 return ldb_module_done(ac
->req
, NULL
, NULL
, ret
);
1717 /* Finds the amount of users which have the primary group "prim_group_rid" and
1718 * save the result in "users_cnt" */
1719 static int samldb_prim_group_rid_to_users_cnt(struct samldb_ctx
*ac
)
1721 struct ldb_context
*ldb
;
1722 static const char * const attrs
[] = { NULL
};
1723 struct ldb_request
*req
;
1727 ldb
= ldb_module_get_ctx(ac
->module
);
1729 if ((ac
->prim_group_rid
== 0) || (ac
->users_cnt
!= 0))
1730 return LDB_ERR_OPERATIONS_ERROR
;
1732 filter
= talloc_asprintf(ac
, "(&(primaryGroupID=%u)(objectclass=user))",
1733 ac
->prim_group_rid
);
1735 return LDB_ERR_OPERATIONS_ERROR
;
1737 ret
= ldb_build_search_req(&req
, ldb
, ac
,
1738 ldb_get_default_basedn(ldb
),
1743 samldb_prim_group_rid_to_users_cnt_callback
,
1745 if (ret
!= LDB_SUCCESS
)
1748 return ldb_next_request(ac
->module
, req
);
1752 * samldb_group_add_member (async)
1753 * samldb_group_del_member (async)
1756 static int samldb_group_add_del_member_callback(struct ldb_request
*req
,
1757 struct ldb_reply
*ares
)
1759 struct ldb_context
*ldb
;
1760 struct samldb_ctx
*ac
;
1763 ac
= talloc_get_type(req
->context
, struct samldb_ctx
);
1764 ldb
= ldb_module_get_ctx(ac
->module
);
1767 ret
= LDB_ERR_OPERATIONS_ERROR
;
1770 if (ares
->error
!= LDB_SUCCESS
) {
1771 if (ares
->error
== LDB_ERR_NO_SUCH_ATTRIBUTE
) {
1772 /* On error "NO_SUCH_ATTRIBUTE" (delete of an invalid
1773 * "member" attribute) return "UNWILLING_TO_PERFORM" */
1774 ares
->error
= LDB_ERR_UNWILLING_TO_PERFORM
;
1776 return ldb_module_done(ac
->req
, ares
->controls
,
1777 ares
->response
, ares
->error
);
1779 if (ares
->type
!= LDB_REPLY_DONE
) {
1780 ldb_set_errstring(ldb
,
1781 "Invalid reply type!\n");
1782 ret
= LDB_ERR_OPERATIONS_ERROR
;
1786 ret
= samldb_next_step(ac
);
1789 if (ret
!= LDB_SUCCESS
) {
1790 return ldb_module_done(ac
->req
, NULL
, NULL
, ret
);
1796 /* Adds a member with DN "member_dn" to a group with DN "group_dn" */
1797 static int samldb_group_add_member(struct samldb_ctx
*ac
)
1799 struct ldb_context
*ldb
;
1800 struct ldb_request
*req
;
1801 struct ldb_message
*msg
;
1804 ldb
= ldb_module_get_ctx(ac
->module
);
1806 if ((ac
->group_dn
== NULL
) || (ac
->member_dn
== NULL
))
1807 return LDB_ERR_OPERATIONS_ERROR
;
1809 msg
= ldb_msg_new(ac
);
1810 msg
->dn
= ac
->group_dn
;
1811 samdb_msg_add_addval(ldb
, ac
, msg
, "member",
1812 ldb_dn_get_linearized(ac
->member_dn
));
1814 ret
= ldb_build_mod_req(&req
, ldb
, ac
,
1816 ac
, samldb_group_add_del_member_callback
,
1818 if (ret
!= LDB_SUCCESS
)
1821 return ldb_next_request(ac
->module
, req
);
1824 /* Removes a member with DN "member_dn" from a group with DN "group_dn" */
1825 static int samldb_group_del_member(struct samldb_ctx
*ac
)
1827 struct ldb_context
*ldb
;
1828 struct ldb_request
*req
;
1829 struct ldb_message
*msg
;
1832 ldb
= ldb_module_get_ctx(ac
->module
);
1834 if ((ac
->group_dn
== NULL
) || (ac
->member_dn
== NULL
))
1835 return LDB_ERR_OPERATIONS_ERROR
;
1837 msg
= ldb_msg_new(ac
);
1838 msg
->dn
= ac
->group_dn
;
1839 samdb_msg_add_delval(ldb
, ac
, msg
, "member",
1840 ldb_dn_get_linearized(ac
->member_dn
));
1842 ret
= ldb_build_mod_req(&req
, ldb
, ac
,
1844 ac
, samldb_group_add_del_member_callback
,
1846 if (ret
!= LDB_SUCCESS
)
1849 return ldb_next_request(ac
->module
, req
);
1853 static int samldb_prim_group_change_1(struct samldb_ctx
*ac
)
1855 struct ldb_context
*ldb
;
1858 ldb
= ldb_module_get_ctx(ac
->module
);
1860 ac
->user_dn
= ac
->msg
->dn
;
1862 rid
= samdb_result_uint(ac
->msg
, "primaryGroupID", ~0);
1863 ac
->sid
= dom_sid_add_rid(ac
, samdb_domain_sid(ldb
), rid
);
1864 if (ac
->sid
== NULL
)
1865 return LDB_ERR_OPERATIONS_ERROR
;
1868 ac
->prim_group_rid
= 0;
1870 return samldb_next_step(ac
);
1873 static int samldb_prim_group_change_2(struct samldb_ctx
*ac
)
1875 struct ldb_context
*ldb
;
1877 ldb
= ldb_module_get_ctx(ac
->module
);
1879 if (ac
->res_dn
!= NULL
)
1880 ac
->new_prim_group_dn
= ac
->res_dn
;
1882 return LDB_ERR_UNWILLING_TO_PERFORM
;
1884 ac
->sid
= dom_sid_add_rid(ac
, samdb_domain_sid(ldb
),
1885 ac
->prim_group_rid
);
1886 if (ac
->sid
== NULL
)
1887 return LDB_ERR_OPERATIONS_ERROR
;
1890 return samldb_next_step(ac
);
1893 static int samldb_prim_group_change_4(struct samldb_ctx
*ac
);
1894 static int samldb_prim_group_change_5(struct samldb_ctx
*ac
);
1895 static int samldb_prim_group_change_6(struct samldb_ctx
*ac
);
1897 static int samldb_prim_group_change_3(struct samldb_ctx
*ac
)
1901 if (ac
->res_dn
!= NULL
)
1902 ac
->old_prim_group_dn
= ac
->res_dn
;
1904 return LDB_ERR_UNWILLING_TO_PERFORM
;
1906 /* Only update when the primary group changed */
1907 if (ldb_dn_compare(ac
->old_prim_group_dn
, ac
->new_prim_group_dn
) != 0) {
1908 ac
->member_dn
= ac
->user_dn
;
1909 /* Remove the "member" attribute of the actual (new) primary
1912 ret
= samldb_add_step(ac
, samldb_prim_group_change_4
);
1913 if (ret
!= LDB_SUCCESS
) return ret
;
1915 ret
= samldb_add_step(ac
, samldb_group_del_member
);
1916 if (ret
!= LDB_SUCCESS
) return ret
;
1918 /* Add a "member" attribute for the previous primary group */
1920 ret
= samldb_add_step(ac
, samldb_prim_group_change_5
);
1921 if (ret
!= LDB_SUCCESS
) return ret
;
1923 ret
= samldb_add_step(ac
, samldb_group_add_member
);
1924 if (ret
!= LDB_SUCCESS
) return ret
;
1927 ret
= samldb_add_step(ac
, samldb_prim_group_change_6
);
1928 if (ret
!= LDB_SUCCESS
) return ret
;
1930 return samldb_next_step(ac
);
1933 static int samldb_prim_group_change_4(struct samldb_ctx
*ac
)
1935 ac
->group_dn
= ac
->new_prim_group_dn
;
1937 return samldb_next_step(ac
);
1940 static int samldb_prim_group_change_5(struct samldb_ctx
*ac
)
1942 ac
->group_dn
= ac
->old_prim_group_dn
;
1944 return samldb_next_step(ac
);
1947 static int samldb_prim_group_change_6(struct samldb_ctx
*ac
)
1949 return ldb_next_request(ac
->module
, ac
->req
);
1952 static int samldb_prim_group_change(struct samldb_ctx
*ac
)
1956 /* Finds out the DN of the new primary group */
1958 ret
= samldb_add_step(ac
, samldb_prim_group_change_1
);
1959 if (ret
!= LDB_SUCCESS
) return ret
;
1961 ret
= samldb_add_step(ac
, samldb_dn_from_sid
);
1962 if (ret
!= LDB_SUCCESS
) return ret
;
1964 ret
= samldb_add_step(ac
, samldb_user_dn_to_prim_group_rid
);
1965 if (ret
!= LDB_SUCCESS
) return ret
;
1967 /* Finds out the DN of the old primary group */
1969 ret
= samldb_add_step(ac
, samldb_prim_group_change_2
);
1970 if (ret
!= LDB_SUCCESS
) return ret
;
1972 ret
= samldb_add_step(ac
, samldb_dn_from_sid
);
1973 if (ret
!= LDB_SUCCESS
) return ret
;
1975 ret
= samldb_add_step(ac
, samldb_prim_group_change_3
);
1976 if (ret
!= LDB_SUCCESS
) return ret
;
1978 return samldb_first_step(ac
);
1982 static int samldb_member_check_1(struct samldb_ctx
*ac
)
1984 struct ldb_context
*ldb
;
1985 struct ldb_message_element
*el
;
1987 ldb
= ldb_module_get_ctx(ac
->module
);
1989 el
= ldb_msg_find_element(ac
->msg
, "member");
1991 ac
->user_dn
= ldb_dn_from_ldb_val(ac
, ldb
, &el
->values
[ac
->cnt
]);
1992 if (!ldb_dn_validate(ac
->user_dn
))
1993 return LDB_ERR_OPERATIONS_ERROR
;
1994 ac
->prim_group_rid
= 0;
1996 return samldb_next_step(ac
);
1999 static int samldb_member_check_2(struct samldb_ctx
*ac
)
2001 struct ldb_context
*ldb
;
2003 ldb
= ldb_module_get_ctx(ac
->module
);
2005 ac
->sid
= dom_sid_add_rid(ac
, samdb_domain_sid(ldb
),
2006 ac
->prim_group_rid
);
2007 if (ac
->sid
== NULL
)
2008 return LDB_ERR_OPERATIONS_ERROR
;
2011 return samldb_next_step(ac
);
2014 static int samldb_member_check_3(struct samldb_ctx
*ac
)
2016 if (ldb_dn_compare(ac
->res_dn
, ac
->msg
->dn
) == 0)
2017 return LDB_ERR_ENTRY_ALREADY_EXISTS
;
2021 return samldb_next_step(ac
);
2024 static int samldb_member_check_4(struct samldb_ctx
*ac
)
2026 return ldb_next_request(ac
->module
, ac
->req
);
2029 static int samldb_member_check(struct samldb_ctx
*ac
)
2031 struct ldb_message_element
*el
;
2034 el
= ldb_msg_find_element(ac
->msg
, "member");
2036 for (i
= 0; i
< el
->num_values
; i
++) {
2037 /* Denies to add "member"s to groups which are primary ones
2039 ret
= samldb_add_step(ac
, samldb_member_check_1
);
2040 if (ret
!= LDB_SUCCESS
) return ret
;
2042 ret
= samldb_add_step(ac
, samldb_user_dn_to_prim_group_rid
);
2043 if (ret
!= LDB_SUCCESS
) return ret
;
2045 ret
= samldb_add_step(ac
, samldb_member_check_2
);
2046 if (ret
!= LDB_SUCCESS
) return ret
;
2048 ret
= samldb_add_step(ac
, samldb_dn_from_sid
);
2049 if (ret
!= LDB_SUCCESS
) return ret
;
2051 ret
= samldb_add_step(ac
, samldb_member_check_3
);
2052 if (ret
!= LDB_SUCCESS
) return ret
;
2055 ret
= samldb_add_step(ac
, samldb_member_check_4
);
2056 if (ret
!= LDB_SUCCESS
) return ret
;
2058 return samldb_first_step(ac
);
2062 static int samldb_prim_group_users_check_1(struct samldb_ctx
*ac
)
2064 ac
->dn
= ac
->req
->op
.del
.dn
;
2067 return samldb_next_step(ac
);
2070 static int samldb_prim_group_users_check_2(struct samldb_ctx
*ac
)
2075 if (ac
->res_sid
== NULL
) {
2076 /* No SID - therefore ok here */
2077 return ldb_next_request(ac
->module
, ac
->req
);
2079 status
= dom_sid_split_rid(ac
, ac
->res_sid
, NULL
, &rid
);
2080 if (!NT_STATUS_IS_OK(status
))
2081 return LDB_ERR_OPERATIONS_ERROR
;
2084 /* Special object (security principal?) */
2085 return ldb_next_request(ac
->module
, ac
->req
);
2088 ac
->prim_group_rid
= rid
;
2091 return samldb_next_step(ac
);
2094 static int samldb_prim_group_users_check_3(struct samldb_ctx
*ac
)
2096 if (ac
->users_cnt
> 0)
2097 return LDB_ERR_ENTRY_ALREADY_EXISTS
;
2099 return ldb_next_request(ac
->module
, ac
->req
);
2102 static int samldb_prim_group_users_check(struct samldb_ctx
*ac
)
2106 /* Finds out the SID/RID of the domain object */
2108 ret
= samldb_add_step(ac
, samldb_prim_group_users_check_1
);
2109 if (ret
!= LDB_SUCCESS
) return ret
;
2111 ret
= samldb_add_step(ac
, samldb_sid_from_dn
);
2112 if (ret
!= LDB_SUCCESS
) return ret
;
2114 /* Deny delete requests from groups which are primary ones */
2116 ret
= samldb_add_step(ac
, samldb_prim_group_users_check_2
);
2117 if (ret
!= LDB_SUCCESS
) return ret
;
2119 ret
= samldb_add_step(ac
, samldb_prim_group_rid_to_users_cnt
);
2120 if (ret
!= LDB_SUCCESS
) return ret
;
2122 ret
= samldb_add_step(ac
, samldb_prim_group_users_check_3
);
2123 if (ret
!= LDB_SUCCESS
) return ret
;
2125 return samldb_first_step(ac
);
2130 static int samldb_add(struct ldb_module
*module
, struct ldb_request
*req
)
2132 struct ldb_context
*ldb
;
2133 struct samldb_ctx
*ac
;
2136 ldb
= ldb_module_get_ctx(module
);
2137 ldb_debug(ldb
, LDB_DEBUG_TRACE
, "samldb_add\n");
2139 /* do not manipulate our control entries */
2140 if (ldb_dn_is_special(req
->op
.add
.message
->dn
)) {
2141 return ldb_next_request(module
, req
);
2144 ac
= samldb_ctx_init(module
, req
);
2146 return LDB_ERR_OPERATIONS_ERROR
;
2149 /* build the new msg */
2150 ac
->msg
= ldb_msg_copy(ac
, ac
->req
->op
.add
.message
);
2153 ldb_debug(ldb
, LDB_DEBUG_FATAL
,
2154 "samldb_add: ldb_msg_copy failed!\n");
2155 return LDB_ERR_OPERATIONS_ERROR
;
2158 if (samdb_find_attribute(ldb
, ac
->msg
,
2159 "objectclass", "computer") != NULL
) {
2161 /* make sure the computer object also has the 'user'
2162 * objectclass so it will be handled by the next call */
2163 ret
= samdb_find_or_add_value(ldb
, ac
->msg
,
2164 "objectclass", "user");
2165 if (ret
!= LDB_SUCCESS
) {
2171 if (samdb_find_attribute(ldb
, ac
->msg
,
2172 "objectclass", "user") != NULL
) {
2174 ret
= samldb_check_rdn(module
, ac
->req
->op
.add
.message
->dn
);
2175 if (ret
!= LDB_SUCCESS
) {
2180 return samldb_fill_object(ac
, "user");
2183 if (samdb_find_attribute(ldb
, ac
->msg
,
2184 "objectclass", "group") != NULL
) {
2186 ret
= samldb_check_rdn(module
, ac
->req
->op
.add
.message
->dn
);
2187 if (ret
!= LDB_SUCCESS
) {
2192 return samldb_fill_object(ac
, "group");
2195 /* perhaps a foreignSecurityPrincipal? */
2196 if (samdb_find_attribute(ldb
, ac
->msg
,
2198 "foreignSecurityPrincipal") != NULL
) {
2200 ret
= samldb_check_rdn(module
, ac
->req
->op
.add
.message
->dn
);
2201 if (ret
!= LDB_SUCCESS
) {
2206 return samldb_fill_foreignSecurityPrincipal_object(ac
);
2209 if (samdb_find_attribute(ldb
, ac
->msg
,
2210 "objectclass", "classSchema") != NULL
) {
2212 ret
= samldb_check_rdn(module
, ac
->req
->op
.add
.message
->dn
);
2213 if (ret
!= LDB_SUCCESS
) {
2218 return samldb_fill_object(ac
, "classSchema");
2221 if (samdb_find_attribute(ldb
, ac
->msg
,
2222 "objectclass", "attributeSchema") != NULL
) {
2224 ret
= samldb_check_rdn(module
, ac
->req
->op
.add
.message
->dn
);
2225 if (ret
!= LDB_SUCCESS
) {
2230 return samldb_fill_object(ac
, "attributeSchema");
2235 /* nothing matched, go on */
2236 return ldb_next_request(module
, req
);
2240 static int samldb_modify(struct ldb_module
*module
, struct ldb_request
*req
)
2242 struct ldb_context
*ldb
;
2243 struct ldb_message
*msg
;
2244 struct ldb_message_element
*el
, *el2
;
2246 uint32_t account_type
;
2248 if (ldb_dn_is_special(req
->op
.mod
.message
->dn
)) {
2249 /* do not manipulate our control entries */
2250 return ldb_next_request(module
, req
);
2253 ldb
= ldb_module_get_ctx(module
);
2255 if (ldb_msg_find_element(req
->op
.mod
.message
, "sAMAccountType") != NULL
) {
2256 ldb_asprintf_errstring(ldb
,
2257 "sAMAccountType must not be specified!");
2258 return LDB_ERR_UNWILLING_TO_PERFORM
;
2261 /* TODO: do not modify original request, create a new one */
2263 el
= ldb_msg_find_element(req
->op
.mod
.message
, "groupType");
2264 if (el
&& el
->flags
& (LDB_FLAG_MOD_ADD
|LDB_FLAG_MOD_REPLACE
) && el
->num_values
== 1) {
2265 uint32_t group_type
;
2267 req
->op
.mod
.message
= msg
= ldb_msg_copy_shallow(req
,
2268 req
->op
.mod
.message
);
2270 group_type
= strtoul((const char *)el
->values
[0].data
, NULL
, 0);
2271 account_type
= ds_gtype2atype(group_type
);
2272 ret
= samdb_msg_add_uint(ldb
, msg
, msg
,
2275 if (ret
!= LDB_SUCCESS
) {
2278 el2
= ldb_msg_find_element(msg
, "sAMAccountType");
2279 el2
->flags
= LDB_FLAG_MOD_REPLACE
;
2282 el
= ldb_msg_find_element(req
->op
.mod
.message
, "userAccountControl");
2283 if (el
&& el
->flags
& (LDB_FLAG_MOD_ADD
|LDB_FLAG_MOD_REPLACE
) && el
->num_values
== 1) {
2284 uint32_t user_account_control
;
2286 req
->op
.mod
.message
= msg
= ldb_msg_copy_shallow(req
,
2287 req
->op
.mod
.message
);
2289 user_account_control
= strtoul((const char *)el
->values
[0].data
,
2291 account_type
= ds_uf2atype(user_account_control
);
2292 ret
= samdb_msg_add_uint(ldb
, msg
, msg
,
2295 if (ret
!= LDB_SUCCESS
) {
2298 el2
= ldb_msg_find_element(msg
, "sAMAccountType");
2299 el2
->flags
= LDB_FLAG_MOD_REPLACE
;
2301 if (user_account_control
& UF_SERVER_TRUST_ACCOUNT
) {
2302 ret
= samdb_msg_add_string(ldb
, msg
, msg
,
2303 "isCriticalSystemObject", "TRUE");
2304 if (ret
!= LDB_SUCCESS
) {
2307 el2
= ldb_msg_find_element(msg
, "isCriticalSystemObject");
2308 el2
->flags
= LDB_FLAG_MOD_REPLACE
;
2312 el
= ldb_msg_find_element(req
->op
.mod
.message
, "primaryGroupID");
2313 if (el
&& el
->flags
& (LDB_FLAG_MOD_ADD
|LDB_FLAG_MOD_REPLACE
) && el
->num_values
== 1) {
2314 struct samldb_ctx
*ac
;
2316 ac
= samldb_ctx_init(module
, req
);
2318 return LDB_ERR_OPERATIONS_ERROR
;
2320 req
->op
.mod
.message
= ac
->msg
= ldb_msg_copy_shallow(req
,
2321 req
->op
.mod
.message
);
2323 return samldb_prim_group_change(ac
);
2326 el
= ldb_msg_find_element(req
->op
.mod
.message
, "member");
2327 if (el
&& el
->flags
& (LDB_FLAG_MOD_ADD
|LDB_FLAG_MOD_REPLACE
) && el
->num_values
== 1) {
2328 struct samldb_ctx
*ac
;
2330 ac
= samldb_ctx_init(module
, req
);
2332 return LDB_ERR_OPERATIONS_ERROR
;
2334 req
->op
.mod
.message
= ac
->msg
= ldb_msg_copy_shallow(req
,
2335 req
->op
.mod
.message
);
2337 return samldb_member_check(ac
);
2340 /* nothing matched, go on */
2341 return ldb_next_request(module
, req
);
2345 static int samldb_delete(struct ldb_module
*module
, struct ldb_request
*req
)
2347 struct samldb_ctx
*ac
;
2349 if (ldb_dn_is_special(req
->op
.del
.dn
)) {
2350 /* do not manipulate our control entries */
2351 return ldb_next_request(module
, req
);
2354 ac
= samldb_ctx_init(module
, req
);
2356 return LDB_ERR_OPERATIONS_ERROR
;
2358 return samldb_prim_group_users_check(ac
);
2362 static int samldb_init(struct ldb_module
*module
)
2364 return ldb_next_init(module
);
2367 _PUBLIC_
const struct ldb_module_ops ldb_samldb_module_ops
= {
2369 .init_context
= samldb_init
,
2371 .modify
= samldb_modify
,
2372 .del
= samldb_delete