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 blob
= ldb_msg_find_ldb_val(msg
, "userParameters");
264 str
= base64_encode_data_blob(frame
, *blob
);
266 DEBUG(0, ("base64_encode_data_blob() failed\n"));
269 pdb_set_munged_dial(sam
, str
, PDB_SET
);
272 sid
= samdb_result_dom_sid(talloc_tos(), msg
, "objectSid");
274 DEBUG(10, ("Could not pull SID\n"));
277 pdb_set_user_sid(sam
, sid
, PDB_SET
);
279 n
= ldb_msg_find_attr_as_uint(msg
, "userAccountControl", 0);
281 DEBUG(10, ("Could not pull userAccountControl\n"));
284 pdb_set_acct_ctrl(sam
, ds_uf2acb(n
), PDB_SET
);
286 blob
= ldb_msg_find_ldb_val(msg
, "unicodePwd");
288 if (blob
->length
!= NT_HASH_LEN
) {
289 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
290 (int)blob
->length
, NT_HASH_LEN
));
293 pdb_set_nt_passwd(sam
, blob
->data
, PDB_SET
);
296 blob
= ldb_msg_find_ldb_val(msg
, "dBCSPwd");
298 if (blob
->length
!= LM_HASH_LEN
) {
299 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
300 (int)blob
->length
, LM_HASH_LEN
));
303 pdb_set_lanman_passwd(sam
, blob
->data
, PDB_SET
);
306 n
= ldb_msg_find_attr_as_uint(msg
, "primaryGroupID", 0);
308 DEBUG(10, ("Could not pull primaryGroupID\n"));
311 sid_compose(&group_sid
, samdb_domain_sid(state
->ldb
), n
);
312 pdb_set_group_sid(sam
, &group_sid
, PDB_SET
);
314 status
= NT_STATUS_OK
;
320 static bool pdb_samba_dsdb_add_time(struct ldb_message
*msg
,
321 const char *attrib
, time_t t
)
325 unix_to_nt_time(&nt_time
, t
);
327 return ldb_msg_add_fmt(msg
, attrib
, "%llu", (unsigned long long) nt_time
);
330 static int pdb_samba_dsdb_replace_by_sam(struct pdb_samba_dsdb_state
*state
,
331 bool (*need_update
)(const struct samu
*,
336 TALLOC_CTX
*frame
= talloc_stackframe();
337 int ret
= LDB_SUCCESS
;
339 struct ldb_message
*msg
;
340 struct ldb_request
*req
;
341 uint32_t dsdb_flags
= 0;
342 /* TODO: All fields :-) */
344 msg
= ldb_msg_new(frame
);
351 /* build modify request */
352 ret
= ldb_build_mod_req(&req
, state
->ldb
, frame
, msg
, NULL
, NULL
,
353 ldb_op_default_callback
,
355 if (ret
!= LDB_SUCCESS
) {
360 /* If we set a plaintext password, the system will
361 * force the pwdLastSet to now() */
362 if (need_update(sam
, PDB_PASSLASTSET
)) {
363 dsdb_flags
= DSDB_PASSWORD_BYPASS_LAST_SET
;
365 ret
|= pdb_samba_dsdb_add_time(msg
, "pwdLastSet",
366 pdb_get_pass_last_set_time(sam
));
369 pw
= pdb_get_plaintext_passwd(sam
);
370 if (need_update(sam
, PDB_PLAINTEXT_PW
)) {
371 struct ldb_val pw_utf16
;
374 return LDB_ERR_OPERATIONS_ERROR
;
377 if (!convert_string_talloc(msg
,
380 (void *)&pw_utf16
.data
,
382 return LDB_ERR_OPERATIONS_ERROR
;
384 ret
|= ldb_msg_add_value(msg
, "clearTextPassword", &pw_utf16
, NULL
);
386 bool changed_lm_pw
= false;
387 bool changed_nt_pw
= false;
388 bool changed_history
= false;
389 if (need_update(sam
, PDB_LMPASSWD
)) {
391 val
.data
= discard_const_p(uint8_t, pdb_get_lanman_passwd(sam
));
393 samdb_msg_add_delete(state
->ldb
, msg
, msg
,
396 val
.length
= LM_HASH_LEN
;
397 ret
|= ldb_msg_add_value(msg
, "dBCSPwd", &val
, NULL
);
399 changed_lm_pw
= true;
401 if (need_update(sam
, PDB_NTPASSWD
)) {
403 val
.data
= discard_const_p(uint8_t, pdb_get_nt_passwd(sam
));
405 samdb_msg_add_delete(state
->ldb
, msg
, msg
,
408 val
.length
= NT_HASH_LEN
;
409 ret
|= ldb_msg_add_value(msg
, "unicodePwd", &val
, NULL
);
411 changed_nt_pw
= true;
414 /* Try to ensure we don't get out of sync */
415 if (changed_lm_pw
&& !changed_nt_pw
) {
416 samdb_msg_add_delete(state
->ldb
, msg
, msg
,
418 } else if (changed_nt_pw
&& !changed_lm_pw
) {
419 samdb_msg_add_delete(state
->ldb
, msg
, msg
,
422 if (changed_lm_pw
|| changed_nt_pw
) {
423 samdb_msg_add_delete(state
->ldb
, msg
, msg
,
424 "supplementalCredentials");
428 if (need_update(sam
, PDB_PWHISTORY
)) {
429 uint32_t current_hist_len
;
430 const uint8_t *history
= pdb_get_pw_history(sam
, ¤t_hist_len
);
432 bool invalid_history
= false;
433 struct samr_Password
*history_hashes
= talloc_array(talloc_tos(), struct samr_Password
,
436 invalid_history
= true;
439 static const uint8_t zeros
[16];
440 /* Parse the history into the correct format */
441 for (i
= 0; i
< current_hist_len
; i
++) {
442 if (memcmp(&history
[i
*PW_HISTORY_ENTRY_LEN
], zeros
, 16) != 0) {
443 /* If the history is in the old format, with a salted hash, then we can't migrate it to AD format */
444 invalid_history
= true;
447 /* Copy out the 2nd 16 bytes of the 32 byte password history, containing the NT hash */
448 memcpy(history_hashes
[i
].hash
,
449 &history
[(i
*PW_HISTORY_ENTRY_LEN
) + PW_HISTORY_SALT_LEN
],
450 sizeof(history_hashes
[i
].hash
));
453 if (invalid_history
) {
454 ret
|= samdb_msg_add_delete(state
->ldb
, msg
, msg
,
457 ret
|= samdb_msg_add_delete(state
->ldb
, msg
, msg
,
460 ret
|= samdb_msg_add_hashes(state
->ldb
, msg
, msg
,
465 changed_history
= true;
467 if (changed_lm_pw
|| changed_nt_pw
|| changed_history
) {
468 /* These attributes can only be modified directly by using a special control */
469 dsdb_flags
= DSDB_BYPASS_PASSWORD_HASH
;
473 /* PDB_USERSID is only allowed on ADD, handled in caller */
474 if (need_update(sam
, PDB_GROUPSID
)) {
475 const struct dom_sid
*sid
= pdb_get_group_sid(sam
);
477 NTSTATUS status
= dom_sid_split_rid(NULL
, sid
, NULL
, &rid
);
478 if (!NT_STATUS_IS_OK(status
)) {
480 return LDB_ERR_OPERATIONS_ERROR
;
482 if (!dom_sid_in_domain(samdb_domain_sid(state
->ldb
), sid
)) {
484 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
486 ret
|= samdb_msg_add_uint(state
->ldb
, msg
, msg
, "primaryGroupID", rid
);
488 if (need_update(sam
, PDB_FULLNAME
)) {
489 ret
|= ldb_msg_add_string(msg
, "displayName", pdb_get_fullname(sam
));
492 if (need_update(sam
, PDB_SMBHOME
)) {
493 ret
|= ldb_msg_add_string(msg
, "homeDirectory",
494 pdb_get_homedir(sam
));
497 if (need_update(sam
, PDB_PROFILE
)) {
498 ret
|= ldb_msg_add_string(msg
, "profilePath",
499 pdb_get_profile_path(sam
));
502 if (need_update(sam
, PDB_DRIVE
)) {
503 ret
|= ldb_msg_add_string(msg
, "homeDrive",
504 pdb_get_dir_drive(sam
));
507 if (need_update(sam
, PDB_LOGONSCRIPT
)) {
508 ret
|= ldb_msg_add_string(msg
, "scriptPath",
509 pdb_get_logon_script(sam
));
512 if (need_update(sam
, PDB_KICKOFFTIME
)) {
513 ret
|= pdb_samba_dsdb_add_time(msg
, "accountExpires",
514 pdb_get_kickoff_time(sam
));
517 if (need_update(sam
, PDB_LOGONTIME
)) {
518 ret
|= pdb_samba_dsdb_add_time(msg
, "lastLogon",
519 pdb_get_logon_time(sam
));
522 if (need_update(sam
, PDB_LOGOFFTIME
)) {
523 ret
|= pdb_samba_dsdb_add_time(msg
, "lastLogoff",
524 pdb_get_logoff_time(sam
));
527 if (need_update(sam
, PDB_USERNAME
)) {
528 ret
|= ldb_msg_add_string(msg
, "samAccountName",
529 pdb_get_username(sam
));
532 if (need_update(sam
, PDB_HOURSLEN
) || need_update(sam
, PDB_HOURS
)) {
533 struct ldb_val hours
= data_blob_const(pdb_get_hours(sam
), pdb_get_hours_len(sam
));
534 ret
|= ldb_msg_add_value(msg
, "logonHours",
538 if (need_update(sam
, PDB_ACCTCTRL
)) {
539 ret
|= samdb_msg_add_acct_flags(state
->ldb
, msg
, msg
,
540 "userAccountControl", pdb_get_acct_ctrl(sam
));
543 if (need_update(sam
, PDB_COMMENT
)) {
544 ret
|= ldb_msg_add_string(msg
, "comment",
545 pdb_get_comment(sam
));
548 if (need_update(sam
, PDB_ACCTDESC
)) {
549 ret
|= ldb_msg_add_string(msg
, "description",
550 pdb_get_acct_desc(sam
));
553 if (need_update(sam
, PDB_WORKSTATIONS
)) {
554 ret
|= ldb_msg_add_string(msg
, "userWorkstations",
555 pdb_get_workstations(sam
));
558 /* This will need work, it is actually a UTF8 'string' with internal NULLs, to handle TS parameters */
559 if (need_update(sam
, PDB_MUNGEDDIAL
)) {
560 const char *base64_munged_dial
= NULL
;
562 base64_munged_dial
= pdb_get_munged_dial(sam
);
563 if (base64_munged_dial
!= NULL
&& strlen(base64_munged_dial
) > 0) {
566 blob
= base64_decode_data_blob_talloc(msg
,
568 if (blob
.data
== NULL
) {
569 DEBUG(0, ("Failed to decode userParameters from "
570 "munged dialback string[%s] for %s\n",
572 ldb_dn_get_linearized(msg
->dn
)));
574 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
576 ret
|= ldb_msg_add_steal_value(msg
, "userParameters",
581 if (need_update(sam
, PDB_COUNTRY_CODE
)) {
582 ret
|= ldb_msg_add_fmt(msg
, "countryCode",
583 "%i", (int)pdb_get_country_code(sam
));
586 if (need_update(sam
, PDB_CODE_PAGE
)) {
587 ret
|= ldb_msg_add_fmt(msg
, "codePage",
588 "%i", (int)pdb_get_code_page(sam
));
591 /* Not yet handled here or not meaningful for modifies on a Samba_Dsdb backend:
592 PDB_BAD_PASSWORD_TIME,
593 PDB_CANCHANGETIME, - these are calculated per policy, not stored
595 PDB_NTUSERNAME, - this makes no sense, and never really did
597 PDB_USERSID, - Handled in pdb_samba_dsdb_add_sam_account()
599 PDB_BAD_PASSWORD_COUNT,
602 PDB_BACKEND_PRIVATE_DATA,
605 if (ret
!= LDB_SUCCESS
) {
607 return LDB_ERR_OPERATIONS_ERROR
;
610 if (msg
->num_elements
== 0) {
612 /* Nothing to do, just return success */
616 ret
= dsdb_replace(state
->ldb
, msg
, dsdb_flags
);
618 if (ret
!= LDB_SUCCESS
) {
619 DEBUG(0,("Failed to modify account record %s to set user attributes: %s\n",
620 ldb_dn_get_linearized(msg
->dn
),
621 ldb_errstring(state
->ldb
)));
628 static NTSTATUS
pdb_samba_dsdb_getsamupriv(struct pdb_samba_dsdb_state
*state
,
631 struct ldb_message
**msg
)
633 const char * attrs
[] = {
634 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
635 "sAMAccountName", "displayName", "homeDirectory",
636 "homeDrive", "scriptPath", "profilePath", "description",
637 "userWorkstations", "comment", "userParameters", "objectSid",
638 "primaryGroupID", "userAccountControl", "logonHours",
639 "badPwdCount", "logonCount", "countryCode", "codePage",
640 "unicodePwd", "dBCSPwd", NULL
};
642 int rc
= dsdb_search_one(state
->ldb
, mem_ctx
, msg
, ldb_get_default_basedn(state
->ldb
), LDB_SCOPE_SUBTREE
, attrs
, 0, "%s", filter
);
643 if (rc
!= LDB_SUCCESS
) {
644 DEBUG(10, ("ldap_search failed %s\n",
645 ldb_errstring(state
->ldb
)));
646 return NT_STATUS_LDAP(rc
);
652 static NTSTATUS
pdb_samba_dsdb_getsampwfilter(struct pdb_methods
*m
,
653 struct pdb_samba_dsdb_state
*state
,
654 struct samu
*sam_acct
,
655 const char *exp_fmt
, ...) _PRINTF_ATTRIBUTE(4, 5)
657 struct ldb_message
*priv
;
660 char *expression
= NULL
;
661 TALLOC_CTX
*tmp_ctx
= talloc_new(state
);
662 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
664 va_start(ap
, exp_fmt
);
665 expression
= talloc_vasprintf(tmp_ctx
, exp_fmt
, ap
);
669 talloc_free(tmp_ctx
);
670 return NT_STATUS_NO_MEMORY
;
673 status
= pdb_samba_dsdb_getsamupriv(state
, expression
, sam_acct
, &priv
);
674 talloc_free(tmp_ctx
);
675 if (!NT_STATUS_IS_OK(status
)) {
676 DEBUG(10, ("pdb_samba_dsdb_getsamupriv failed: %s\n",
681 status
= pdb_samba_dsdb_init_sam_from_priv(m
, sam_acct
, priv
);
682 if (!NT_STATUS_IS_OK(status
)) {
683 DEBUG(10, ("pdb_samba_dsdb_init_sam_from_priv failed: %s\n",
689 pdb_set_backend_private_data(sam_acct
, priv
, NULL
, m
, PDB_SET
);
693 static NTSTATUS
pdb_samba_dsdb_getsampwnam(struct pdb_methods
*m
,
694 struct samu
*sam_acct
,
695 const char *username
)
697 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
698 m
->private_data
, struct pdb_samba_dsdb_state
);
700 return pdb_samba_dsdb_getsampwfilter(m
, state
, sam_acct
,
701 "(&(samaccountname=%s)(objectclass=user))",
705 static NTSTATUS
pdb_samba_dsdb_getsampwsid(struct pdb_methods
*m
,
706 struct samu
*sam_acct
,
707 const struct dom_sid
*sid
)
710 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
711 m
->private_data
, struct pdb_samba_dsdb_state
);
714 sidstr
= dom_sid_string(talloc_tos(), sid
);
715 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
717 status
= pdb_samba_dsdb_getsampwfilter(m
, state
, sam_acct
,
718 "(&(objectsid=%s)(objectclass=user))",
724 static NTSTATUS
pdb_samba_dsdb_create_user(struct pdb_methods
*m
,
726 const char *name
, uint32 acct_flags
,
729 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
730 m
->private_data
, struct pdb_samba_dsdb_state
);
734 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
735 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
737 /* Internally this uses transactions to ensure all the steps
738 * happen or fail as one */
739 status
= dsdb_add_user(state
->ldb
, tmp_ctx
, name
, acct_flags
, NULL
,
741 if (!NT_STATUS_IS_OK(status
)) {
742 talloc_free(tmp_ctx
);
745 sid_peek_rid(sid
, rid
);
746 talloc_free(tmp_ctx
);
750 static NTSTATUS
pdb_samba_dsdb_delete_user(struct pdb_methods
*m
,
754 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
755 m
->private_data
, struct pdb_samba_dsdb_state
);
758 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
759 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
761 dn
= ldb_dn_new_fmt(tmp_ctx
, state
->ldb
, "<SID=%s>", dom_sid_string(tmp_ctx
, pdb_get_user_sid(sam
)));
762 if (!dn
|| !ldb_dn_validate(dn
)) {
763 talloc_free(tmp_ctx
);
764 return NT_STATUS_NO_MEMORY
;
766 rc
= ldb_delete(state
->ldb
, dn
);
768 if (rc
!= LDB_SUCCESS
) {
769 DEBUG(10, ("ldb_delete for %s failed: %s\n", ldb_dn_get_linearized(dn
),
770 ldb_errstring(state
->ldb
)));
771 talloc_free(tmp_ctx
);
772 return NT_STATUS_LDAP(rc
);
774 talloc_free(tmp_ctx
);
778 /* This interface takes a fully populated struct samu and places it in
779 * the database. This is not implemented at this time as we need to
780 * be careful around the creation of arbitary SIDs (ie, we must ensrue
781 * they are not left in a RID pool */
782 static NTSTATUS
pdb_samba_dsdb_add_sam_account(struct pdb_methods
*m
,
783 struct samu
*sampass
)
788 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
789 m
->private_data
, struct pdb_samba_dsdb_state
);
790 uint32_t acb_flags
= pdb_get_acct_ctrl(sampass
);
791 const char *username
= pdb_get_username(sampass
);
792 const struct dom_sid
*user_sid
= pdb_get_user_sid(sampass
);
793 TALLOC_CTX
*tframe
= talloc_stackframe();
795 acb_flags
&= (ACB_NORMAL
|ACB_WSTRUST
|ACB_SVRTRUST
|ACB_DOMTRUST
);
797 ret
= ldb_transaction_start(state
->ldb
);
798 if (ret
!= LDB_SUCCESS
) {
800 return NT_STATUS_LOCK_NOT_GRANTED
;
803 status
= dsdb_add_user(state
->ldb
, talloc_tos(), username
,
804 acb_flags
, user_sid
, NULL
, &dn
);
805 if (!NT_STATUS_IS_OK(status
)) {
806 ldb_transaction_cancel(state
->ldb
);
811 ret
= pdb_samba_dsdb_replace_by_sam(state
, pdb_element_is_set_or_changed
,
813 if (ret
!= LDB_SUCCESS
) {
814 ldb_transaction_cancel(state
->ldb
);
816 return dsdb_ldb_err_to_ntstatus(ret
);
819 ret
= ldb_transaction_commit(state
->ldb
);
820 if (ret
!= LDB_SUCCESS
) {
821 DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
822 ldb_dn_get_linearized(dn
),
823 ldb_errstring(state
->ldb
)));
825 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
832 * Update the Samba_Dsdb LDB with the changes from a struct samu.
834 * This takes care not to update elements that have not been changed
837 static NTSTATUS
pdb_samba_dsdb_update_sam_account(struct pdb_methods
*m
,
840 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
841 m
->private_data
, struct pdb_samba_dsdb_state
);
842 struct ldb_message
*msg
= pdb_samba_dsdb_get_samu_private(
846 ret
= pdb_samba_dsdb_replace_by_sam(state
, pdb_element_is_changed
, msg
->dn
,
848 return dsdb_ldb_err_to_ntstatus(ret
);
851 static NTSTATUS
pdb_samba_dsdb_delete_sam_account(struct pdb_methods
*m
,
852 struct samu
*username
)
855 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
856 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
857 status
= pdb_samba_dsdb_delete_user(m
, tmp_ctx
, username
);
858 talloc_free(tmp_ctx
);
862 static NTSTATUS
pdb_samba_dsdb_rename_sam_account(struct pdb_methods
*m
,
863 struct samu
*oldname
,
866 return NT_STATUS_NOT_IMPLEMENTED
;
869 /* This is not implemented, as this module is exptected to be used
870 * with auth_samba_dsdb, and this is responible for login counters etc
873 static NTSTATUS
pdb_samba_dsdb_update_login_attempts(struct pdb_methods
*m
,
874 struct samu
*sam_acct
,
877 return NT_STATUS_NOT_IMPLEMENTED
;
880 static NTSTATUS
pdb_samba_dsdb_getgrfilter(struct pdb_methods
*m
, GROUP_MAP
*map
,
881 const char *exp_fmt
, ...) _PRINTF_ATTRIBUTE(4, 5)
883 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
884 m
->private_data
, struct pdb_samba_dsdb_state
);
885 const char *attrs
[] = { "objectClass", "objectSid", "description", "samAccountName", "groupType",
887 struct ldb_message
*msg
;
889 char *expression
= NULL
;
893 struct id_map id_map
;
894 struct id_map
*id_maps
[2];
895 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
896 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
898 va_start(ap
, exp_fmt
);
899 expression
= talloc_vasprintf(tmp_ctx
, exp_fmt
, ap
);
903 talloc_free(tmp_ctx
);
904 return NT_STATUS_NO_MEMORY
;
907 rc
= dsdb_search_one(state
->ldb
, tmp_ctx
, &msg
, ldb_get_default_basedn(state
->ldb
), LDB_SCOPE_SUBTREE
, attrs
, 0, "%s", expression
);
908 if (rc
== LDB_ERR_NO_SUCH_OBJECT
) {
909 talloc_free(tmp_ctx
);
910 return NT_STATUS_NO_SUCH_GROUP
;
911 } else if (rc
!= LDB_SUCCESS
) {
912 talloc_free(tmp_ctx
);
913 DEBUG(10, ("dsdb_search_one failed %s\n",
914 ldb_errstring(state
->ldb
)));
915 return NT_STATUS_LDAP(rc
);
918 sid
= samdb_result_dom_sid(tmp_ctx
, msg
, "objectSid");
920 talloc_free(tmp_ctx
);
921 DEBUG(10, ("Could not pull SID\n"));
922 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
927 if (samdb_find_attribute(state
->ldb
, msg
, "objectClass", "group")) {
929 uint32_t grouptype
= ldb_msg_find_attr_as_uint(msg
, "groupType", 0);
931 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
:
932 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
:
933 map
->sid_name_use
= SID_NAME_ALIAS
;
935 case GTYPE_SECURITY_GLOBAL_GROUP
:
936 map
->sid_name_use
= SID_NAME_DOM_GRP
;
939 talloc_free(tmp_ctx
);
940 DEBUG(10, ("Could not pull groupType\n"));
941 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
946 id_maps
[0] = &id_map
;
949 status
= idmap_sids_to_xids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
951 if (!NT_STATUS_IS_OK(status
)) {
952 talloc_free(tmp_ctx
);
955 if (id_map
.xid
.type
== ID_TYPE_GID
|| id_map
.xid
.type
== ID_TYPE_BOTH
) {
956 map
->gid
= id_map
.xid
.id
;
958 DEBUG(1, (__location__
"Did not get GUID when mapping SID for %s", expression
));
959 talloc_free(tmp_ctx
);
960 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
962 } else if (samdb_find_attribute(state
->ldb
, msg
, "objectClass", "user")) {
963 DEBUG(1, (__location__
"Got SID_NAME_USER when searching for a group with %s", expression
));
964 talloc_free(tmp_ctx
);
965 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
968 str
= ldb_msg_find_attr_as_string(msg
, "samAccountName",
971 talloc_free(tmp_ctx
);
972 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
974 map
->nt_name
= talloc_strdup(map
, str
);
976 talloc_free(tmp_ctx
);
977 return NT_STATUS_NO_MEMORY
;
980 str
= ldb_msg_find_attr_as_string(msg
, "description",
983 map
->comment
= talloc_strdup(map
, str
);
985 map
->comment
= talloc_strdup(map
, "");
988 talloc_free(tmp_ctx
);
989 return NT_STATUS_NO_MEMORY
;
992 talloc_free(tmp_ctx
);
996 static NTSTATUS
pdb_samba_dsdb_getgrsid(struct pdb_methods
*m
, GROUP_MAP
*map
,
1002 filter
= talloc_asprintf(talloc_tos(),
1003 "(&(objectsid=%s)(objectclass=group))",
1004 sid_string_talloc(talloc_tos(), &sid
));
1005 if (filter
== NULL
) {
1006 return NT_STATUS_NO_MEMORY
;
1009 status
= pdb_samba_dsdb_getgrfilter(m
, map
, filter
);
1010 TALLOC_FREE(filter
);
1014 static NTSTATUS
pdb_samba_dsdb_getgrgid(struct pdb_methods
*m
, GROUP_MAP
*map
,
1017 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1018 m
->private_data
, struct pdb_samba_dsdb_state
);
1020 struct id_map id_map
;
1021 struct id_map
*id_maps
[2];
1022 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1023 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1025 id_map
.xid
.id
= gid
;
1026 id_map
.xid
.type
= ID_TYPE_GID
;
1027 id_maps
[0] = &id_map
;
1030 status
= idmap_xids_to_sids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
1031 if (!NT_STATUS_IS_OK(status
)) {
1034 status
= pdb_samba_dsdb_getgrsid(m
, map
, *id_map
.sid
);
1035 talloc_free(tmp_ctx
);
1039 static NTSTATUS
pdb_samba_dsdb_getgrnam(struct pdb_methods
*m
, GROUP_MAP
*map
,
1045 filter
= talloc_asprintf(talloc_tos(),
1046 "(&(samaccountname=%s)(objectclass=group))",
1048 if (filter
== NULL
) {
1049 return NT_STATUS_NO_MEMORY
;
1052 status
= pdb_samba_dsdb_getgrfilter(m
, map
, filter
);
1053 TALLOC_FREE(filter
);
1057 static NTSTATUS
pdb_samba_dsdb_create_dom_group(struct pdb_methods
*m
,
1058 TALLOC_CTX
*mem_ctx
, const char *name
,
1061 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1062 m
->private_data
, struct pdb_samba_dsdb_state
);
1064 struct dom_sid
*sid
;
1066 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1067 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1069 status
= dsdb_add_domain_group(state
->ldb
, tmp_ctx
, name
, &sid
, &dn
);
1070 if (!NT_STATUS_IS_OK(status
)) {
1071 talloc_free(tmp_ctx
);
1075 sid_peek_rid(sid
, rid
);
1076 talloc_free(tmp_ctx
);
1077 return NT_STATUS_OK
;
1080 static NTSTATUS
pdb_samba_dsdb_delete_dom_group(struct pdb_methods
*m
,
1081 TALLOC_CTX
*mem_ctx
, uint32 rid
)
1083 const char *attrs
[] = { NULL
};
1084 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1085 m
->private_data
, struct pdb_samba_dsdb_state
);
1087 struct ldb_message
*msg
;
1090 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1091 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1093 sid_compose(&sid
, samdb_domain_sid(state
->ldb
), rid
);
1095 if (ldb_transaction_start(state
->ldb
) != LDB_SUCCESS
) {
1096 DEBUG(0, ("Unable to start transaction in pdb_samba_dsdb_delete_dom_group()\n"));
1097 return NT_STATUS_INTERNAL_ERROR
;
1100 dn
= ldb_dn_new_fmt(tmp_ctx
, state
->ldb
, "<SID=%s>", dom_sid_string(tmp_ctx
, &sid
));
1101 if (!dn
|| !ldb_dn_validate(dn
)) {
1102 talloc_free(tmp_ctx
);
1103 ldb_transaction_cancel(state
->ldb
);
1104 return NT_STATUS_NO_MEMORY
;
1106 rc
= dsdb_search_one(state
->ldb
, tmp_ctx
, &msg
, dn
, LDB_SCOPE_BASE
, attrs
, 0, "objectclass=group");
1107 if (rc
== LDB_ERR_NO_SUCH_OBJECT
) {
1108 talloc_free(tmp_ctx
);
1109 ldb_transaction_cancel(state
->ldb
);
1110 return NT_STATUS_NO_SUCH_GROUP
;
1112 rc
= ldb_delete(state
->ldb
, dn
);
1113 if (rc
== LDB_ERR_NO_SUCH_OBJECT
) {
1114 talloc_free(tmp_ctx
);
1115 ldb_transaction_cancel(state
->ldb
);
1116 return NT_STATUS_NO_SUCH_GROUP
;
1117 } else if (rc
!= LDB_SUCCESS
) {
1118 DEBUG(10, ("ldb_delete failed %s\n",
1119 ldb_errstring(state
->ldb
)));
1120 ldb_transaction_cancel(state
->ldb
);
1121 return NT_STATUS_LDAP(rc
);
1124 if (ldb_transaction_commit(state
->ldb
) != LDB_SUCCESS
) {
1125 DEBUG(0, ("Unable to commit transaction in pdb_samba_dsdb_delete_dom_group()\n"));
1126 return NT_STATUS_INTERNAL_ERROR
;
1128 return NT_STATUS_OK
;
1131 static NTSTATUS
pdb_samba_dsdb_add_group_mapping_entry(struct pdb_methods
*m
,
1134 return NT_STATUS_NOT_IMPLEMENTED
;
1137 static NTSTATUS
pdb_samba_dsdb_update_group_mapping_entry(struct pdb_methods
*m
,
1140 return NT_STATUS_NOT_IMPLEMENTED
;
1143 static NTSTATUS
pdb_samba_dsdb_delete_group_mapping_entry(struct pdb_methods
*m
,
1146 return NT_STATUS_NOT_IMPLEMENTED
;
1149 static NTSTATUS
pdb_samba_dsdb_enum_group_mapping(struct pdb_methods
*m
,
1150 const struct dom_sid
*sid
,
1151 enum lsa_SidType sid_name_use
,
1152 GROUP_MAP
***pp_rmap
,
1153 size_t *p_num_entries
,
1156 return NT_STATUS_NOT_IMPLEMENTED
;
1159 static NTSTATUS
pdb_samba_dsdb_enum_group_members(struct pdb_methods
*m
,
1160 TALLOC_CTX
*mem_ctx
,
1161 const struct dom_sid
*group
,
1162 uint32_t **pmembers
,
1163 size_t *pnum_members
)
1165 unsigned int i
, num_sids
, num_members
;
1166 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1167 m
->private_data
, struct pdb_samba_dsdb_state
);
1168 struct dom_sid
*members_as_sids
;
1169 struct dom_sid
*dom_sid
;
1174 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1175 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1177 dn
= ldb_dn_new_fmt(tmp_ctx
, state
->ldb
, "<SID=%s>", dom_sid_string(tmp_ctx
, group
));
1178 if (!dn
|| !ldb_dn_validate(dn
)) {
1179 return NT_STATUS_NO_MEMORY
;
1182 status
= dsdb_enum_group_mem(state
->ldb
, tmp_ctx
, dn
, &members_as_sids
, &num_sids
);
1183 if (!NT_STATUS_IS_OK(status
)) {
1184 talloc_free(tmp_ctx
);
1187 status
= dom_sid_split_rid(tmp_ctx
, group
, &dom_sid
, NULL
);
1188 if (!NT_STATUS_IS_OK(status
)) {
1189 talloc_free(tmp_ctx
);
1193 *pmembers
= members
= talloc_array(mem_ctx
, uint32_t, num_sids
);
1194 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*pmembers
, tmp_ctx
);
1197 for (i
= 0; i
< num_sids
; i
++) {
1198 if (!dom_sid_in_domain(dom_sid
, &members_as_sids
[i
])) {
1201 status
= dom_sid_split_rid(NULL
, &members_as_sids
[i
],
1202 NULL
, &members
[num_members
]);
1203 if (!NT_STATUS_IS_OK(status
)) {
1204 talloc_free(tmp_ctx
);
1209 *pnum_members
= num_members
;
1210 return NT_STATUS_OK
;
1213 /* Just convert the primary group SID into a group */
1214 static NTSTATUS
fake_enum_group_memberships(struct pdb_samba_dsdb_state
*state
,
1215 TALLOC_CTX
*mem_ctx
,
1217 struct dom_sid
**pp_sids
,
1219 uint32_t *p_num_groups
)
1222 size_t num_groups
= 0;
1223 struct dom_sid
*group_sids
= NULL
;
1225 TALLOC_CTX
*tmp_ctx
;
1227 tmp_ctx
= talloc_new(mem_ctx
);
1228 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1230 if (user
->group_sid
) {
1231 struct id_map
*id_maps
[2];
1232 struct id_map id_map
;
1236 group_sids
= talloc_array(tmp_ctx
, struct dom_sid
, num_groups
);
1237 if (group_sids
== NULL
) {
1238 talloc_free(tmp_ctx
);
1239 return NT_STATUS_NO_MEMORY
;
1241 gids
= talloc_array(tmp_ctx
, gid_t
, num_groups
);
1243 talloc_free(tmp_ctx
);
1244 return NT_STATUS_NO_MEMORY
;
1247 group_sids
[0] = *user
->group_sid
;
1249 ZERO_STRUCT(id_map
);
1250 id_map
.sid
= &group_sids
[0];
1251 id_maps
[0] = &id_map
;
1254 status
= idmap_sids_to_xids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
1255 if (!NT_STATUS_IS_OK(status
)) {
1256 talloc_free(tmp_ctx
);
1259 if (id_map
.xid
.type
== ID_TYPE_GID
|| id_map
.xid
.type
== ID_TYPE_BOTH
) {
1260 gids
[0] = id_map
.xid
.id
;
1262 DEBUG(1, (__location__
1263 "Group %s, of which %s is a member, could not be converted to a GID\n",
1264 dom_sid_string(tmp_ctx
, &group_sids
[0]),
1265 dom_sid_string(tmp_ctx
, &user
->user_sid
)));
1266 talloc_free(tmp_ctx
);
1267 /* We must error out, otherwise a user might
1268 * avoid a DENY acl based on a group they
1270 return NT_STATUS_NO_SUCH_GROUP
;
1274 *pp_sids
= talloc_steal(mem_ctx
, group_sids
);
1275 *pp_gids
= talloc_steal(mem_ctx
, gids
);
1276 *p_num_groups
= num_groups
;
1277 talloc_free(tmp_ctx
);
1278 return NT_STATUS_OK
;
1281 static NTSTATUS
pdb_samba_dsdb_enum_group_memberships(struct pdb_methods
*m
,
1282 TALLOC_CTX
*mem_ctx
,
1284 struct dom_sid
**pp_sids
,
1286 uint32_t *p_num_groups
)
1288 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1289 m
->private_data
, struct pdb_samba_dsdb_state
);
1290 struct ldb_message
*msg
= pdb_samba_dsdb_get_samu_private(
1292 const char *attrs
[] = { "tokenGroups", NULL
};
1293 struct ldb_message
*tokengroups_msg
;
1294 struct ldb_message_element
*tokengroups
;
1297 unsigned int count
= 0;
1299 struct dom_sid
*group_sids
;
1301 TALLOC_CTX
*tmp_ctx
;
1304 /* Fake up some things here */
1305 return fake_enum_group_memberships(state
,
1308 pp_gids
, p_num_groups
);
1311 tmp_ctx
= talloc_new(mem_ctx
);
1312 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1314 rc
= dsdb_search_one(state
->ldb
, tmp_ctx
, &tokengroups_msg
, msg
->dn
, LDB_SCOPE_BASE
, attrs
, 0, NULL
);
1316 if (rc
== LDB_ERR_NO_SUCH_OBJECT
) {
1317 talloc_free(tmp_ctx
);
1318 return NT_STATUS_NO_SUCH_USER
;
1319 } else if (rc
!= LDB_SUCCESS
) {
1320 DEBUG(10, ("dsdb_search_one failed %s\n",
1321 ldb_errstring(state
->ldb
)));
1322 talloc_free(tmp_ctx
);
1323 return NT_STATUS_LDAP(rc
);
1326 tokengroups
= ldb_msg_find_element(tokengroups_msg
, "tokenGroups");
1329 count
= tokengroups
->num_values
;
1332 group_sids
= talloc_array(tmp_ctx
, struct dom_sid
, count
);
1333 if (group_sids
== NULL
) {
1334 talloc_free(tmp_ctx
);
1335 return NT_STATUS_NO_MEMORY
;
1337 gids
= talloc_array(tmp_ctx
, gid_t
, count
);
1339 talloc_free(tmp_ctx
);
1340 return NT_STATUS_NO_MEMORY
;
1344 for (i
=0; i
<count
; i
++) {
1345 struct id_map
*id_maps
[2];
1346 struct id_map id_map
;
1347 struct ldb_val
*v
= &tokengroups
->values
[i
];
1348 enum ndr_err_code ndr_err
1349 = ndr_pull_struct_blob(v
, group_sids
, &group_sids
[num_groups
],
1350 (ndr_pull_flags_fn_t
)ndr_pull_dom_sid
);
1351 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1352 talloc_free(tmp_ctx
);
1353 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1356 ZERO_STRUCT(id_map
);
1357 id_map
.sid
= &group_sids
[num_groups
];
1358 id_maps
[0] = &id_map
;
1361 status
= idmap_sids_to_xids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
1362 if (!NT_STATUS_IS_OK(status
)) {
1363 talloc_free(tmp_ctx
);
1366 if (id_map
.xid
.type
== ID_TYPE_GID
|| id_map
.xid
.type
== ID_TYPE_BOTH
) {
1367 gids
[num_groups
] = id_map
.xid
.id
;
1369 DEBUG(1, (__location__
1370 "Group %s, of which %s is a member, could not be converted to a GID\n",
1371 dom_sid_string(tmp_ctx
, &group_sids
[num_groups
]),
1372 ldb_dn_get_linearized(msg
->dn
)));
1373 talloc_free(tmp_ctx
);
1374 /* We must error out, otherwise a user might
1375 * avoid a DENY acl based on a group they
1377 return NT_STATUS_NO_SUCH_GROUP
;
1381 if (num_groups
== count
) {
1386 *pp_sids
= talloc_steal(mem_ctx
, group_sids
);
1387 *pp_gids
= talloc_steal(mem_ctx
, gids
);
1388 *p_num_groups
= num_groups
;
1389 talloc_free(tmp_ctx
);
1390 return NT_STATUS_OK
;
1393 static NTSTATUS
pdb_samba_dsdb_set_unix_primary_group(struct pdb_methods
*m
,
1394 TALLOC_CTX
*mem_ctx
,
1397 return NT_STATUS_NOT_IMPLEMENTED
;
1400 static NTSTATUS
pdb_samba_dsdb_mod_groupmem_by_sid(struct pdb_methods
*m
,
1401 TALLOC_CTX
*mem_ctx
,
1402 const struct dom_sid
*groupsid
,
1403 const struct dom_sid
*membersid
,
1406 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1407 m
->private_data
, struct pdb_samba_dsdb_state
);
1408 struct ldb_message
*msg
;
1410 struct ldb_message_element
*el
;
1411 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1412 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1413 msg
= ldb_msg_new(tmp_ctx
);
1414 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg
, tmp_ctx
);
1416 msg
->dn
= ldb_dn_new_fmt(msg
, state
->ldb
, "<SID=%s>", dom_sid_string(tmp_ctx
, groupsid
));
1417 if (!msg
->dn
|| !ldb_dn_validate(msg
->dn
)) {
1418 talloc_free(tmp_ctx
);
1419 return NT_STATUS_NO_MEMORY
;
1421 ret
= ldb_msg_add_fmt(msg
, "member", "<SID=%s>", dom_sid_string(tmp_ctx
, membersid
));
1422 if (ret
!= LDB_SUCCESS
) {
1423 talloc_free(tmp_ctx
);
1424 return NT_STATUS_NO_MEMORY
;
1426 el
= ldb_msg_find_element(msg
, "member");
1429 /* No need for transactions here, the ldb auto-transaction
1430 * code will handle things for the single operation */
1431 ret
= ldb_modify(state
->ldb
, msg
);
1432 talloc_free(tmp_ctx
);
1433 if (ret
!= LDB_SUCCESS
) {
1434 DEBUG(10, ("ldb_modify failed: %s\n",
1435 ldb_errstring(state
->ldb
)));
1436 if (ret
== LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS
) {
1437 return NT_STATUS_MEMBER_IN_GROUP
;
1439 if (ret
== LDB_ERR_NO_SUCH_ATTRIBUTE
) {
1440 return NT_STATUS_MEMBER_NOT_IN_GROUP
;
1442 return NT_STATUS_LDAP(ret
);
1445 return NT_STATUS_OK
;
1448 static NTSTATUS
pdb_samba_dsdb_mod_groupmem(struct pdb_methods
*m
,
1449 TALLOC_CTX
*mem_ctx
,
1450 uint32 grouprid
, uint32 memberrid
,
1453 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1454 m
->private_data
, struct pdb_samba_dsdb_state
);
1455 const struct dom_sid
*dom_sid
, *groupsid
, *membersid
;
1457 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1458 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1460 dom_sid
= samdb_domain_sid(state
->ldb
);
1462 groupsid
= dom_sid_add_rid(tmp_ctx
, dom_sid
, grouprid
);
1463 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupsid
, tmp_ctx
);
1464 membersid
= dom_sid_add_rid(tmp_ctx
, dom_sid
, memberrid
);
1465 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(membersid
, tmp_ctx
);
1466 status
= pdb_samba_dsdb_mod_groupmem_by_sid(m
, tmp_ctx
, groupsid
, membersid
, mod_op
);
1467 talloc_free(tmp_ctx
);
1471 static NTSTATUS
pdb_samba_dsdb_add_groupmem(struct pdb_methods
*m
,
1472 TALLOC_CTX
*mem_ctx
,
1473 uint32 group_rid
, uint32 member_rid
)
1475 return pdb_samba_dsdb_mod_groupmem(m
, mem_ctx
, group_rid
, member_rid
,
1479 static NTSTATUS
pdb_samba_dsdb_del_groupmem(struct pdb_methods
*m
,
1480 TALLOC_CTX
*mem_ctx
,
1481 uint32 group_rid
, uint32 member_rid
)
1483 return pdb_samba_dsdb_mod_groupmem(m
, mem_ctx
, group_rid
, member_rid
,
1484 LDB_FLAG_MOD_DELETE
);
1487 static NTSTATUS
pdb_samba_dsdb_create_alias(struct pdb_methods
*m
,
1488 const char *name
, uint32
*rid
)
1490 TALLOC_CTX
*frame
= talloc_stackframe();
1491 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1492 m
->private_data
, struct pdb_samba_dsdb_state
);
1493 struct dom_sid
*sid
;
1498 /* Internally this uses transactions to ensure all the steps
1499 * happen or fail as one */
1500 status
= dsdb_add_domain_alias(state
->ldb
, frame
, name
, &sid
, &dn
);
1501 if (!NT_STATUS_IS_OK(status
)) {
1505 sid_peek_rid(sid
, rid
);
1507 return NT_STATUS_OK
;
1510 static NTSTATUS
pdb_samba_dsdb_delete_alias(struct pdb_methods
*m
,
1511 const struct dom_sid
*sid
)
1513 const char *attrs
[] = { NULL
};
1514 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1515 m
->private_data
, struct pdb_samba_dsdb_state
);
1516 struct ldb_message
*msg
;
1519 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1520 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1522 dn
= ldb_dn_new_fmt(tmp_ctx
, state
->ldb
, "<SID=%s>", dom_sid_string(tmp_ctx
, sid
));
1523 if (!dn
|| !ldb_dn_validate(dn
)) {
1524 talloc_free(tmp_ctx
);
1525 return NT_STATUS_NO_MEMORY
;
1528 if (ldb_transaction_start(state
->ldb
) != LDB_SUCCESS
) {
1529 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state
->ldb
)));
1530 return NT_STATUS_INTERNAL_ERROR
;
1533 rc
= dsdb_search_one(state
->ldb
, tmp_ctx
, &msg
, dn
, LDB_SCOPE_BASE
, attrs
, 0, "(objectclass=group)"
1534 "(|(grouptype=%d)(grouptype=%d)))",
1535 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1536 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1537 if (rc
== LDB_ERR_NO_SUCH_OBJECT
) {
1538 talloc_free(tmp_ctx
);
1539 ldb_transaction_cancel(state
->ldb
);
1540 return NT_STATUS_NO_SUCH_ALIAS
;
1542 rc
= ldb_delete(state
->ldb
, dn
);
1543 if (rc
== LDB_ERR_NO_SUCH_OBJECT
) {
1544 talloc_free(tmp_ctx
);
1545 ldb_transaction_cancel(state
->ldb
);
1546 return NT_STATUS_NO_SUCH_ALIAS
;
1547 } else if (rc
!= LDB_SUCCESS
) {
1548 DEBUG(10, ("ldb_delete failed %s\n",
1549 ldb_errstring(state
->ldb
)));
1550 ldb_transaction_cancel(state
->ldb
);
1551 return NT_STATUS_LDAP(rc
);
1554 if (ldb_transaction_commit(state
->ldb
) != LDB_SUCCESS
) {
1555 DEBUG(0, ("Failed to commit transaction in pdb_samba_dsdb_delete_alias(): %s\n",
1556 ldb_errstring(state
->ldb
)));
1557 return NT_STATUS_INTERNAL_ERROR
;
1560 return NT_STATUS_OK
;
1564 static NTSTATUS
pdb_samba_dsdb_set_aliasinfo(struct pdb_methods
*m
,
1565 const struct dom_sid
*sid
,
1566 struct acct_info
*info
)
1568 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1569 m
->private_data
, struct pdb_samba_dsdb_state
);
1570 struct tldap_context
*ld
;
1571 const char *attrs
[3] = { "objectSid", "description",
1573 struct ldb_message
**msg
;
1576 struct tldap_mod
*mods
;
1580 ld
= pdb_samba_dsdb_ld(state
);
1582 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1585 sidstr
= sid_binstring(talloc_tos(), sid
);
1586 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1588 rc
= pdb_samba_dsdb_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1589 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1590 &msg
, "(&(objectSid=%s)(objectclass=group)"
1591 "(|(grouptype=%d)(grouptype=%d)))",
1592 sidstr
, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1593 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1595 if (rc
!= LDB_SUCCESS
) {
1596 DEBUG(10, ("ldap_search failed %s\n",
1597 ldb_errstring(state
->ldb
)));
1598 return NT_STATUS_LDAP(rc
);
1600 switch talloc_array_length(msg
) {
1602 return NT_STATUS_NO_SUCH_ALIAS
;
1606 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1609 if (!tldap_entry_dn(msg
[0], &dn
)) {
1611 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1618 ok
&= tldap_make_mod_fmt(
1619 msg
[0], msg
, &num_mods
, &mods
, "description",
1620 "%s", info
->acct_desc
);
1621 ok
&= tldap_make_mod_fmt(
1622 msg
[0], msg
, &num_mods
, &mods
, "samAccountName",
1623 "%s", info
->acct_name
);
1626 return NT_STATUS_NO_MEMORY
;
1628 if (num_mods
== 0) {
1631 return NT_STATUS_OK
;
1634 rc
= tldap_modify(ld
, dn
, num_mods
, mods
, NULL
, 0, NULL
, 0);
1636 if (rc
!= LDB_SUCCESS
) {
1637 DEBUG(10, ("ldap_modify failed: %s\n",
1638 ldb_errstring(state
->ldb
)));
1639 return NT_STATUS_LDAP(rc
);
1641 return NT_STATUS_OK
;
1644 static NTSTATUS
pdb_samba_dsdb_add_aliasmem(struct pdb_methods
*m
,
1645 const struct dom_sid
*alias
,
1646 const struct dom_sid
*member
)
1649 TALLOC_CTX
*frame
= talloc_stackframe();
1650 status
= pdb_samba_dsdb_mod_groupmem_by_sid(m
, frame
, alias
, member
, LDB_FLAG_MOD_ADD
);
1655 static NTSTATUS
pdb_samba_dsdb_del_aliasmem(struct pdb_methods
*m
,
1656 const struct dom_sid
*alias
,
1657 const struct dom_sid
*member
)
1660 TALLOC_CTX
*frame
= talloc_stackframe();
1661 status
= pdb_samba_dsdb_mod_groupmem_by_sid(m
, frame
, alias
, member
, LDB_FLAG_MOD_DELETE
);
1666 static NTSTATUS
pdb_samba_dsdb_enum_aliasmem(struct pdb_methods
*m
,
1667 const struct dom_sid
*alias
,
1668 TALLOC_CTX
*mem_ctx
,
1669 struct dom_sid
**pmembers
,
1670 size_t *pnum_members
)
1672 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1673 m
->private_data
, struct pdb_samba_dsdb_state
);
1675 unsigned int num_members
;
1677 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1678 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1680 dn
= ldb_dn_new_fmt(tmp_ctx
, state
->ldb
, "<SID=%s>", dom_sid_string(tmp_ctx
, alias
));
1681 if (!dn
|| !ldb_dn_validate(dn
)) {
1682 return NT_STATUS_NO_MEMORY
;
1685 status
= dsdb_enum_group_mem(state
->ldb
, mem_ctx
, dn
, pmembers
, &num_members
);
1686 *pnum_members
= num_members
;
1687 if (NT_STATUS_IS_OK(status
)) {
1688 talloc_steal(mem_ctx
, pmembers
);
1690 talloc_free(tmp_ctx
);
1694 static NTSTATUS
pdb_samba_dsdb_enum_alias_memberships(struct pdb_methods
*m
,
1695 TALLOC_CTX
*mem_ctx
,
1696 const struct dom_sid
*domain_sid
,
1697 const struct dom_sid
*members
,
1699 uint32_t **palias_rids
,
1700 size_t *pnum_alias_rids
)
1702 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1703 m
->private_data
, struct pdb_samba_dsdb_state
);
1704 uint32_t *alias_rids
= NULL
;
1705 size_t num_alias_rids
= 0;
1707 struct dom_sid
*groupSIDs
= NULL
;
1708 unsigned int num_groupSIDs
= 0;
1711 const char *sid_string
;
1715 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1716 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1718 * TODO: Get the filter right so that we only get the aliases from
1719 * either the SAM or BUILTIN
1722 filter
= talloc_asprintf(tmp_ctx
, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1723 GROUP_TYPE_BUILTIN_LOCAL_GROUP
);
1724 if (filter
== NULL
) {
1725 return NT_STATUS_NO_MEMORY
;
1728 for (i
= 0; i
< num_members
; i
++) {
1729 sid_string
= dom_sid_string(tmp_ctx
, &members
[i
]);
1730 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string
, tmp_ctx
);
1732 sid_dn
= talloc_asprintf(tmp_ctx
, "<SID=%s>", sid_string
);
1733 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn
, tmp_ctx
);
1735 sid_blob
= data_blob_string_const(sid_dn
);
1737 status
= dsdb_expand_nested_groups(state
->ldb
, &sid_blob
, true, filter
,
1738 tmp_ctx
, &groupSIDs
, &num_groupSIDs
);
1739 if (!NT_STATUS_IS_OK(status
)) {
1740 talloc_free(tmp_ctx
);
1745 alias_rids
= talloc_array(mem_ctx
, uint32_t, num_groupSIDs
);
1746 if (alias_rids
== NULL
) {
1747 talloc_free(tmp_ctx
);
1748 return NT_STATUS_NO_MEMORY
;
1751 for (i
=0; i
<num_groupSIDs
; i
++) {
1752 if (sid_peek_check_rid(domain_sid
, &groupSIDs
[i
],
1753 &alias_rids
[num_alias_rids
])) {
1758 *palias_rids
= alias_rids
;
1759 *pnum_alias_rids
= num_alias_rids
;
1760 return NT_STATUS_OK
;
1763 static NTSTATUS
pdb_samba_dsdb_lookup_rids(struct pdb_methods
*m
,
1764 const struct dom_sid
*domain_sid
,
1768 enum lsa_SidType
*lsa_attrs
)
1770 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1771 m
->private_data
, struct pdb_samba_dsdb_state
);
1774 TALLOC_CTX
*tmp_ctx
;
1776 if (num_rids
== 0) {
1777 return NT_STATUS_NONE_MAPPED
;
1780 tmp_ctx
= talloc_stackframe();
1781 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1783 status
= dsdb_lookup_rids(state
->ldb
, tmp_ctx
, domain_sid
, num_rids
, rids
, names
, lsa_attrs
);
1784 talloc_free(tmp_ctx
);
1788 static NTSTATUS
pdb_samba_dsdb_lookup_names(struct pdb_methods
*m
,
1789 const struct dom_sid
*domain_sid
,
1791 const char **pp_names
,
1793 enum lsa_SidType
*attrs
)
1795 return NT_STATUS_NOT_IMPLEMENTED
;
1798 static NTSTATUS
pdb_samba_dsdb_get_account_policy(struct pdb_methods
*m
,
1799 enum pdb_policy_type type
,
1802 return account_policy_get(type
, value
)
1803 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1806 static NTSTATUS
pdb_samba_dsdb_set_account_policy(struct pdb_methods
*m
,
1807 enum pdb_policy_type type
,
1810 return account_policy_set(type
, value
)
1811 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1814 static NTSTATUS
pdb_samba_dsdb_get_seq_num(struct pdb_methods
*m
,
1815 time_t *seq_num_out
)
1817 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1818 m
->private_data
, struct pdb_samba_dsdb_state
);
1820 int ret
= ldb_sequence_number(state
->ldb
, LDB_SEQ_HIGHEST_SEQ
, &seq_num
);
1821 if (ret
== LDB_SUCCESS
) {
1822 *seq_num_out
= seq_num
;
1823 return NT_STATUS_OK
;
1825 return NT_STATUS_UNSUCCESSFUL
;
1829 struct pdb_samba_dsdb_search_state
{
1830 uint32_t acct_flags
;
1831 struct samr_displayentry
*entries
;
1832 uint32_t num_entries
;
1837 static bool pdb_samba_dsdb_next_entry(struct pdb_search
*search
,
1838 struct samr_displayentry
*entry
)
1840 struct pdb_samba_dsdb_search_state
*state
= talloc_get_type_abort(
1841 search
->private_data
, struct pdb_samba_dsdb_search_state
);
1843 if (state
->current
== state
->num_entries
) {
1847 entry
->idx
= state
->entries
[state
->current
].idx
;
1848 entry
->rid
= state
->entries
[state
->current
].rid
;
1849 entry
->acct_flags
= state
->entries
[state
->current
].acct_flags
;
1851 entry
->account_name
= talloc_strdup(
1852 search
, state
->entries
[state
->current
].account_name
);
1853 entry
->fullname
= talloc_strdup(
1854 search
, state
->entries
[state
->current
].fullname
);
1855 entry
->description
= talloc_strdup(
1856 search
, state
->entries
[state
->current
].description
);
1858 state
->current
+= 1;
1862 static void pdb_samba_dsdb_search_end(struct pdb_search
*search
)
1864 struct pdb_samba_dsdb_search_state
*state
= talloc_get_type_abort(
1865 search
->private_data
, struct pdb_samba_dsdb_search_state
);
1869 static bool pdb_samba_dsdb_search_filter(struct pdb_methods
*m
,
1870 struct pdb_search
*search
,
1871 struct pdb_samba_dsdb_search_state
**pstate
,
1872 const char *exp_fmt
, ...) _PRINTF_ATTRIBUTE(4, 5)
1874 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1875 m
->private_data
, struct pdb_samba_dsdb_state
);
1876 struct pdb_samba_dsdb_search_state
*sstate
;
1877 const char * attrs
[] = { "objectSid", "sAMAccountName", "displayName",
1878 "userAccountControl", "description", NULL
};
1879 struct ldb_result
*res
;
1880 int i
, rc
, num_users
;
1883 char *expression
= NULL
;
1885 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1890 va_start(ap
, exp_fmt
);
1891 expression
= talloc_vasprintf(tmp_ctx
, exp_fmt
, ap
);
1895 talloc_free(tmp_ctx
);
1896 return LDB_ERR_OPERATIONS_ERROR
;
1899 sstate
= talloc_zero(tmp_ctx
, struct pdb_samba_dsdb_search_state
);
1900 if (sstate
== NULL
) {
1901 talloc_free(tmp_ctx
);
1905 rc
= dsdb_search(state
->ldb
, tmp_ctx
, &res
, ldb_get_default_basedn(state
->ldb
), LDB_SCOPE_SUBTREE
, attrs
, 0, "%s", expression
);
1906 if (rc
!= LDB_SUCCESS
) {
1907 talloc_free(tmp_ctx
);
1908 DEBUG(10, ("dsdb_search failed: %s\n",
1909 ldb_errstring(state
->ldb
)));
1913 num_users
= res
->count
;
1915 sstate
->entries
= talloc_array(sstate
, struct samr_displayentry
,
1917 if (sstate
->entries
== NULL
) {
1918 talloc_free(tmp_ctx
);
1919 DEBUG(10, ("talloc failed\n"));
1923 sstate
->num_entries
= 0;
1925 for (i
=0; i
<num_users
; i
++) {
1926 struct samr_displayentry
*e
;
1927 struct dom_sid
*sid
;
1929 e
= &sstate
->entries
[sstate
->num_entries
];
1931 e
->idx
= sstate
->num_entries
;
1932 sid
= samdb_result_dom_sid(tmp_ctx
, res
->msgs
[i
], "objectSid");
1934 talloc_free(tmp_ctx
);
1935 DEBUG(10, ("Could not pull SID\n"));
1938 sid_peek_rid(sid
, &e
->rid
);
1940 e
->acct_flags
= samdb_result_acct_flags(state
->ldb
, tmp_ctx
,
1942 ldb_get_default_basedn(state
->ldb
));
1943 e
->account_name
= ldb_msg_find_attr_as_string(
1944 res
->msgs
[i
], "samAccountName", NULL
);
1945 if (e
->account_name
== NULL
) {
1946 talloc_free(tmp_ctx
);
1949 e
->fullname
= ldb_msg_find_attr_as_string(
1950 res
->msgs
[i
], "displayName", "");
1951 e
->description
= ldb_msg_find_attr_as_string(
1952 res
->msgs
[i
], "description", "");
1954 sstate
->num_entries
+= 1;
1955 if (sstate
->num_entries
>= num_users
) {
1959 talloc_steal(sstate
->entries
, res
->msgs
);
1960 search
->private_data
= talloc_steal(search
, sstate
);
1961 search
->next_entry
= pdb_samba_dsdb_next_entry
;
1962 search
->search_end
= pdb_samba_dsdb_search_end
;
1964 talloc_free(tmp_ctx
);
1968 static bool pdb_samba_dsdb_search_users(struct pdb_methods
*m
,
1969 struct pdb_search
*search
,
1972 struct pdb_samba_dsdb_search_state
*sstate
;
1975 ret
= pdb_samba_dsdb_search_filter(m
, search
, &sstate
, "(objectclass=user)");
1979 sstate
->acct_flags
= acct_flags
;
1983 static bool pdb_samba_dsdb_search_groups(struct pdb_methods
*m
,
1984 struct pdb_search
*search
)
1986 struct pdb_samba_dsdb_search_state
*sstate
;
1989 ret
= pdb_samba_dsdb_search_filter(m
, search
, &sstate
,
1990 "(&(grouptype=%d)(objectclass=group))",
1991 GTYPE_SECURITY_GLOBAL_GROUP
);
1995 sstate
->acct_flags
= 0;
1999 static bool pdb_samba_dsdb_search_aliases(struct pdb_methods
*m
,
2000 struct pdb_search
*search
,
2001 const struct dom_sid
*sid
)
2003 struct pdb_samba_dsdb_search_state
*sstate
;
2006 ret
= pdb_samba_dsdb_search_filter(m
, search
, &sstate
,
2007 "(&(grouptype=%d)(objectclass=group))",
2008 sid_check_is_builtin(sid
)
2009 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2010 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
2014 sstate
->acct_flags
= 0;
2018 static bool pdb_samba_dsdb_uid_to_sid(struct pdb_methods
*m
, uid_t uid
,
2019 struct dom_sid
*sid
)
2021 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
2022 m
->private_data
, struct pdb_samba_dsdb_state
);
2024 struct id_map id_map
;
2025 struct id_map
*id_maps
[2];
2026 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2031 id_map
.xid
.id
= uid
;
2032 id_map
.xid
.type
= ID_TYPE_UID
;
2033 id_maps
[0] = &id_map
;
2036 status
= idmap_xids_to_sids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
2037 if (!NT_STATUS_IS_OK(status
)) {
2038 talloc_free(tmp_ctx
);
2042 talloc_free(tmp_ctx
);
2046 static bool pdb_samba_dsdb_gid_to_sid(struct pdb_methods
*m
, gid_t gid
,
2047 struct dom_sid
*sid
)
2049 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
2050 m
->private_data
, struct pdb_samba_dsdb_state
);
2052 struct id_map id_map
;
2053 struct id_map
*id_maps
[2];
2054 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2059 id_map
.xid
.id
= gid
;
2060 id_map
.xid
.type
= ID_TYPE_GID
;
2061 id_maps
[0] = &id_map
;
2064 status
= idmap_xids_to_sids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
2065 if (!NT_STATUS_IS_OK(status
)) {
2069 talloc_free(tmp_ctx
);
2073 static bool pdb_samba_dsdb_sid_to_id(struct pdb_methods
*m
, const struct dom_sid
*sid
,
2076 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
2077 m
->private_data
, struct pdb_samba_dsdb_state
);
2078 struct id_map id_map
;
2079 struct id_map
*id_maps
[2];
2081 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2086 ZERO_STRUCT(id_map
);
2087 id_map
.sid
= discard_const_p(struct dom_sid
, sid
);
2088 id_maps
[0] = &id_map
;
2091 status
= idmap_sids_to_xids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
2092 talloc_free(tmp_ctx
);
2093 if (!NT_STATUS_IS_OK(status
)) {
2096 if (id_map
.xid
.type
!= ID_TYPE_NOT_SPECIFIED
) {
2103 static uint32_t pdb_samba_dsdb_capabilities(struct pdb_methods
*m
)
2105 return PDB_CAP_STORE_RIDS
| PDB_CAP_ADS
;
2108 static bool pdb_samba_dsdb_new_rid(struct pdb_methods
*m
, uint32
*rid
)
2113 static bool pdb_samba_dsdb_get_trusteddom_pw(struct pdb_methods
*m
,
2114 const char *domain
, char** pwd
,
2115 struct dom_sid
*sid
,
2116 time_t *pass_last_set_time
)
2121 static bool pdb_samba_dsdb_set_trusteddom_pw(struct pdb_methods
*m
,
2122 const char* domain
, const char* pwd
,
2123 const struct dom_sid
*sid
)
2128 static bool pdb_samba_dsdb_del_trusteddom_pw(struct pdb_methods
*m
,
2134 static NTSTATUS
pdb_samba_dsdb_enum_trusteddoms(struct pdb_methods
*m
,
2135 TALLOC_CTX
*mem_ctx
,
2136 uint32
*num_domains
,
2137 struct trustdom_info
***domains
)
2141 return NT_STATUS_OK
;
2144 static bool pdb_samba_dsdb_is_responsible_for_wellknown(struct pdb_methods
*m
)
2149 static void pdb_samba_dsdb_init_methods(struct pdb_methods
*m
)
2151 m
->name
= "samba_dsdb";
2152 m
->get_domain_info
= pdb_samba_dsdb_get_domain_info
;
2153 m
->getsampwnam
= pdb_samba_dsdb_getsampwnam
;
2154 m
->getsampwsid
= pdb_samba_dsdb_getsampwsid
;
2155 m
->create_user
= pdb_samba_dsdb_create_user
;
2156 m
->delete_user
= pdb_samba_dsdb_delete_user
;
2157 m
->add_sam_account
= pdb_samba_dsdb_add_sam_account
;
2158 m
->update_sam_account
= pdb_samba_dsdb_update_sam_account
;
2159 m
->delete_sam_account
= pdb_samba_dsdb_delete_sam_account
;
2160 m
->rename_sam_account
= pdb_samba_dsdb_rename_sam_account
;
2161 m
->update_login_attempts
= pdb_samba_dsdb_update_login_attempts
;
2162 m
->getgrsid
= pdb_samba_dsdb_getgrsid
;
2163 m
->getgrgid
= pdb_samba_dsdb_getgrgid
;
2164 m
->getgrnam
= pdb_samba_dsdb_getgrnam
;
2165 m
->create_dom_group
= pdb_samba_dsdb_create_dom_group
;
2166 m
->delete_dom_group
= pdb_samba_dsdb_delete_dom_group
;
2167 m
->add_group_mapping_entry
= pdb_samba_dsdb_add_group_mapping_entry
;
2168 m
->update_group_mapping_entry
= pdb_samba_dsdb_update_group_mapping_entry
;
2169 m
->delete_group_mapping_entry
= pdb_samba_dsdb_delete_group_mapping_entry
;
2170 m
->enum_group_mapping
= pdb_samba_dsdb_enum_group_mapping
;
2171 m
->enum_group_members
= pdb_samba_dsdb_enum_group_members
;
2172 m
->enum_group_memberships
= pdb_samba_dsdb_enum_group_memberships
;
2173 m
->set_unix_primary_group
= pdb_samba_dsdb_set_unix_primary_group
;
2174 m
->add_groupmem
= pdb_samba_dsdb_add_groupmem
;
2175 m
->del_groupmem
= pdb_samba_dsdb_del_groupmem
;
2176 m
->create_alias
= pdb_samba_dsdb_create_alias
;
2177 m
->delete_alias
= pdb_samba_dsdb_delete_alias
;
2178 m
->get_aliasinfo
= pdb_default_get_aliasinfo
;
2179 m
->add_aliasmem
= pdb_samba_dsdb_add_aliasmem
;
2180 m
->del_aliasmem
= pdb_samba_dsdb_del_aliasmem
;
2181 m
->enum_aliasmem
= pdb_samba_dsdb_enum_aliasmem
;
2182 m
->enum_alias_memberships
= pdb_samba_dsdb_enum_alias_memberships
;
2183 m
->lookup_rids
= pdb_samba_dsdb_lookup_rids
;
2184 m
->lookup_names
= pdb_samba_dsdb_lookup_names
;
2185 m
->get_account_policy
= pdb_samba_dsdb_get_account_policy
;
2186 m
->set_account_policy
= pdb_samba_dsdb_set_account_policy
;
2187 m
->get_seq_num
= pdb_samba_dsdb_get_seq_num
;
2188 m
->search_users
= pdb_samba_dsdb_search_users
;
2189 m
->search_groups
= pdb_samba_dsdb_search_groups
;
2190 m
->search_aliases
= pdb_samba_dsdb_search_aliases
;
2191 m
->uid_to_sid
= pdb_samba_dsdb_uid_to_sid
;
2192 m
->gid_to_sid
= pdb_samba_dsdb_gid_to_sid
;
2193 m
->sid_to_id
= pdb_samba_dsdb_sid_to_id
;
2194 m
->capabilities
= pdb_samba_dsdb_capabilities
;
2195 m
->new_rid
= pdb_samba_dsdb_new_rid
;
2196 m
->get_trusteddom_pw
= pdb_samba_dsdb_get_trusteddom_pw
;
2197 m
->set_trusteddom_pw
= pdb_samba_dsdb_set_trusteddom_pw
;
2198 m
->del_trusteddom_pw
= pdb_samba_dsdb_del_trusteddom_pw
;
2199 m
->enum_trusteddoms
= pdb_samba_dsdb_enum_trusteddoms
;
2200 m
->is_responsible_for_wellknown
=
2201 pdb_samba_dsdb_is_responsible_for_wellknown
;
2204 static void free_private_data(void **vp
)
2206 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
2207 *vp
, struct pdb_samba_dsdb_state
);
2208 talloc_unlink(state
, state
->ldb
);
2212 static NTSTATUS
pdb_samba_dsdb_init_secrets(struct pdb_methods
*m
)
2214 struct pdb_domain_info
*dom_info
;
2215 struct dom_sid stored_sid
;
2216 struct GUID stored_guid
;
2217 bool sid_exists_and_matches
= false;
2218 bool guid_exists_and_matches
= false;
2221 dom_info
= pdb_samba_dsdb_get_domain_info(m
, m
);
2223 return NT_STATUS_UNSUCCESSFUL
;
2226 ret
= secrets_fetch_domain_sid(dom_info
->name
, &stored_sid
);
2228 if (dom_sid_equal(&stored_sid
, &dom_info
->sid
)) {
2229 sid_exists_and_matches
= true;
2233 if (sid_exists_and_matches
== false) {
2234 secrets_clear_domain_protection(dom_info
->name
);
2235 ret
= secrets_store_domain_sid(dom_info
->name
,
2237 ret
&= secrets_mark_domain_protected(dom_info
->name
);
2243 ret
= secrets_fetch_domain_guid(dom_info
->name
, &stored_guid
);
2245 if (GUID_equal(&stored_guid
, &dom_info
->guid
)) {
2246 guid_exists_and_matches
= true;
2250 if (guid_exists_and_matches
== false) {
2251 secrets_clear_domain_protection(dom_info
->name
);
2252 ret
= secrets_store_domain_guid(dom_info
->name
,
2254 ret
&= secrets_mark_domain_protected(dom_info
->name
);
2261 TALLOC_FREE(dom_info
);
2263 return NT_STATUS_UNSUCCESSFUL
;
2265 return NT_STATUS_OK
;
2268 static NTSTATUS
pdb_init_samba_dsdb(struct pdb_methods
**pdb_method
,
2269 const char *location
)
2271 struct pdb_methods
*m
;
2272 struct pdb_samba_dsdb_state
*state
;
2275 if ( !NT_STATUS_IS_OK(status
= make_pdb_method( &m
)) ) {
2279 state
= talloc_zero(m
, struct pdb_samba_dsdb_state
);
2280 if (state
== NULL
) {
2283 m
->private_data
= state
;
2284 m
->free_private_data
= free_private_data
;
2285 pdb_samba_dsdb_init_methods(m
);
2287 state
->ev
= s4_event_context_init(state
);
2289 DEBUG(0, ("s4_event_context_init failed\n"));
2293 state
->lp_ctx
= loadparm_init_s3(state
, loadparm_s3_helpers());
2294 if (state
->lp_ctx
== NULL
) {
2295 DEBUG(0, ("loadparm_init_s3 failed\n"));
2300 state
->ldb
= samdb_connect_url(state
,
2303 system_session(state
->lp_ctx
),
2306 state
->ldb
= samdb_connect(state
,
2309 system_session(state
->lp_ctx
), 0);
2313 DEBUG(0, ("samdb_connect failed\n"));
2314 status
= NT_STATUS_INTERNAL_ERROR
;
2318 state
->idmap_ctx
= idmap_init(state
, state
->ev
,
2320 if (!state
->idmap_ctx
) {
2321 DEBUG(0, ("idmap failed\n"));
2322 status
= NT_STATUS_INTERNAL_ERROR
;
2326 status
= pdb_samba_dsdb_init_secrets(m
);
2327 if (!NT_STATUS_IS_OK(status
)) {
2328 DEBUG(10, ("pdb_samba_dsdb_init_secrets failed!\n"));
2333 return NT_STATUS_OK
;
2335 status
= NT_STATUS_NO_MEMORY
;
2341 NTSTATUS
pdb_samba_dsdb_init(void);
2342 NTSTATUS
pdb_samba_dsdb_init(void)
2344 NTSTATUS status
= smb_register_passdb(PASSDB_INTERFACE_VERSION
, "samba_dsdb",
2345 pdb_init_samba_dsdb
);
2346 if (!NT_STATUS_IS_OK(status
)) {
2349 return smb_register_passdb(PASSDB_INTERFACE_VERSION
, "samba4",
2350 pdb_init_samba_dsdb
);