2 Unix SMB/CIFS implementation.
3 pdb glue module for direct access to the dsdb via LDB APIs
4 Copyright (C) Volker Lendecke 2009-2011
5 Copyright (C) Andrew Bartlett 2010-2012
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/>.
22 /* This module, is a port of Volker's pdb_ads to ldb and DSDB APIs */
25 #include "source3/include/passdb.h"
26 #include "source4/dsdb/samdb/samdb.h"
27 #include "ldb_errors.h"
28 #include "libcli/security/dom_sid.h"
29 #include "source4/winbind/idmap.h"
30 #include "librpc/gen_ndr/ndr_security.h"
31 #include "libds/common/flag_mapping.h"
32 #include "source4/lib/events/events.h"
33 #include "source4/auth/session.h"
34 #include "source4/auth/system_session_proto.h"
35 #include "lib/param/param.h"
36 #include "source4/dsdb/common/util.h"
37 #include "source3/include/secrets.h"
39 struct pdb_samba_dsdb_state
{
40 struct tevent_context
*ev
;
41 struct ldb_context
*ldb
;
42 struct idmap_context
*idmap_ctx
;
43 struct loadparm_context
*lp_ctx
;
46 static NTSTATUS
pdb_samba_dsdb_getsampwsid(struct pdb_methods
*m
,
47 struct samu
*sam_acct
,
48 const struct dom_sid
*sid
);
49 static NTSTATUS
pdb_samba_dsdb_getsamupriv(struct pdb_samba_dsdb_state
*state
,
52 struct ldb_message
**pmsg
);
53 static bool pdb_samba_dsdb_sid_to_id(struct pdb_methods
*m
, const struct dom_sid
*sid
,
56 static bool pdb_samba_dsdb_pull_time(struct ldb_message
*msg
, const char *attr
,
60 if (! ldb_msg_find_element(msg
, attr
)) {
63 tmp
= ldb_msg_find_attr_as_uint64(msg
, attr
, 0);
64 *ptime
= nt_time_to_unix(tmp
);
68 static struct pdb_domain_info
*pdb_samba_dsdb_get_domain_info(
69 struct pdb_methods
*m
, TALLOC_CTX
*mem_ctx
)
71 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
72 m
->private_data
, struct pdb_samba_dsdb_state
);
73 struct pdb_domain_info
*info
;
74 struct dom_sid
*domain_sid
;
75 struct ldb_dn
*forest_dn
, *domain_dn
;
76 struct ldb_result
*dom_res
= NULL
;
77 const char *dom_attrs
[] = {
86 info
= talloc(mem_ctx
, struct pdb_domain_info
);
91 domain_dn
= ldb_get_default_basedn(state
->ldb
);
93 ret
= ldb_search(state
->ldb
, info
, &dom_res
,
94 domain_dn
, LDB_SCOPE_BASE
, dom_attrs
, NULL
);
95 if (ret
!= LDB_SUCCESS
) {
98 if (dom_res
->count
!= 1) {
102 info
->guid
= samdb_result_guid(dom_res
->msgs
[0], "objectGUID");
104 domain_sid
= samdb_result_dom_sid(state
, dom_res
->msgs
[0], "objectSid");
108 info
->sid
= *domain_sid
;
110 TALLOC_FREE(dom_res
);
112 info
->name
= talloc_strdup(info
, lpcfg_sam_name(state
->lp_ctx
));
113 info
->dns_domain
= ldb_dn_canonical_string(info
, domain_dn
);
115 if (!info
->dns_domain
) {
118 p
= strchr(info
->dns_domain
, '/');
123 forest_dn
= ldb_get_root_basedn(state
->ldb
);
128 info
->dns_forest
= ldb_dn_canonical_string(info
, forest_dn
);
129 if (!info
->dns_forest
) {
132 p
= strchr(info
->dns_forest
, '/');
140 TALLOC_FREE(dom_res
);
145 static struct ldb_message
*pdb_samba_dsdb_get_samu_private(
146 struct pdb_methods
*m
, struct samu
*sam
)
148 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
149 m
->private_data
, struct pdb_samba_dsdb_state
);
150 struct ldb_message
*msg
;
151 char *sidstr
, *filter
;
154 msg
= (struct ldb_message
*)
155 pdb_get_backend_private_data(sam
, m
);
158 return talloc_get_type_abort(msg
, struct ldb_message
);
161 sidstr
= dom_sid_string(talloc_tos(), pdb_get_user_sid(sam
));
162 if (sidstr
== NULL
) {
166 filter
= talloc_asprintf(
167 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr
);
169 if (filter
== NULL
) {
173 status
= pdb_samba_dsdb_getsamupriv(state
, filter
, sam
, &msg
);
175 if (!NT_STATUS_IS_OK(status
)) {
182 static NTSTATUS
pdb_samba_dsdb_init_sam_from_priv(struct pdb_methods
*m
,
184 struct ldb_message
*msg
)
186 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
187 m
->private_data
, struct pdb_samba_dsdb_state
);
188 TALLOC_CTX
*frame
= talloc_stackframe();
189 NTSTATUS status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
192 struct dom_sid
*sid
, group_sid
;
194 const DATA_BLOB
*blob
;
196 str
= ldb_msg_find_attr_as_string(msg
, "samAccountName", NULL
);
198 DEBUG(10, ("no samAccountName\n"));
201 pdb_set_username(sam
, str
, PDB_SET
);
203 if (pdb_samba_dsdb_pull_time(msg
, "lastLogon", &tmp_time
)) {
204 pdb_set_logon_time(sam
, tmp_time
, PDB_SET
);
206 if (pdb_samba_dsdb_pull_time(msg
, "lastLogoff", &tmp_time
)) {
207 pdb_set_logoff_time(sam
, tmp_time
, PDB_SET
);
209 if (pdb_samba_dsdb_pull_time(msg
, "pwdLastSet", &tmp_time
)) {
210 pdb_set_pass_last_set_time(sam
, tmp_time
, PDB_SET
);
212 if (pdb_samba_dsdb_pull_time(msg
, "accountExpires", &tmp_time
)) {
213 pdb_set_kickoff_time(sam
, tmp_time
, PDB_SET
);
216 str
= ldb_msg_find_attr_as_string(msg
, "displayName",
219 pdb_set_fullname(sam
, str
, PDB_SET
);
222 str
= ldb_msg_find_attr_as_string(msg
, "homeDirectory",
225 pdb_set_homedir(sam
, str
, PDB_SET
);
228 str
= ldb_msg_find_attr_as_string(msg
, "homeDrive", NULL
);
230 pdb_set_dir_drive(sam
, str
, PDB_SET
);
233 str
= ldb_msg_find_attr_as_string(msg
, "scriptPath", NULL
);
235 pdb_set_logon_script(sam
, str
, PDB_SET
);
238 str
= ldb_msg_find_attr_as_string(msg
, "profilePath",
241 pdb_set_profile_path(sam
, str
, PDB_SET
);
244 str
= ldb_msg_find_attr_as_string(msg
, "comment",
247 pdb_set_comment(sam
, str
, PDB_SET
);
250 str
= ldb_msg_find_attr_as_string(msg
, "description",
253 pdb_set_acct_desc(sam
, str
, PDB_SET
);
256 str
= ldb_msg_find_attr_as_string(msg
, "userWorkstations",
259 pdb_set_workstations(sam
, str
, PDB_SET
);
262 str
= ldb_msg_find_attr_as_string(msg
, "userParameters",
265 pdb_set_munged_dial(sam
, str
, PDB_SET
);
268 sid
= samdb_result_dom_sid(talloc_tos(), msg
, "objectSid");
270 DEBUG(10, ("Could not pull SID\n"));
273 pdb_set_user_sid(sam
, sid
, PDB_SET
);
275 n
= ldb_msg_find_attr_as_uint(msg
, "userAccountControl", 0);
277 DEBUG(10, ("Could not pull userAccountControl\n"));
280 pdb_set_acct_ctrl(sam
, ds_uf2acb(n
), PDB_SET
);
282 blob
= ldb_msg_find_ldb_val(msg
, "unicodePwd");
284 if (blob
->length
!= NT_HASH_LEN
) {
285 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
286 (int)blob
->length
, NT_HASH_LEN
));
289 pdb_set_nt_passwd(sam
, blob
->data
, PDB_SET
);
292 blob
= ldb_msg_find_ldb_val(msg
, "dBCSPwd");
294 if (blob
->length
!= LM_HASH_LEN
) {
295 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
296 (int)blob
->length
, LM_HASH_LEN
));
299 pdb_set_lanman_passwd(sam
, blob
->data
, PDB_SET
);
302 n
= ldb_msg_find_attr_as_uint(msg
, "primaryGroupID", 0);
304 DEBUG(10, ("Could not pull primaryGroupID\n"));
307 sid_compose(&group_sid
, samdb_domain_sid(state
->ldb
), n
);
308 pdb_set_group_sid(sam
, &group_sid
, PDB_SET
);
310 status
= NT_STATUS_OK
;
316 static bool pdb_samba_dsdb_add_time(struct ldb_message
*msg
,
317 const char *attrib
, time_t t
)
321 unix_to_nt_time(&nt_time
, t
);
323 return ldb_msg_add_fmt(msg
, attrib
, "%llu", (unsigned long long) nt_time
);
326 static int pdb_samba_dsdb_replace_by_sam(struct pdb_samba_dsdb_state
*state
,
327 bool (*need_update
)(const struct samu
*,
332 TALLOC_CTX
*frame
= talloc_stackframe();
333 int ret
= LDB_SUCCESS
;
335 struct ldb_message
*msg
;
336 struct ldb_request
*req
;
337 uint32_t dsdb_flags
= 0;
338 /* TODO: All fields :-) */
340 msg
= ldb_msg_new(frame
);
347 /* build modify request */
348 ret
= ldb_build_mod_req(&req
, state
->ldb
, frame
, msg
, NULL
, NULL
,
349 ldb_op_default_callback
,
351 if (ret
!= LDB_SUCCESS
) {
356 /* If we set a plaintext password, the system will
357 * force the pwdLastSet to now() */
358 if (need_update(sam
, PDB_PASSLASTSET
)) {
359 dsdb_flags
= DSDB_PASSWORD_BYPASS_LAST_SET
;
361 ret
|= pdb_samba_dsdb_add_time(msg
, "pwdLastSet",
362 pdb_get_pass_last_set_time(sam
));
365 pw
= pdb_get_plaintext_passwd(sam
);
366 if (need_update(sam
, PDB_PLAINTEXT_PW
)) {
367 struct ldb_val pw_utf16
;
370 return LDB_ERR_OPERATIONS_ERROR
;
373 if (!convert_string_talloc(msg
,
376 (void *)&pw_utf16
.data
,
378 return LDB_ERR_OPERATIONS_ERROR
;
380 ret
|= ldb_msg_add_value(msg
, "clearTextPassword", &pw_utf16
, NULL
);
382 bool changed_lm_pw
= false;
383 bool changed_nt_pw
= false;
384 bool changed_history
= false;
385 if (need_update(sam
, PDB_LMPASSWD
)) {
387 val
.data
= discard_const_p(uint8_t, pdb_get_lanman_passwd(sam
));
389 samdb_msg_add_delete(state
->ldb
, msg
, msg
,
392 val
.length
= LM_HASH_LEN
;
393 ret
|= ldb_msg_add_value(msg
, "dBCSPwd", &val
, NULL
);
395 changed_lm_pw
= true;
397 if (need_update(sam
, PDB_NTPASSWD
)) {
399 val
.data
= discard_const_p(uint8_t, pdb_get_nt_passwd(sam
));
401 samdb_msg_add_delete(state
->ldb
, msg
, msg
,
404 val
.length
= NT_HASH_LEN
;
405 ret
|= ldb_msg_add_value(msg
, "unicodePwd", &val
, NULL
);
407 changed_nt_pw
= true;
410 /* Try to ensure we don't get out of sync */
411 if (changed_lm_pw
&& !changed_nt_pw
) {
412 samdb_msg_add_delete(state
->ldb
, msg
, msg
,
414 } else if (changed_nt_pw
&& !changed_lm_pw
) {
415 samdb_msg_add_delete(state
->ldb
, msg
, msg
,
418 if (changed_lm_pw
|| changed_nt_pw
) {
419 samdb_msg_add_delete(state
->ldb
, msg
, msg
,
420 "supplementalCredentials");
424 if (need_update(sam
, PDB_PWHISTORY
)) {
425 uint32_t current_hist_len
;
426 const uint8_t *history
= pdb_get_pw_history(sam
, ¤t_hist_len
);
428 bool invalid_history
= false;
429 struct samr_Password
*history_hashes
= talloc_array(talloc_tos(), struct samr_Password
,
432 invalid_history
= true;
435 static const uint8_t zeros
[16];
436 /* Parse the history into the correct format */
437 for (i
= 0; i
< current_hist_len
; i
++) {
438 if (memcmp(&history
[i
*PW_HISTORY_ENTRY_LEN
], zeros
, 16) != 0) {
439 /* If the history is in the old format, with a salted hash, then we can't migrate it to AD format */
440 invalid_history
= true;
443 /* Copy out the 2nd 16 bytes of the 32 byte password history, containing the NT hash */
444 memcpy(history_hashes
[i
].hash
,
445 &history
[(i
*PW_HISTORY_ENTRY_LEN
) + PW_HISTORY_SALT_LEN
],
446 sizeof(history_hashes
[i
].hash
));
449 if (invalid_history
) {
450 ret
|= samdb_msg_add_delete(state
->ldb
, msg
, msg
,
453 ret
|= samdb_msg_add_delete(state
->ldb
, msg
, msg
,
456 ret
|= samdb_msg_add_hashes(state
->ldb
, msg
, msg
,
461 changed_history
= true;
463 if (changed_lm_pw
|| changed_nt_pw
|| changed_history
) {
464 /* These attributes can only be modified directly by using a special control */
465 dsdb_flags
= DSDB_BYPASS_PASSWORD_HASH
;
469 /* PDB_USERSID is only allowed on ADD, handled in caller */
470 if (need_update(sam
, PDB_GROUPSID
)) {
471 const struct dom_sid
*sid
= pdb_get_group_sid(sam
);
473 NTSTATUS status
= dom_sid_split_rid(NULL
, sid
, NULL
, &rid
);
474 if (!NT_STATUS_IS_OK(status
)) {
476 return LDB_ERR_OPERATIONS_ERROR
;
478 if (!dom_sid_in_domain(samdb_domain_sid(state
->ldb
), sid
)) {
480 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
482 ret
|= samdb_msg_add_uint(state
->ldb
, msg
, msg
, "primaryGroupID", rid
);
484 if (need_update(sam
, PDB_FULLNAME
)) {
485 ret
|= ldb_msg_add_string(msg
, "displayName", pdb_get_fullname(sam
));
488 if (need_update(sam
, PDB_SMBHOME
)) {
489 ret
|= ldb_msg_add_string(msg
, "homeDirectory",
490 pdb_get_homedir(sam
));
493 if (need_update(sam
, PDB_PROFILE
)) {
494 ret
|= ldb_msg_add_string(msg
, "profilePath",
495 pdb_get_profile_path(sam
));
498 if (need_update(sam
, PDB_DRIVE
)) {
499 ret
|= ldb_msg_add_string(msg
, "homeDrive",
500 pdb_get_dir_drive(sam
));
503 if (need_update(sam
, PDB_LOGONSCRIPT
)) {
504 ret
|= ldb_msg_add_string(msg
, "scriptPath",
505 pdb_get_logon_script(sam
));
508 if (need_update(sam
, PDB_KICKOFFTIME
)) {
509 ret
|= pdb_samba_dsdb_add_time(msg
, "accountExpires",
510 pdb_get_kickoff_time(sam
));
513 if (need_update(sam
, PDB_LOGONTIME
)) {
514 ret
|= pdb_samba_dsdb_add_time(msg
, "lastLogon",
515 pdb_get_logon_time(sam
));
518 if (need_update(sam
, PDB_LOGOFFTIME
)) {
519 ret
|= pdb_samba_dsdb_add_time(msg
, "lastLogoff",
520 pdb_get_logoff_time(sam
));
523 if (need_update(sam
, PDB_USERNAME
)) {
524 ret
|= ldb_msg_add_string(msg
, "samAccountName",
525 pdb_get_username(sam
));
528 if (need_update(sam
, PDB_HOURSLEN
) || need_update(sam
, PDB_HOURS
)) {
529 struct ldb_val hours
= data_blob_const(pdb_get_hours(sam
), pdb_get_hours_len(sam
));
530 ret
|= ldb_msg_add_value(msg
, "logonHours",
534 if (need_update(sam
, PDB_ACCTCTRL
)) {
535 ret
|= samdb_msg_add_acct_flags(state
->ldb
, msg
, msg
,
536 "userAccountControl", pdb_get_acct_ctrl(sam
));
539 if (need_update(sam
, PDB_COMMENT
)) {
540 ret
|= ldb_msg_add_string(msg
, "comment",
541 pdb_get_comment(sam
));
544 if (need_update(sam
, PDB_ACCTDESC
)) {
545 ret
|= ldb_msg_add_string(msg
, "description",
546 pdb_get_acct_desc(sam
));
549 if (need_update(sam
, PDB_WORKSTATIONS
)) {
550 ret
|= ldb_msg_add_string(msg
, "userWorkstations",
551 pdb_get_workstations(sam
));
554 /* This will need work, it is actually a UTF8 'string' with internal NULLs, to handle TS parameters */
555 if (need_update(sam
, PDB_MUNGEDDIAL
)) {
556 ret
|= ldb_msg_add_string(msg
, "userParameters",
557 pdb_get_munged_dial(sam
));
560 if (need_update(sam
, PDB_COUNTRY_CODE
)) {
561 ret
|= ldb_msg_add_fmt(msg
, "countryCode",
562 "%i", (int)pdb_get_country_code(sam
));
565 if (need_update(sam
, PDB_CODE_PAGE
)) {
566 ret
|= ldb_msg_add_fmt(msg
, "codePage",
567 "%i", (int)pdb_get_code_page(sam
));
570 /* Not yet handled here or not meaningful for modifies on a Samba_Dsdb backend:
571 PDB_BAD_PASSWORD_TIME,
572 PDB_CANCHANGETIME, - these are calculated per policy, not stored
574 PDB_NTUSERNAME, - this makes no sense, and never really did
576 PDB_USERSID, - Handled in pdb_samba_dsdb_add_sam_account()
578 PDB_BAD_PASSWORD_COUNT,
581 PDB_BACKEND_PRIVATE_DATA,
584 if (ret
!= LDB_SUCCESS
) {
586 return LDB_ERR_OPERATIONS_ERROR
;
589 if (msg
->num_elements
== 0) {
591 /* Nothing to do, just return success */
595 ret
= dsdb_replace(state
->ldb
, msg
, dsdb_flags
);
597 if (ret
!= LDB_SUCCESS
) {
598 DEBUG(0,("Failed to modify account record %s to set user attributes: %s\n",
599 ldb_dn_get_linearized(msg
->dn
),
600 ldb_errstring(state
->ldb
)));
607 static NTSTATUS
pdb_samba_dsdb_getsamupriv(struct pdb_samba_dsdb_state
*state
,
610 struct ldb_message
**msg
)
612 const char * attrs
[] = {
613 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
614 "sAMAccountName", "displayName", "homeDirectory",
615 "homeDrive", "scriptPath", "profilePath", "description",
616 "userWorkstations", "comment", "userParameters", "objectSid",
617 "primaryGroupID", "userAccountControl", "logonHours",
618 "badPwdCount", "logonCount", "countryCode", "codePage",
619 "unicodePwd", "dBCSPwd", NULL
};
621 int rc
= dsdb_search_one(state
->ldb
, mem_ctx
, msg
, ldb_get_default_basedn(state
->ldb
), LDB_SCOPE_SUBTREE
, attrs
, 0, "%s", filter
);
622 if (rc
!= LDB_SUCCESS
) {
623 DEBUG(10, ("ldap_search failed %s\n",
624 ldb_errstring(state
->ldb
)));
625 return NT_STATUS_LDAP(rc
);
631 static NTSTATUS
pdb_samba_dsdb_getsampwfilter(struct pdb_methods
*m
,
632 struct pdb_samba_dsdb_state
*state
,
633 struct samu
*sam_acct
,
634 const char *exp_fmt
, ...) _PRINTF_ATTRIBUTE(4, 5)
636 struct ldb_message
*priv
;
639 char *expression
= NULL
;
640 TALLOC_CTX
*tmp_ctx
= talloc_new(state
);
641 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
643 va_start(ap
, exp_fmt
);
644 expression
= talloc_vasprintf(tmp_ctx
, exp_fmt
, ap
);
648 talloc_free(tmp_ctx
);
649 return NT_STATUS_NO_MEMORY
;
652 status
= pdb_samba_dsdb_getsamupriv(state
, expression
, sam_acct
, &priv
);
653 talloc_free(tmp_ctx
);
654 if (!NT_STATUS_IS_OK(status
)) {
655 DEBUG(10, ("pdb_samba_dsdb_getsamupriv failed: %s\n",
660 status
= pdb_samba_dsdb_init_sam_from_priv(m
, sam_acct
, priv
);
661 if (!NT_STATUS_IS_OK(status
)) {
662 DEBUG(10, ("pdb_samba_dsdb_init_sam_from_priv failed: %s\n",
668 pdb_set_backend_private_data(sam_acct
, priv
, NULL
, m
, PDB_SET
);
672 static NTSTATUS
pdb_samba_dsdb_getsampwnam(struct pdb_methods
*m
,
673 struct samu
*sam_acct
,
674 const char *username
)
676 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
677 m
->private_data
, struct pdb_samba_dsdb_state
);
679 return pdb_samba_dsdb_getsampwfilter(m
, state
, sam_acct
,
680 "(&(samaccountname=%s)(objectclass=user))",
684 static NTSTATUS
pdb_samba_dsdb_getsampwsid(struct pdb_methods
*m
,
685 struct samu
*sam_acct
,
686 const struct dom_sid
*sid
)
689 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
690 m
->private_data
, struct pdb_samba_dsdb_state
);
693 sidstr
= dom_sid_string(talloc_tos(), sid
);
694 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
696 status
= pdb_samba_dsdb_getsampwfilter(m
, state
, sam_acct
,
697 "(&(objectsid=%s)(objectclass=user))",
703 static NTSTATUS
pdb_samba_dsdb_create_user(struct pdb_methods
*m
,
705 const char *name
, uint32 acct_flags
,
708 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
709 m
->private_data
, struct pdb_samba_dsdb_state
);
713 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
714 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
716 /* Internally this uses transactions to ensure all the steps
717 * happen or fail as one */
718 status
= dsdb_add_user(state
->ldb
, tmp_ctx
, name
, acct_flags
, NULL
,
720 if (!NT_STATUS_IS_OK(status
)) {
721 talloc_free(tmp_ctx
);
724 sid_peek_rid(sid
, rid
);
725 talloc_free(tmp_ctx
);
729 static NTSTATUS
pdb_samba_dsdb_delete_user(struct pdb_methods
*m
,
733 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
734 m
->private_data
, struct pdb_samba_dsdb_state
);
737 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
738 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
740 dn
= ldb_dn_new_fmt(tmp_ctx
, state
->ldb
, "<SID=%s>", dom_sid_string(tmp_ctx
, pdb_get_user_sid(sam
)));
741 if (!dn
|| !ldb_dn_validate(dn
)) {
742 talloc_free(tmp_ctx
);
743 return NT_STATUS_NO_MEMORY
;
745 rc
= ldb_delete(state
->ldb
, dn
);
747 if (rc
!= LDB_SUCCESS
) {
748 DEBUG(10, ("ldb_delete for %s failed: %s\n", ldb_dn_get_linearized(dn
),
749 ldb_errstring(state
->ldb
)));
750 talloc_free(tmp_ctx
);
751 return NT_STATUS_LDAP(rc
);
753 talloc_free(tmp_ctx
);
757 /* This interface takes a fully populated struct samu and places it in
758 * the database. This is not implemented at this time as we need to
759 * be careful around the creation of arbitary SIDs (ie, we must ensrue
760 * they are not left in a RID pool */
761 static NTSTATUS
pdb_samba_dsdb_add_sam_account(struct pdb_methods
*m
,
762 struct samu
*sampass
)
767 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
768 m
->private_data
, struct pdb_samba_dsdb_state
);
769 uint32_t acb_flags
= pdb_get_acct_ctrl(sampass
);
770 const char *username
= pdb_get_username(sampass
);
771 const struct dom_sid
*user_sid
= pdb_get_user_sid(sampass
);
772 TALLOC_CTX
*tframe
= talloc_stackframe();
774 acb_flags
&= (ACB_NORMAL
|ACB_WSTRUST
|ACB_SVRTRUST
|ACB_DOMTRUST
);
776 ret
= ldb_transaction_start(state
->ldb
);
777 if (ret
!= LDB_SUCCESS
) {
779 return NT_STATUS_LOCK_NOT_GRANTED
;
782 status
= dsdb_add_user(state
->ldb
, talloc_tos(), username
,
783 acb_flags
, user_sid
, NULL
, &dn
);
784 if (!NT_STATUS_IS_OK(status
)) {
785 ldb_transaction_cancel(state
->ldb
);
790 ret
= pdb_samba_dsdb_replace_by_sam(state
, pdb_element_is_set_or_changed
,
792 if (ret
!= LDB_SUCCESS
) {
793 ldb_transaction_cancel(state
->ldb
);
795 return dsdb_ldb_err_to_ntstatus(ret
);
798 ret
= ldb_transaction_commit(state
->ldb
);
799 if (ret
!= LDB_SUCCESS
) {
800 DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
801 ldb_dn_get_linearized(dn
),
802 ldb_errstring(state
->ldb
)));
804 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
811 * Update the Samba_Dsdb LDB with the changes from a struct samu.
813 * This takes care not to update elements that have not been changed
816 static NTSTATUS
pdb_samba_dsdb_update_sam_account(struct pdb_methods
*m
,
819 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
820 m
->private_data
, struct pdb_samba_dsdb_state
);
821 struct ldb_message
*msg
= pdb_samba_dsdb_get_samu_private(
825 ret
= pdb_samba_dsdb_replace_by_sam(state
, pdb_element_is_changed
, msg
->dn
,
827 return dsdb_ldb_err_to_ntstatus(ret
);
830 static NTSTATUS
pdb_samba_dsdb_delete_sam_account(struct pdb_methods
*m
,
831 struct samu
*username
)
834 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
835 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
836 status
= pdb_samba_dsdb_delete_user(m
, tmp_ctx
, username
);
837 talloc_free(tmp_ctx
);
841 static NTSTATUS
pdb_samba_dsdb_rename_sam_account(struct pdb_methods
*m
,
842 struct samu
*oldname
,
845 return NT_STATUS_NOT_IMPLEMENTED
;
848 /* This is not implemented, as this module is exptected to be used
849 * with auth_samba_dsdb, and this is responible for login counters etc
852 static NTSTATUS
pdb_samba_dsdb_update_login_attempts(struct pdb_methods
*m
,
853 struct samu
*sam_acct
,
856 return NT_STATUS_NOT_IMPLEMENTED
;
859 static NTSTATUS
pdb_samba_dsdb_getgrfilter(struct pdb_methods
*m
, GROUP_MAP
*map
,
860 const char *exp_fmt
, ...) _PRINTF_ATTRIBUTE(4, 5)
862 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
863 m
->private_data
, struct pdb_samba_dsdb_state
);
864 const char *attrs
[] = { "objectSid", "description", "samAccountName", "groupType",
866 struct ldb_message
*msg
;
868 char *expression
= NULL
;
872 struct id_map id_map
;
873 struct id_map
*id_maps
[2];
874 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
875 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
877 va_start(ap
, exp_fmt
);
878 expression
= talloc_vasprintf(tmp_ctx
, exp_fmt
, ap
);
882 talloc_free(tmp_ctx
);
883 return NT_STATUS_NO_MEMORY
;
886 rc
= dsdb_search_one(state
->ldb
, tmp_ctx
, &msg
, ldb_get_default_basedn(state
->ldb
), LDB_SCOPE_SUBTREE
, attrs
, 0, "%s", expression
);
887 if (rc
== LDB_ERR_NO_SUCH_OBJECT
) {
888 talloc_free(tmp_ctx
);
889 return NT_STATUS_NO_SUCH_GROUP
;
890 } else if (rc
!= LDB_SUCCESS
) {
891 talloc_free(tmp_ctx
);
892 DEBUG(10, ("dsdb_search_one failed %s\n",
893 ldb_errstring(state
->ldb
)));
894 return NT_STATUS_LDAP(rc
);
897 sid
= samdb_result_dom_sid(tmp_ctx
, msg
, "objectSid");
899 talloc_free(tmp_ctx
);
900 DEBUG(10, ("Could not pull SID\n"));
901 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
906 if (samdb_find_attribute(state
->ldb
, msg
, "objectClass", "group")) {
908 uint32_t grouptype
= ldb_msg_find_attr_as_uint(msg
, "groupType", 0);
910 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
:
911 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
:
912 map
->sid_name_use
= SID_NAME_ALIAS
;
914 case GTYPE_SECURITY_GLOBAL_GROUP
:
915 map
->sid_name_use
= SID_NAME_DOM_GRP
;
918 talloc_free(tmp_ctx
);
919 DEBUG(10, ("Could not pull groupType\n"));
920 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
923 map
->sid_name_use
= SID_NAME_DOM_GRP
;
927 id_maps
[0] = &id_map
;
930 status
= idmap_sids_to_xids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
931 talloc_free(tmp_ctx
);
932 if (!NT_STATUS_IS_OK(status
)) {
933 talloc_free(tmp_ctx
);
936 if (id_map
.xid
.type
== ID_TYPE_GID
|| id_map
.xid
.type
== ID_TYPE_BOTH
) {
937 map
->gid
= id_map
.xid
.id
;
939 DEBUG(1, (__location__
"Did not get GUID when mapping SID for %s", expression
));
940 talloc_free(tmp_ctx
);
941 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
943 } else if (samdb_find_attribute(state
->ldb
, msg
, "objectClass", "user")) {
944 DEBUG(1, (__location__
"Got SID_NAME_USER when searching for a group with %s", expression
));
945 talloc_free(tmp_ctx
);
946 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
949 str
= ldb_msg_find_attr_as_string(msg
, "samAccountName",
952 talloc_free(tmp_ctx
);
953 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
955 map
->nt_name
= talloc_strdup(map
, str
);
957 talloc_free(tmp_ctx
);
958 return NT_STATUS_NO_MEMORY
;
961 str
= ldb_msg_find_attr_as_string(msg
, "description",
964 map
->comment
= talloc_strdup(map
, str
);
966 map
->comment
= talloc_strdup(map
, "");
969 talloc_free(tmp_ctx
);
970 return NT_STATUS_NO_MEMORY
;
973 talloc_free(tmp_ctx
);
977 static NTSTATUS
pdb_samba_dsdb_getgrsid(struct pdb_methods
*m
, GROUP_MAP
*map
,
983 filter
= talloc_asprintf(talloc_tos(),
984 "(&(objectsid=%s)(objectclass=group))",
985 sid_string_talloc(talloc_tos(), &sid
));
986 if (filter
== NULL
) {
987 return NT_STATUS_NO_MEMORY
;
990 status
= pdb_samba_dsdb_getgrfilter(m
, map
, filter
);
995 static NTSTATUS
pdb_samba_dsdb_getgrgid(struct pdb_methods
*m
, GROUP_MAP
*map
,
998 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
999 m
->private_data
, struct pdb_samba_dsdb_state
);
1001 struct id_map id_map
;
1002 struct id_map
*id_maps
[2];
1003 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1004 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1006 id_map
.xid
.id
= gid
;
1007 id_map
.xid
.type
= ID_TYPE_GID
;
1008 id_maps
[0] = &id_map
;
1011 status
= idmap_xids_to_sids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
1012 if (!NT_STATUS_IS_OK(status
)) {
1015 status
= pdb_samba_dsdb_getgrsid(m
, map
, *id_map
.sid
);
1016 talloc_free(tmp_ctx
);
1020 static NTSTATUS
pdb_samba_dsdb_getgrnam(struct pdb_methods
*m
, GROUP_MAP
*map
,
1026 filter
= talloc_asprintf(talloc_tos(),
1027 "(&(samaccountname=%s)(objectclass=group))",
1029 if (filter
== NULL
) {
1030 return NT_STATUS_NO_MEMORY
;
1033 status
= pdb_samba_dsdb_getgrfilter(m
, map
, filter
);
1034 TALLOC_FREE(filter
);
1038 static NTSTATUS
pdb_samba_dsdb_create_dom_group(struct pdb_methods
*m
,
1039 TALLOC_CTX
*mem_ctx
, const char *name
,
1042 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1043 m
->private_data
, struct pdb_samba_dsdb_state
);
1045 struct dom_sid
*sid
;
1047 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1048 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1050 status
= dsdb_add_domain_group(state
->ldb
, tmp_ctx
, name
, &sid
, &dn
);
1051 if (!NT_STATUS_IS_OK(status
)) {
1052 talloc_free(tmp_ctx
);
1056 sid_peek_rid(sid
, rid
);
1057 talloc_free(tmp_ctx
);
1058 return NT_STATUS_OK
;
1061 static NTSTATUS
pdb_samba_dsdb_delete_dom_group(struct pdb_methods
*m
,
1062 TALLOC_CTX
*mem_ctx
, uint32 rid
)
1064 const char *attrs
[] = { NULL
};
1065 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1066 m
->private_data
, struct pdb_samba_dsdb_state
);
1068 struct ldb_message
*msg
;
1071 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1072 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1074 sid_compose(&sid
, samdb_domain_sid(state
->ldb
), rid
);
1076 if (ldb_transaction_start(state
->ldb
) != LDB_SUCCESS
) {
1077 DEBUG(0, ("Unable to start transaction in pdb_samba_dsdb_delete_dom_group()\n"));
1078 return NT_STATUS_INTERNAL_ERROR
;
1081 dn
= ldb_dn_new_fmt(tmp_ctx
, state
->ldb
, "<SID=%s>", dom_sid_string(tmp_ctx
, &sid
));
1082 if (!dn
|| !ldb_dn_validate(dn
)) {
1083 talloc_free(tmp_ctx
);
1084 ldb_transaction_cancel(state
->ldb
);
1085 return NT_STATUS_NO_MEMORY
;
1087 rc
= dsdb_search_one(state
->ldb
, tmp_ctx
, &msg
, dn
, LDB_SCOPE_BASE
, attrs
, 0, "objectclass=group");
1088 if (rc
== LDB_ERR_NO_SUCH_OBJECT
) {
1089 talloc_free(tmp_ctx
);
1090 ldb_transaction_cancel(state
->ldb
);
1091 return NT_STATUS_NO_SUCH_GROUP
;
1093 rc
= ldb_delete(state
->ldb
, dn
);
1094 if (rc
== LDB_ERR_NO_SUCH_OBJECT
) {
1095 talloc_free(tmp_ctx
);
1096 ldb_transaction_cancel(state
->ldb
);
1097 return NT_STATUS_NO_SUCH_GROUP
;
1098 } else if (rc
!= LDB_SUCCESS
) {
1099 DEBUG(10, ("ldb_delete failed %s\n",
1100 ldb_errstring(state
->ldb
)));
1101 ldb_transaction_cancel(state
->ldb
);
1102 return NT_STATUS_LDAP(rc
);
1105 if (ldb_transaction_commit(state
->ldb
) != LDB_SUCCESS
) {
1106 DEBUG(0, ("Unable to commit transaction in pdb_samba_dsdb_delete_dom_group()\n"));
1107 return NT_STATUS_INTERNAL_ERROR
;
1109 return NT_STATUS_OK
;
1112 static NTSTATUS
pdb_samba_dsdb_add_group_mapping_entry(struct pdb_methods
*m
,
1115 return NT_STATUS_NOT_IMPLEMENTED
;
1118 static NTSTATUS
pdb_samba_dsdb_update_group_mapping_entry(struct pdb_methods
*m
,
1121 return NT_STATUS_NOT_IMPLEMENTED
;
1124 static NTSTATUS
pdb_samba_dsdb_delete_group_mapping_entry(struct pdb_methods
*m
,
1127 return NT_STATUS_NOT_IMPLEMENTED
;
1130 static NTSTATUS
pdb_samba_dsdb_enum_group_mapping(struct pdb_methods
*m
,
1131 const struct dom_sid
*sid
,
1132 enum lsa_SidType sid_name_use
,
1133 GROUP_MAP
***pp_rmap
,
1134 size_t *p_num_entries
,
1137 return NT_STATUS_NOT_IMPLEMENTED
;
1140 static NTSTATUS
pdb_samba_dsdb_enum_group_members(struct pdb_methods
*m
,
1141 TALLOC_CTX
*mem_ctx
,
1142 const struct dom_sid
*group
,
1143 uint32_t **pmembers
,
1144 size_t *pnum_members
)
1146 unsigned int i
, num_sids
, num_members
;
1147 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1148 m
->private_data
, struct pdb_samba_dsdb_state
);
1149 struct dom_sid
*members_as_sids
;
1150 struct dom_sid
*dom_sid
;
1155 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1156 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1158 dn
= ldb_dn_new_fmt(tmp_ctx
, state
->ldb
, "<SID=%s>", dom_sid_string(tmp_ctx
, group
));
1159 if (!dn
|| !ldb_dn_validate(dn
)) {
1160 return NT_STATUS_NO_MEMORY
;
1163 status
= dsdb_enum_group_mem(state
->ldb
, tmp_ctx
, dn
, &members_as_sids
, &num_sids
);
1164 if (!NT_STATUS_IS_OK(status
)) {
1165 talloc_free(tmp_ctx
);
1168 status
= dom_sid_split_rid(tmp_ctx
, group
, &dom_sid
, NULL
);
1169 if (!NT_STATUS_IS_OK(status
)) {
1170 talloc_free(tmp_ctx
);
1174 *pmembers
= members
= talloc_array(mem_ctx
, uint32_t, num_sids
);
1175 if (*pmembers
== NULL
) {
1176 TALLOC_FREE(tmp_ctx
);
1177 return NT_STATUS_NO_MEMORY
;
1181 for (i
= 0; i
< num_sids
; i
++) {
1182 if (!dom_sid_in_domain(dom_sid
, &members_as_sids
[i
])) {
1185 status
= dom_sid_split_rid(NULL
, &members_as_sids
[i
],
1186 NULL
, &members
[num_members
]);
1187 if (!NT_STATUS_IS_OK(status
)) {
1188 talloc_free(tmp_ctx
);
1193 *pnum_members
= num_members
;
1194 return NT_STATUS_OK
;
1197 /* Just convert the primary group SID into a group */
1198 static NTSTATUS
fake_enum_group_memberships(struct pdb_samba_dsdb_state
*state
,
1199 TALLOC_CTX
*mem_ctx
,
1201 struct dom_sid
**pp_sids
,
1203 uint32_t *p_num_groups
)
1206 size_t num_groups
= 0;
1207 struct dom_sid
*group_sids
= NULL
;
1209 TALLOC_CTX
*tmp_ctx
;
1211 tmp_ctx
= talloc_new(mem_ctx
);
1212 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1214 if (user
->group_sid
) {
1215 struct id_map
*id_maps
[2];
1216 struct id_map id_map
;
1220 group_sids
= talloc_array(tmp_ctx
, struct dom_sid
, num_groups
);
1221 if (group_sids
== NULL
) {
1222 talloc_free(tmp_ctx
);
1223 return NT_STATUS_NO_MEMORY
;
1225 gids
= talloc_array(tmp_ctx
, gid_t
, num_groups
);
1227 talloc_free(tmp_ctx
);
1228 return NT_STATUS_NO_MEMORY
;
1231 group_sids
[0] = *user
->group_sid
;
1233 ZERO_STRUCT(id_map
);
1234 id_map
.sid
= &group_sids
[0];
1235 id_maps
[0] = &id_map
;
1238 status
= idmap_sids_to_xids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
1239 if (!NT_STATUS_IS_OK(status
)) {
1240 talloc_free(tmp_ctx
);
1243 if (id_map
.xid
.type
== ID_TYPE_GID
|| id_map
.xid
.type
== ID_TYPE_BOTH
) {
1244 gids
[0] = id_map
.xid
.id
;
1246 DEBUG(1, (__location__
1247 "Group %s, of which %s is a member, could not be converted to a GID\n",
1248 dom_sid_string(tmp_ctx
, &group_sids
[0]),
1249 dom_sid_string(tmp_ctx
, &user
->user_sid
)));
1250 talloc_free(tmp_ctx
);
1251 /* We must error out, otherwise a user might
1252 * avoid a DENY acl based on a group they
1254 return NT_STATUS_NO_SUCH_GROUP
;
1258 *pp_sids
= talloc_steal(mem_ctx
, group_sids
);
1259 *pp_gids
= talloc_steal(mem_ctx
, gids
);
1260 *p_num_groups
= num_groups
;
1261 talloc_free(tmp_ctx
);
1262 return NT_STATUS_OK
;
1265 static NTSTATUS
pdb_samba_dsdb_enum_group_memberships(struct pdb_methods
*m
,
1266 TALLOC_CTX
*mem_ctx
,
1268 struct dom_sid
**pp_sids
,
1270 uint32_t *p_num_groups
)
1272 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1273 m
->private_data
, struct pdb_samba_dsdb_state
);
1274 struct ldb_message
*msg
= pdb_samba_dsdb_get_samu_private(
1276 const char *attrs
[] = { "tokenGroups", NULL
};
1277 struct ldb_message
*tokengroups_msg
;
1278 struct ldb_message_element
*tokengroups
;
1281 unsigned int count
= 0;
1283 struct dom_sid
*group_sids
;
1285 TALLOC_CTX
*tmp_ctx
;
1288 /* Fake up some things here */
1289 return fake_enum_group_memberships(state
,
1292 pp_gids
, p_num_groups
);
1295 tmp_ctx
= talloc_new(mem_ctx
);
1296 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1298 rc
= dsdb_search_one(state
->ldb
, tmp_ctx
, &tokengroups_msg
, msg
->dn
, LDB_SCOPE_BASE
, attrs
, 0, NULL
);
1300 if (rc
== LDB_ERR_NO_SUCH_OBJECT
) {
1301 talloc_free(tmp_ctx
);
1302 return NT_STATUS_NO_SUCH_USER
;
1303 } else if (rc
!= LDB_SUCCESS
) {
1304 DEBUG(10, ("dsdb_search_one failed %s\n",
1305 ldb_errstring(state
->ldb
)));
1306 talloc_free(tmp_ctx
);
1307 return NT_STATUS_LDAP(rc
);
1310 tokengroups
= ldb_msg_find_element(tokengroups_msg
, "tokenGroups");
1313 count
= tokengroups
->num_values
;
1316 group_sids
= talloc_array(tmp_ctx
, struct dom_sid
, count
);
1317 if (group_sids
== NULL
) {
1318 talloc_free(tmp_ctx
);
1319 return NT_STATUS_NO_MEMORY
;
1321 gids
= talloc_array(tmp_ctx
, gid_t
, count
);
1323 talloc_free(tmp_ctx
);
1324 return NT_STATUS_NO_MEMORY
;
1328 for (i
=0; i
<count
; i
++) {
1329 struct id_map
*id_maps
[2];
1330 struct id_map id_map
;
1331 struct ldb_val
*v
= &tokengroups
->values
[i
];
1332 enum ndr_err_code ndr_err
1333 = ndr_pull_struct_blob(v
, group_sids
, &group_sids
[num_groups
],
1334 (ndr_pull_flags_fn_t
)ndr_pull_dom_sid
);
1335 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1336 talloc_free(tmp_ctx
);
1337 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1340 ZERO_STRUCT(id_map
);
1341 id_map
.sid
= &group_sids
[num_groups
];
1342 id_maps
[0] = &id_map
;
1345 status
= idmap_sids_to_xids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
1346 if (!NT_STATUS_IS_OK(status
)) {
1347 talloc_free(tmp_ctx
);
1350 if (id_map
.xid
.type
== ID_TYPE_GID
|| id_map
.xid
.type
== ID_TYPE_BOTH
) {
1351 gids
[num_groups
] = id_map
.xid
.id
;
1353 DEBUG(1, (__location__
1354 "Group %s, of which %s is a member, could not be converted to a GID\n",
1355 dom_sid_string(tmp_ctx
, &group_sids
[num_groups
]),
1356 ldb_dn_get_linearized(msg
->dn
)));
1357 talloc_free(tmp_ctx
);
1358 /* We must error out, otherwise a user might
1359 * avoid a DENY acl based on a group they
1361 return NT_STATUS_NO_SUCH_GROUP
;
1365 if (num_groups
== count
) {
1370 *pp_sids
= talloc_steal(mem_ctx
, group_sids
);
1371 *pp_gids
= talloc_steal(mem_ctx
, gids
);
1372 *p_num_groups
= num_groups
;
1373 talloc_free(tmp_ctx
);
1374 return NT_STATUS_OK
;
1377 static NTSTATUS
pdb_samba_dsdb_set_unix_primary_group(struct pdb_methods
*m
,
1378 TALLOC_CTX
*mem_ctx
,
1381 return NT_STATUS_NOT_IMPLEMENTED
;
1384 static NTSTATUS
pdb_samba_dsdb_mod_groupmem_by_sid(struct pdb_methods
*m
,
1385 TALLOC_CTX
*mem_ctx
,
1386 const struct dom_sid
*groupsid
,
1387 const struct dom_sid
*membersid
,
1390 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1391 m
->private_data
, struct pdb_samba_dsdb_state
);
1392 struct ldb_message
*msg
;
1394 struct ldb_message_element
*el
;
1395 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1396 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1397 msg
= ldb_msg_new(tmp_ctx
);
1399 TALLOC_FREE(tmp_ctx
);
1400 return NT_STATUS_NO_MEMORY
;
1403 msg
->dn
= ldb_dn_new_fmt(msg
, state
->ldb
, "<SID=%s>", dom_sid_string(tmp_ctx
, groupsid
));
1404 if (!msg
->dn
|| !ldb_dn_validate(msg
->dn
)) {
1405 talloc_free(tmp_ctx
);
1406 return NT_STATUS_NO_MEMORY
;
1408 ret
= ldb_msg_add_fmt(msg
, "member", "<SID=%s>", dom_sid_string(tmp_ctx
, membersid
));
1409 if (ret
!= LDB_SUCCESS
) {
1410 talloc_free(tmp_ctx
);
1411 return NT_STATUS_NO_MEMORY
;
1413 el
= ldb_msg_find_element(msg
, "member");
1416 /* No need for transactions here, the ldb auto-transaction
1417 * code will handle things for the single operation */
1418 ret
= ldb_modify(state
->ldb
, msg
);
1419 talloc_free(tmp_ctx
);
1420 if (ret
!= LDB_SUCCESS
) {
1421 DEBUG(10, ("ldb_modify failed: %s\n",
1422 ldb_errstring(state
->ldb
)));
1423 if (ret
== LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS
) {
1424 return NT_STATUS_MEMBER_IN_GROUP
;
1426 if (ret
== LDB_ERR_NO_SUCH_ATTRIBUTE
) {
1427 return NT_STATUS_MEMBER_NOT_IN_GROUP
;
1429 return NT_STATUS_LDAP(ret
);
1432 return NT_STATUS_OK
;
1435 static NTSTATUS
pdb_samba_dsdb_mod_groupmem(struct pdb_methods
*m
,
1436 TALLOC_CTX
*mem_ctx
,
1437 uint32 grouprid
, uint32 memberrid
,
1440 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1441 m
->private_data
, struct pdb_samba_dsdb_state
);
1442 const struct dom_sid
*dom_sid
, *groupsid
, *membersid
;
1444 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1445 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1447 dom_sid
= samdb_domain_sid(state
->ldb
);
1449 groupsid
= dom_sid_add_rid(tmp_ctx
, dom_sid
, grouprid
);
1450 if (groupsid
== NULL
) {
1451 TALLOC_FREE(tmp_ctx
);
1452 return NT_STATUS_NO_MEMORY
;
1454 membersid
= dom_sid_add_rid(tmp_ctx
, dom_sid
, memberrid
);
1455 if (membersid
== NULL
) {
1456 TALLOC_FREE(tmp_ctx
);
1457 return NT_STATUS_NO_MEMORY
;
1459 status
= pdb_samba_dsdb_mod_groupmem_by_sid(m
, tmp_ctx
, groupsid
, membersid
, mod_op
);
1460 talloc_free(tmp_ctx
);
1464 static NTSTATUS
pdb_samba_dsdb_add_groupmem(struct pdb_methods
*m
,
1465 TALLOC_CTX
*mem_ctx
,
1466 uint32 group_rid
, uint32 member_rid
)
1468 return pdb_samba_dsdb_mod_groupmem(m
, mem_ctx
, group_rid
, member_rid
,
1472 static NTSTATUS
pdb_samba_dsdb_del_groupmem(struct pdb_methods
*m
,
1473 TALLOC_CTX
*mem_ctx
,
1474 uint32 group_rid
, uint32 member_rid
)
1476 return pdb_samba_dsdb_mod_groupmem(m
, mem_ctx
, group_rid
, member_rid
,
1477 LDB_FLAG_MOD_DELETE
);
1480 static NTSTATUS
pdb_samba_dsdb_create_alias(struct pdb_methods
*m
,
1481 const char *name
, uint32
*rid
)
1483 TALLOC_CTX
*frame
= talloc_stackframe();
1484 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1485 m
->private_data
, struct pdb_samba_dsdb_state
);
1486 struct dom_sid
*sid
;
1491 /* Internally this uses transactions to ensure all the steps
1492 * happen or fail as one */
1493 status
= dsdb_add_domain_alias(state
->ldb
, frame
, name
, &sid
, &dn
);
1494 if (!NT_STATUS_IS_OK(status
)) {
1498 sid_peek_rid(sid
, rid
);
1500 return NT_STATUS_OK
;
1503 static NTSTATUS
pdb_samba_dsdb_delete_alias(struct pdb_methods
*m
,
1504 const struct dom_sid
*sid
)
1506 const char *attrs
[] = { NULL
};
1507 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1508 m
->private_data
, struct pdb_samba_dsdb_state
);
1509 struct ldb_message
*msg
;
1512 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1513 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1515 dn
= ldb_dn_new_fmt(tmp_ctx
, state
->ldb
, "<SID=%s>", dom_sid_string(tmp_ctx
, sid
));
1516 if (!dn
|| !ldb_dn_validate(dn
)) {
1517 talloc_free(tmp_ctx
);
1518 return NT_STATUS_NO_MEMORY
;
1521 if (ldb_transaction_start(state
->ldb
) != LDB_SUCCESS
) {
1522 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state
->ldb
)));
1523 return NT_STATUS_INTERNAL_ERROR
;
1526 rc
= dsdb_search_one(state
->ldb
, tmp_ctx
, &msg
, dn
, LDB_SCOPE_BASE
, attrs
, 0, "(objectclass=group)"
1527 "(|(grouptype=%d)(grouptype=%d)))",
1528 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1529 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1530 if (rc
== LDB_ERR_NO_SUCH_OBJECT
) {
1531 talloc_free(tmp_ctx
);
1532 ldb_transaction_cancel(state
->ldb
);
1533 return NT_STATUS_NO_SUCH_ALIAS
;
1535 rc
= ldb_delete(state
->ldb
, dn
);
1536 if (rc
== LDB_ERR_NO_SUCH_OBJECT
) {
1537 talloc_free(tmp_ctx
);
1538 ldb_transaction_cancel(state
->ldb
);
1539 return NT_STATUS_NO_SUCH_ALIAS
;
1540 } else if (rc
!= LDB_SUCCESS
) {
1541 DEBUG(10, ("ldb_delete failed %s\n",
1542 ldb_errstring(state
->ldb
)));
1543 ldb_transaction_cancel(state
->ldb
);
1544 return NT_STATUS_LDAP(rc
);
1547 if (ldb_transaction_commit(state
->ldb
) != LDB_SUCCESS
) {
1548 DEBUG(0, ("Failed to commit transaction in pdb_samba_dsdb_delete_alias(): %s\n",
1549 ldb_errstring(state
->ldb
)));
1550 return NT_STATUS_INTERNAL_ERROR
;
1553 return NT_STATUS_OK
;
1557 static NTSTATUS
pdb_samba_dsdb_set_aliasinfo(struct pdb_methods
*m
,
1558 const struct dom_sid
*sid
,
1559 struct acct_info
*info
)
1561 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1562 m
->private_data
, struct pdb_samba_dsdb_state
);
1563 struct tldap_context
*ld
;
1564 const char *attrs
[3] = { "objectSid", "description",
1566 struct ldb_message
**msg
;
1569 struct tldap_mod
*mods
;
1573 ld
= pdb_samba_dsdb_ld(state
);
1575 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1578 sidstr
= sid_binstring(talloc_tos(), sid
);
1579 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1581 rc
= pdb_samba_dsdb_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1582 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1583 &msg
, "(&(objectSid=%s)(objectclass=group)"
1584 "(|(grouptype=%d)(grouptype=%d)))",
1585 sidstr
, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1586 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1588 if (rc
!= LDB_SUCCESS
) {
1589 DEBUG(10, ("ldap_search failed %s\n",
1590 ldb_errstring(state
->ldb
)));
1591 return NT_STATUS_LDAP(rc
);
1593 switch talloc_array_length(msg
) {
1595 return NT_STATUS_NO_SUCH_ALIAS
;
1599 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1602 if (!tldap_entry_dn(msg
[0], &dn
)) {
1604 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1611 ok
&= tldap_make_mod_fmt(
1612 msg
[0], msg
, &num_mods
, &mods
, "description",
1613 "%s", info
->acct_desc
);
1614 ok
&= tldap_make_mod_fmt(
1615 msg
[0], msg
, &num_mods
, &mods
, "samAccountName",
1616 "%s", info
->acct_name
);
1619 return NT_STATUS_NO_MEMORY
;
1621 if (num_mods
== 0) {
1624 return NT_STATUS_OK
;
1627 rc
= tldap_modify(ld
, dn
, num_mods
, mods
, NULL
, 0, NULL
, 0);
1629 if (rc
!= LDB_SUCCESS
) {
1630 DEBUG(10, ("ldap_modify failed: %s\n",
1631 ldb_errstring(state
->ldb
)));
1632 return NT_STATUS_LDAP(rc
);
1634 return NT_STATUS_OK
;
1637 static NTSTATUS
pdb_samba_dsdb_add_aliasmem(struct pdb_methods
*m
,
1638 const struct dom_sid
*alias
,
1639 const struct dom_sid
*member
)
1642 TALLOC_CTX
*frame
= talloc_stackframe();
1643 status
= pdb_samba_dsdb_mod_groupmem_by_sid(m
, frame
, alias
, member
, LDB_FLAG_MOD_ADD
);
1648 static NTSTATUS
pdb_samba_dsdb_del_aliasmem(struct pdb_methods
*m
,
1649 const struct dom_sid
*alias
,
1650 const struct dom_sid
*member
)
1653 TALLOC_CTX
*frame
= talloc_stackframe();
1654 status
= pdb_samba_dsdb_mod_groupmem_by_sid(m
, frame
, alias
, member
, LDB_FLAG_MOD_DELETE
);
1659 static NTSTATUS
pdb_samba_dsdb_enum_aliasmem(struct pdb_methods
*m
,
1660 const struct dom_sid
*alias
,
1661 TALLOC_CTX
*mem_ctx
,
1662 struct dom_sid
**pmembers
,
1663 size_t *pnum_members
)
1665 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1666 m
->private_data
, struct pdb_samba_dsdb_state
);
1668 unsigned int num_members
;
1670 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1671 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1673 dn
= ldb_dn_new_fmt(tmp_ctx
, state
->ldb
, "<SID=%s>", dom_sid_string(tmp_ctx
, alias
));
1674 if (!dn
|| !ldb_dn_validate(dn
)) {
1675 return NT_STATUS_NO_MEMORY
;
1678 status
= dsdb_enum_group_mem(state
->ldb
, mem_ctx
, dn
, pmembers
, &num_members
);
1679 *pnum_members
= num_members
;
1680 if (NT_STATUS_IS_OK(status
)) {
1681 talloc_steal(mem_ctx
, pmembers
);
1683 talloc_free(tmp_ctx
);
1687 static NTSTATUS
pdb_samba_dsdb_enum_alias_memberships(struct pdb_methods
*m
,
1688 TALLOC_CTX
*mem_ctx
,
1689 const struct dom_sid
*domain_sid
,
1690 const struct dom_sid
*members
,
1692 uint32_t **palias_rids
,
1693 size_t *pnum_alias_rids
)
1695 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1696 m
->private_data
, struct pdb_samba_dsdb_state
);
1697 uint32_t *alias_rids
= NULL
;
1698 size_t num_alias_rids
= 0;
1700 struct dom_sid
*groupSIDs
= NULL
;
1701 unsigned int num_groupSIDs
= 0;
1704 const char *sid_string
;
1708 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1709 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1711 * TODO: Get the filter right so that we only get the aliases from
1712 * either the SAM or BUILTIN
1715 filter
= talloc_asprintf(tmp_ctx
, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1716 GROUP_TYPE_BUILTIN_LOCAL_GROUP
);
1717 if (filter
== NULL
) {
1718 return NT_STATUS_NO_MEMORY
;
1721 for (i
= 0; i
< num_members
; i
++) {
1722 sid_string
= dom_sid_string(tmp_ctx
, &members
[i
]);
1723 if (sid_string
== NULL
) {
1724 TALLOC_FREE(tmp_ctx
);
1725 return NT_STATUS_NO_MEMORY
;
1728 sid_dn
= talloc_asprintf(tmp_ctx
, "<SID=%s>", sid_string
);
1729 if (sid_dn
== NULL
) {
1730 TALLOC_FREE(tmp_ctx
);
1731 return NT_STATUS_NO_MEMORY
;
1734 sid_blob
= data_blob_string_const(sid_dn
);
1736 status
= dsdb_expand_nested_groups(state
->ldb
, &sid_blob
, true, filter
,
1737 tmp_ctx
, &groupSIDs
, &num_groupSIDs
);
1738 if (!NT_STATUS_IS_OK(status
)) {
1739 talloc_free(tmp_ctx
);
1744 alias_rids
= talloc_array(mem_ctx
, uint32_t, num_groupSIDs
);
1745 if (alias_rids
== NULL
) {
1746 talloc_free(tmp_ctx
);
1747 return NT_STATUS_NO_MEMORY
;
1750 for (i
=0; i
<num_groupSIDs
; i
++) {
1751 if (sid_peek_check_rid(domain_sid
, &groupSIDs
[i
],
1752 &alias_rids
[num_alias_rids
])) {
1757 *palias_rids
= alias_rids
;
1758 *pnum_alias_rids
= num_alias_rids
;
1759 return NT_STATUS_OK
;
1762 static NTSTATUS
pdb_samba_dsdb_lookup_rids(struct pdb_methods
*m
,
1763 const struct dom_sid
*domain_sid
,
1767 enum lsa_SidType
*lsa_attrs
)
1769 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1770 m
->private_data
, struct pdb_samba_dsdb_state
);
1773 TALLOC_CTX
*tmp_ctx
;
1775 if (num_rids
== 0) {
1776 return NT_STATUS_NONE_MAPPED
;
1779 tmp_ctx
= talloc_stackframe();
1780 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1782 status
= dsdb_lookup_rids(state
->ldb
, tmp_ctx
, domain_sid
, num_rids
, rids
, names
, lsa_attrs
);
1783 talloc_free(tmp_ctx
);
1787 static NTSTATUS
pdb_samba_dsdb_lookup_names(struct pdb_methods
*m
,
1788 const struct dom_sid
*domain_sid
,
1790 const char **pp_names
,
1792 enum lsa_SidType
*attrs
)
1794 return NT_STATUS_NOT_IMPLEMENTED
;
1797 static NTSTATUS
pdb_samba_dsdb_get_account_policy(struct pdb_methods
*m
,
1798 enum pdb_policy_type type
,
1801 return account_policy_get(type
, value
)
1802 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1805 static NTSTATUS
pdb_samba_dsdb_set_account_policy(struct pdb_methods
*m
,
1806 enum pdb_policy_type type
,
1809 return account_policy_set(type
, value
)
1810 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1813 static NTSTATUS
pdb_samba_dsdb_get_seq_num(struct pdb_methods
*m
,
1814 time_t *seq_num_out
)
1816 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1817 m
->private_data
, struct pdb_samba_dsdb_state
);
1819 int ret
= ldb_sequence_number(state
->ldb
, LDB_SEQ_HIGHEST_SEQ
, &seq_num
);
1820 if (ret
== LDB_SUCCESS
) {
1821 *seq_num_out
= seq_num
;
1822 return NT_STATUS_OK
;
1824 return NT_STATUS_UNSUCCESSFUL
;
1828 struct pdb_samba_dsdb_search_state
{
1829 uint32_t acct_flags
;
1830 struct samr_displayentry
*entries
;
1831 uint32_t num_entries
;
1836 static bool pdb_samba_dsdb_next_entry(struct pdb_search
*search
,
1837 struct samr_displayentry
*entry
)
1839 struct pdb_samba_dsdb_search_state
*state
= talloc_get_type_abort(
1840 search
->private_data
, struct pdb_samba_dsdb_search_state
);
1842 if (state
->current
== state
->num_entries
) {
1846 entry
->idx
= state
->entries
[state
->current
].idx
;
1847 entry
->rid
= state
->entries
[state
->current
].rid
;
1848 entry
->acct_flags
= state
->entries
[state
->current
].acct_flags
;
1850 entry
->account_name
= talloc_strdup(
1851 search
, state
->entries
[state
->current
].account_name
);
1852 entry
->fullname
= talloc_strdup(
1853 search
, state
->entries
[state
->current
].fullname
);
1854 entry
->description
= talloc_strdup(
1855 search
, state
->entries
[state
->current
].description
);
1857 state
->current
+= 1;
1861 static void pdb_samba_dsdb_search_end(struct pdb_search
*search
)
1863 struct pdb_samba_dsdb_search_state
*state
= talloc_get_type_abort(
1864 search
->private_data
, struct pdb_samba_dsdb_search_state
);
1868 static bool pdb_samba_dsdb_search_filter(struct pdb_methods
*m
,
1869 struct pdb_search
*search
,
1870 struct pdb_samba_dsdb_search_state
**pstate
,
1871 const char *exp_fmt
, ...) _PRINTF_ATTRIBUTE(4, 5)
1873 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1874 m
->private_data
, struct pdb_samba_dsdb_state
);
1875 struct pdb_samba_dsdb_search_state
*sstate
;
1876 const char * attrs
[] = { "objectSid", "sAMAccountName", "displayName",
1877 "userAccountControl", "description", NULL
};
1878 struct ldb_result
*res
;
1879 int i
, rc
, num_users
;
1882 char *expression
= NULL
;
1884 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1889 va_start(ap
, exp_fmt
);
1890 expression
= talloc_vasprintf(tmp_ctx
, exp_fmt
, ap
);
1894 talloc_free(tmp_ctx
);
1895 return LDB_ERR_OPERATIONS_ERROR
;
1898 sstate
= talloc_zero(tmp_ctx
, struct pdb_samba_dsdb_search_state
);
1899 if (sstate
== NULL
) {
1900 talloc_free(tmp_ctx
);
1904 rc
= dsdb_search(state
->ldb
, tmp_ctx
, &res
, ldb_get_default_basedn(state
->ldb
), LDB_SCOPE_SUBTREE
, attrs
, 0, "%s", expression
);
1905 if (rc
!= LDB_SUCCESS
) {
1906 talloc_free(tmp_ctx
);
1907 DEBUG(10, ("dsdb_search failed: %s\n",
1908 ldb_errstring(state
->ldb
)));
1912 num_users
= res
->count
;
1914 sstate
->entries
= talloc_array(sstate
, struct samr_displayentry
,
1916 if (sstate
->entries
== NULL
) {
1917 talloc_free(tmp_ctx
);
1918 DEBUG(10, ("talloc failed\n"));
1922 sstate
->num_entries
= 0;
1924 for (i
=0; i
<num_users
; i
++) {
1925 struct samr_displayentry
*e
;
1926 struct dom_sid
*sid
;
1928 e
= &sstate
->entries
[sstate
->num_entries
];
1930 e
->idx
= sstate
->num_entries
;
1931 sid
= samdb_result_dom_sid(tmp_ctx
, res
->msgs
[i
], "objectSid");
1933 talloc_free(tmp_ctx
);
1934 DEBUG(10, ("Could not pull SID\n"));
1937 sid_peek_rid(sid
, &e
->rid
);
1939 e
->acct_flags
= samdb_result_acct_flags(state
->ldb
, tmp_ctx
,
1941 ldb_get_default_basedn(state
->ldb
));
1942 e
->account_name
= ldb_msg_find_attr_as_string(
1943 res
->msgs
[i
], "samAccountName", NULL
);
1944 if (e
->account_name
== NULL
) {
1945 talloc_free(tmp_ctx
);
1948 e
->fullname
= ldb_msg_find_attr_as_string(
1949 res
->msgs
[i
], "displayName", "");
1950 e
->description
= ldb_msg_find_attr_as_string(
1951 res
->msgs
[i
], "description", "");
1953 sstate
->num_entries
+= 1;
1954 if (sstate
->num_entries
>= num_users
) {
1958 talloc_steal(sstate
->entries
, res
->msgs
);
1959 search
->private_data
= talloc_steal(search
, sstate
);
1960 search
->next_entry
= pdb_samba_dsdb_next_entry
;
1961 search
->search_end
= pdb_samba_dsdb_search_end
;
1963 talloc_free(tmp_ctx
);
1967 static bool pdb_samba_dsdb_search_users(struct pdb_methods
*m
,
1968 struct pdb_search
*search
,
1971 struct pdb_samba_dsdb_search_state
*sstate
;
1974 ret
= pdb_samba_dsdb_search_filter(m
, search
, &sstate
, "(objectclass=user)");
1978 sstate
->acct_flags
= acct_flags
;
1982 static bool pdb_samba_dsdb_search_groups(struct pdb_methods
*m
,
1983 struct pdb_search
*search
)
1985 struct pdb_samba_dsdb_search_state
*sstate
;
1988 ret
= pdb_samba_dsdb_search_filter(m
, search
, &sstate
,
1989 "(&(grouptype=%d)(objectclass=group))",
1990 GTYPE_SECURITY_GLOBAL_GROUP
);
1994 sstate
->acct_flags
= 0;
1998 static bool pdb_samba_dsdb_search_aliases(struct pdb_methods
*m
,
1999 struct pdb_search
*search
,
2000 const struct dom_sid
*sid
)
2002 struct pdb_samba_dsdb_search_state
*sstate
;
2005 ret
= pdb_samba_dsdb_search_filter(m
, search
, &sstate
,
2006 "(&(grouptype=%d)(objectclass=group))",
2007 sid_check_is_builtin(sid
)
2008 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2009 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
2013 sstate
->acct_flags
= 0;
2017 static bool pdb_samba_dsdb_uid_to_sid(struct pdb_methods
*m
, uid_t uid
,
2018 struct dom_sid
*sid
)
2020 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
2021 m
->private_data
, struct pdb_samba_dsdb_state
);
2023 struct id_map id_map
;
2024 struct id_map
*id_maps
[2];
2025 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2030 id_map
.xid
.id
= uid
;
2031 id_map
.xid
.type
= ID_TYPE_UID
;
2032 id_maps
[0] = &id_map
;
2035 status
= idmap_xids_to_sids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
2036 if (!NT_STATUS_IS_OK(status
)) {
2037 talloc_free(tmp_ctx
);
2041 talloc_free(tmp_ctx
);
2045 static bool pdb_samba_dsdb_gid_to_sid(struct pdb_methods
*m
, gid_t gid
,
2046 struct dom_sid
*sid
)
2048 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
2049 m
->private_data
, struct pdb_samba_dsdb_state
);
2051 struct id_map id_map
;
2052 struct id_map
*id_maps
[2];
2053 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2058 id_map
.xid
.id
= gid
;
2059 id_map
.xid
.type
= ID_TYPE_GID
;
2060 id_maps
[0] = &id_map
;
2063 status
= idmap_xids_to_sids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
2064 if (!NT_STATUS_IS_OK(status
)) {
2068 talloc_free(tmp_ctx
);
2072 static bool pdb_samba_dsdb_sid_to_id(struct pdb_methods
*m
, const struct dom_sid
*sid
,
2075 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
2076 m
->private_data
, struct pdb_samba_dsdb_state
);
2077 struct id_map id_map
;
2078 struct id_map
*id_maps
[2];
2080 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2085 ZERO_STRUCT(id_map
);
2086 id_map
.sid
= discard_const_p(struct dom_sid
, sid
);
2087 id_maps
[0] = &id_map
;
2090 status
= idmap_sids_to_xids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
2091 talloc_free(tmp_ctx
);
2092 if (!NT_STATUS_IS_OK(status
)) {
2095 if (id_map
.xid
.type
!= ID_TYPE_NOT_SPECIFIED
) {
2102 static uint32_t pdb_samba_dsdb_capabilities(struct pdb_methods
*m
)
2104 return PDB_CAP_STORE_RIDS
| PDB_CAP_ADS
;
2107 static bool pdb_samba_dsdb_new_rid(struct pdb_methods
*m
, uint32
*rid
)
2112 static bool pdb_samba_dsdb_get_trusteddom_pw(struct pdb_methods
*m
,
2113 const char *domain
, char** pwd
,
2114 struct dom_sid
*sid
,
2115 time_t *pass_last_set_time
)
2120 static bool pdb_samba_dsdb_set_trusteddom_pw(struct pdb_methods
*m
,
2121 const char* domain
, const char* pwd
,
2122 const struct dom_sid
*sid
)
2127 static bool pdb_samba_dsdb_del_trusteddom_pw(struct pdb_methods
*m
,
2133 static NTSTATUS
pdb_samba_dsdb_enum_trusteddoms(struct pdb_methods
*m
,
2134 TALLOC_CTX
*mem_ctx
,
2135 uint32
*num_domains
,
2136 struct trustdom_info
***domains
)
2140 return NT_STATUS_OK
;
2143 static bool pdb_samba_dsdb_is_responsible_for_wellknown(struct pdb_methods
*m
)
2148 static void pdb_samba_dsdb_init_methods(struct pdb_methods
*m
)
2150 m
->name
= "samba_dsdb";
2151 m
->get_domain_info
= pdb_samba_dsdb_get_domain_info
;
2152 m
->getsampwnam
= pdb_samba_dsdb_getsampwnam
;
2153 m
->getsampwsid
= pdb_samba_dsdb_getsampwsid
;
2154 m
->create_user
= pdb_samba_dsdb_create_user
;
2155 m
->delete_user
= pdb_samba_dsdb_delete_user
;
2156 m
->add_sam_account
= pdb_samba_dsdb_add_sam_account
;
2157 m
->update_sam_account
= pdb_samba_dsdb_update_sam_account
;
2158 m
->delete_sam_account
= pdb_samba_dsdb_delete_sam_account
;
2159 m
->rename_sam_account
= pdb_samba_dsdb_rename_sam_account
;
2160 m
->update_login_attempts
= pdb_samba_dsdb_update_login_attempts
;
2161 m
->getgrsid
= pdb_samba_dsdb_getgrsid
;
2162 m
->getgrgid
= pdb_samba_dsdb_getgrgid
;
2163 m
->getgrnam
= pdb_samba_dsdb_getgrnam
;
2164 m
->create_dom_group
= pdb_samba_dsdb_create_dom_group
;
2165 m
->delete_dom_group
= pdb_samba_dsdb_delete_dom_group
;
2166 m
->add_group_mapping_entry
= pdb_samba_dsdb_add_group_mapping_entry
;
2167 m
->update_group_mapping_entry
= pdb_samba_dsdb_update_group_mapping_entry
;
2168 m
->delete_group_mapping_entry
= pdb_samba_dsdb_delete_group_mapping_entry
;
2169 m
->enum_group_mapping
= pdb_samba_dsdb_enum_group_mapping
;
2170 m
->enum_group_members
= pdb_samba_dsdb_enum_group_members
;
2171 m
->enum_group_memberships
= pdb_samba_dsdb_enum_group_memberships
;
2172 m
->set_unix_primary_group
= pdb_samba_dsdb_set_unix_primary_group
;
2173 m
->add_groupmem
= pdb_samba_dsdb_add_groupmem
;
2174 m
->del_groupmem
= pdb_samba_dsdb_del_groupmem
;
2175 m
->create_alias
= pdb_samba_dsdb_create_alias
;
2176 m
->delete_alias
= pdb_samba_dsdb_delete_alias
;
2177 m
->get_aliasinfo
= pdb_default_get_aliasinfo
;
2178 m
->add_aliasmem
= pdb_samba_dsdb_add_aliasmem
;
2179 m
->del_aliasmem
= pdb_samba_dsdb_del_aliasmem
;
2180 m
->enum_aliasmem
= pdb_samba_dsdb_enum_aliasmem
;
2181 m
->enum_alias_memberships
= pdb_samba_dsdb_enum_alias_memberships
;
2182 m
->lookup_rids
= pdb_samba_dsdb_lookup_rids
;
2183 m
->lookup_names
= pdb_samba_dsdb_lookup_names
;
2184 m
->get_account_policy
= pdb_samba_dsdb_get_account_policy
;
2185 m
->set_account_policy
= pdb_samba_dsdb_set_account_policy
;
2186 m
->get_seq_num
= pdb_samba_dsdb_get_seq_num
;
2187 m
->search_users
= pdb_samba_dsdb_search_users
;
2188 m
->search_groups
= pdb_samba_dsdb_search_groups
;
2189 m
->search_aliases
= pdb_samba_dsdb_search_aliases
;
2190 m
->uid_to_sid
= pdb_samba_dsdb_uid_to_sid
;
2191 m
->gid_to_sid
= pdb_samba_dsdb_gid_to_sid
;
2192 m
->sid_to_id
= pdb_samba_dsdb_sid_to_id
;
2193 m
->capabilities
= pdb_samba_dsdb_capabilities
;
2194 m
->new_rid
= pdb_samba_dsdb_new_rid
;
2195 m
->get_trusteddom_pw
= pdb_samba_dsdb_get_trusteddom_pw
;
2196 m
->set_trusteddom_pw
= pdb_samba_dsdb_set_trusteddom_pw
;
2197 m
->del_trusteddom_pw
= pdb_samba_dsdb_del_trusteddom_pw
;
2198 m
->enum_trusteddoms
= pdb_samba_dsdb_enum_trusteddoms
;
2199 m
->is_responsible_for_wellknown
=
2200 pdb_samba_dsdb_is_responsible_for_wellknown
;
2203 static void free_private_data(void **vp
)
2205 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
2206 *vp
, struct pdb_samba_dsdb_state
);
2207 talloc_unlink(state
, state
->ldb
);
2211 static NTSTATUS
pdb_samba_dsdb_init_secrets(struct pdb_methods
*m
)
2213 struct pdb_domain_info
*dom_info
;
2216 dom_info
= pdb_samba_dsdb_get_domain_info(m
, m
);
2218 return NT_STATUS_UNSUCCESSFUL
;
2221 secrets_clear_domain_protection(dom_info
->name
);
2222 ret
= secrets_store_domain_sid(dom_info
->name
,
2227 ret
= secrets_store_domain_guid(dom_info
->name
,
2232 ret
= secrets_mark_domain_protected(dom_info
->name
);
2238 TALLOC_FREE(dom_info
);
2240 return NT_STATUS_UNSUCCESSFUL
;
2242 return NT_STATUS_OK
;
2245 static NTSTATUS
pdb_init_samba_dsdb(struct pdb_methods
**pdb_method
,
2246 const char *location
)
2248 struct pdb_methods
*m
;
2249 struct pdb_samba_dsdb_state
*state
;
2252 if ( !NT_STATUS_IS_OK(status
= make_pdb_method( &m
)) ) {
2256 state
= talloc_zero(m
, struct pdb_samba_dsdb_state
);
2257 if (state
== NULL
) {
2260 m
->private_data
= state
;
2261 m
->free_private_data
= free_private_data
;
2262 pdb_samba_dsdb_init_methods(m
);
2264 state
->ev
= s4_event_context_init(state
);
2266 DEBUG(0, ("s4_event_context_init failed\n"));
2270 state
->lp_ctx
= loadparm_init_s3(state
, loadparm_s3_helpers());
2271 if (state
->lp_ctx
== NULL
) {
2272 DEBUG(0, ("loadparm_init_s3 failed\n"));
2277 state
->ldb
= samdb_connect_url(state
,
2280 system_session(state
->lp_ctx
),
2283 state
->ldb
= samdb_connect(state
,
2286 system_session(state
->lp_ctx
), 0);
2290 DEBUG(0, ("samdb_connect failed\n"));
2291 status
= NT_STATUS_INTERNAL_ERROR
;
2295 state
->idmap_ctx
= idmap_init(state
, state
->ev
,
2297 if (!state
->idmap_ctx
) {
2298 DEBUG(0, ("idmap failed\n"));
2299 status
= NT_STATUS_INTERNAL_ERROR
;
2303 status
= pdb_samba_dsdb_init_secrets(m
);
2304 if (!NT_STATUS_IS_OK(status
)) {
2305 DEBUG(10, ("pdb_samba_dsdb_init_secrets failed!\n"));
2310 return NT_STATUS_OK
;
2312 status
= NT_STATUS_NO_MEMORY
;
2318 NTSTATUS
pdb_samba_dsdb_init(void);
2319 NTSTATUS
pdb_samba_dsdb_init(void)
2321 NTSTATUS status
= smb_register_passdb(PASSDB_INTERFACE_VERSION
, "samba_dsdb",
2322 pdb_init_samba_dsdb
);
2323 if (!NT_STATUS_IS_OK(status
)) {
2326 return smb_register_passdb(PASSDB_INTERFACE_VERSION
, "samba4",
2327 pdb_init_samba_dsdb
);