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
= 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
= 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 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*pmembers
, tmp_ctx
);
1178 for (i
= 0; i
< num_sids
; i
++) {
1179 if (!dom_sid_in_domain(dom_sid
, &members_as_sids
[i
])) {
1182 status
= dom_sid_split_rid(NULL
, &members_as_sids
[i
],
1183 NULL
, &members
[num_members
]);
1184 if (!NT_STATUS_IS_OK(status
)) {
1185 talloc_free(tmp_ctx
);
1190 *pnum_members
= num_members
;
1191 return NT_STATUS_OK
;
1194 /* Just convert the primary group SID into a group */
1195 static NTSTATUS
fake_enum_group_memberships(struct pdb_samba_dsdb_state
*state
,
1196 TALLOC_CTX
*mem_ctx
,
1198 struct dom_sid
**pp_sids
,
1200 uint32_t *p_num_groups
)
1203 size_t num_groups
= 0;
1204 struct dom_sid
*group_sids
;
1206 TALLOC_CTX
*tmp_ctx
;
1208 tmp_ctx
= talloc_new(mem_ctx
);
1209 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1211 if (user
->group_sid
) {
1212 struct id_map
*id_maps
[2];
1213 struct id_map id_map
;
1217 group_sids
= talloc_array(tmp_ctx
, struct dom_sid
, num_groups
);
1218 if (group_sids
== NULL
) {
1219 talloc_free(tmp_ctx
);
1220 return NT_STATUS_NO_MEMORY
;
1222 gids
= talloc_array(tmp_ctx
, gid_t
, num_groups
);
1224 talloc_free(tmp_ctx
);
1225 return NT_STATUS_NO_MEMORY
;
1228 group_sids
[0] = *user
->group_sid
;
1230 ZERO_STRUCT(id_map
);
1231 id_map
.sid
= &group_sids
[0];
1232 id_maps
[0] = &id_map
;
1235 status
= idmap_sids_to_xids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
1236 if (!NT_STATUS_IS_OK(status
)) {
1237 talloc_free(tmp_ctx
);
1240 if (id_map
.xid
.type
== ID_TYPE_GID
|| id_map
.xid
.type
== ID_TYPE_BOTH
) {
1241 gids
[0] = id_map
.xid
.id
;
1243 DEBUG(1, (__location__
1244 "Group %s, of which %s is a member, could not be converted to a GID\n",
1245 dom_sid_string(tmp_ctx
, &group_sids
[0]),
1246 dom_sid_string(tmp_ctx
, &user
->user_sid
)));
1247 talloc_free(tmp_ctx
);
1248 /* We must error out, otherwise a user might
1249 * avoid a DENY acl based on a group they
1251 return NT_STATUS_NO_SUCH_GROUP
;
1255 *pp_sids
= talloc_steal(mem_ctx
, group_sids
);
1256 *pp_gids
= talloc_steal(mem_ctx
, gids
);
1257 *p_num_groups
= num_groups
;
1258 talloc_free(tmp_ctx
);
1259 return NT_STATUS_OK
;
1262 static NTSTATUS
pdb_samba_dsdb_enum_group_memberships(struct pdb_methods
*m
,
1263 TALLOC_CTX
*mem_ctx
,
1265 struct dom_sid
**pp_sids
,
1267 uint32_t *p_num_groups
)
1269 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1270 m
->private_data
, struct pdb_samba_dsdb_state
);
1271 struct ldb_message
*msg
= pdb_samba_dsdb_get_samu_private(
1273 const char *attrs
[] = { "tokenGroups", NULL
};
1274 struct ldb_message
*tokengroups_msg
;
1275 struct ldb_message_element
*tokengroups
;
1278 unsigned int count
= 0;
1280 struct dom_sid
*group_sids
;
1282 TALLOC_CTX
*tmp_ctx
;
1285 /* Fake up some things here */
1286 return fake_enum_group_memberships(state
,
1289 pp_gids
, p_num_groups
);
1292 tmp_ctx
= talloc_new(mem_ctx
);
1293 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1295 rc
= dsdb_search_one(state
->ldb
, tmp_ctx
, &tokengroups_msg
, msg
->dn
, LDB_SCOPE_BASE
, attrs
, 0, NULL
);
1297 if (rc
== LDB_ERR_NO_SUCH_OBJECT
) {
1298 talloc_free(tmp_ctx
);
1299 return NT_STATUS_NO_SUCH_USER
;
1300 } else if (rc
!= LDB_SUCCESS
) {
1301 DEBUG(10, ("dsdb_search_one failed %s\n",
1302 ldb_errstring(state
->ldb
)));
1303 talloc_free(tmp_ctx
);
1304 return NT_STATUS_LDAP(rc
);
1307 tokengroups
= ldb_msg_find_element(tokengroups_msg
, "tokenGroups");
1310 count
= tokengroups
->num_values
;
1313 group_sids
= talloc_array(tmp_ctx
, struct dom_sid
, count
);
1314 if (group_sids
== NULL
) {
1315 talloc_free(tmp_ctx
);
1316 return NT_STATUS_NO_MEMORY
;
1318 gids
= talloc_array(tmp_ctx
, gid_t
, count
);
1320 talloc_free(tmp_ctx
);
1321 return NT_STATUS_NO_MEMORY
;
1325 for (i
=0; i
<count
; i
++) {
1326 struct id_map
*id_maps
[2];
1327 struct id_map id_map
;
1328 struct ldb_val
*v
= &tokengroups
->values
[i
];
1329 enum ndr_err_code ndr_err
1330 = ndr_pull_struct_blob(v
, group_sids
, &group_sids
[num_groups
],
1331 (ndr_pull_flags_fn_t
)ndr_pull_dom_sid
);
1332 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1333 talloc_free(tmp_ctx
);
1334 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1337 ZERO_STRUCT(id_map
);
1338 id_map
.sid
= &group_sids
[num_groups
];
1339 id_maps
[0] = &id_map
;
1342 status
= idmap_sids_to_xids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
1343 if (!NT_STATUS_IS_OK(status
)) {
1344 talloc_free(tmp_ctx
);
1347 if (id_map
.xid
.type
== ID_TYPE_GID
|| id_map
.xid
.type
== ID_TYPE_BOTH
) {
1348 gids
[num_groups
] = id_map
.xid
.id
;
1350 DEBUG(1, (__location__
1351 "Group %s, of which %s is a member, could not be converted to a GID\n",
1352 dom_sid_string(tmp_ctx
, &group_sids
[num_groups
]),
1353 ldb_dn_get_linearized(msg
->dn
)));
1354 talloc_free(tmp_ctx
);
1355 /* We must error out, otherwise a user might
1356 * avoid a DENY acl based on a group they
1358 return NT_STATUS_NO_SUCH_GROUP
;
1362 if (num_groups
== count
) {
1367 *pp_sids
= talloc_steal(mem_ctx
, group_sids
);
1368 *pp_gids
= talloc_steal(mem_ctx
, gids
);
1369 *p_num_groups
= num_groups
;
1370 talloc_free(tmp_ctx
);
1371 return NT_STATUS_OK
;
1374 static NTSTATUS
pdb_samba_dsdb_set_unix_primary_group(struct pdb_methods
*m
,
1375 TALLOC_CTX
*mem_ctx
,
1378 return NT_STATUS_NOT_IMPLEMENTED
;
1381 static NTSTATUS
pdb_samba_dsdb_mod_groupmem_by_sid(struct pdb_methods
*m
,
1382 TALLOC_CTX
*mem_ctx
,
1383 const struct dom_sid
*groupsid
,
1384 const struct dom_sid
*membersid
,
1387 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1388 m
->private_data
, struct pdb_samba_dsdb_state
);
1389 struct ldb_message
*msg
;
1391 struct ldb_message_element
*el
;
1392 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1393 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1394 msg
= ldb_msg_new(tmp_ctx
);
1395 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg
, tmp_ctx
);
1397 msg
->dn
= ldb_dn_new_fmt(msg
, state
->ldb
, "<SID=%s>", dom_sid_string(tmp_ctx
, groupsid
));
1398 if (!msg
->dn
|| !ldb_dn_validate(msg
->dn
)) {
1399 talloc_free(tmp_ctx
);
1400 return NT_STATUS_NO_MEMORY
;
1402 ret
= ldb_msg_add_fmt(msg
, "member", "<SID=%s>", dom_sid_string(tmp_ctx
, membersid
));
1403 if (ret
!= LDB_SUCCESS
) {
1404 talloc_free(tmp_ctx
);
1405 return NT_STATUS_NO_MEMORY
;
1407 el
= ldb_msg_find_element(msg
, "member");
1410 /* No need for transactions here, the ldb auto-transaction
1411 * code will handle things for the single operation */
1412 ret
= ldb_modify(state
->ldb
, msg
);
1413 talloc_free(tmp_ctx
);
1414 if (ret
!= LDB_SUCCESS
) {
1415 DEBUG(10, ("ldb_modify failed: %s\n",
1416 ldb_errstring(state
->ldb
)));
1417 if (ret
== LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS
) {
1418 return NT_STATUS_MEMBER_IN_GROUP
;
1420 if (ret
== LDB_ERR_NO_SUCH_ATTRIBUTE
) {
1421 return NT_STATUS_MEMBER_NOT_IN_GROUP
;
1423 return NT_STATUS_LDAP(ret
);
1426 return NT_STATUS_OK
;
1429 static NTSTATUS
pdb_samba_dsdb_mod_groupmem(struct pdb_methods
*m
,
1430 TALLOC_CTX
*mem_ctx
,
1431 uint32 grouprid
, uint32 memberrid
,
1434 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1435 m
->private_data
, struct pdb_samba_dsdb_state
);
1436 const struct dom_sid
*dom_sid
, *groupsid
, *membersid
;
1438 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1439 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1441 dom_sid
= samdb_domain_sid(state
->ldb
);
1443 groupsid
= dom_sid_add_rid(tmp_ctx
, dom_sid
, grouprid
);
1444 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupsid
, tmp_ctx
);
1445 membersid
= dom_sid_add_rid(tmp_ctx
, dom_sid
, memberrid
);
1446 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(membersid
, tmp_ctx
);
1447 status
= pdb_samba_dsdb_mod_groupmem_by_sid(m
, tmp_ctx
, groupsid
, membersid
, mod_op
);
1448 talloc_free(tmp_ctx
);
1452 static NTSTATUS
pdb_samba_dsdb_add_groupmem(struct pdb_methods
*m
,
1453 TALLOC_CTX
*mem_ctx
,
1454 uint32 group_rid
, uint32 member_rid
)
1456 return pdb_samba_dsdb_mod_groupmem(m
, mem_ctx
, group_rid
, member_rid
,
1460 static NTSTATUS
pdb_samba_dsdb_del_groupmem(struct pdb_methods
*m
,
1461 TALLOC_CTX
*mem_ctx
,
1462 uint32 group_rid
, uint32 member_rid
)
1464 return pdb_samba_dsdb_mod_groupmem(m
, mem_ctx
, group_rid
, member_rid
,
1465 LDB_FLAG_MOD_DELETE
);
1468 static NTSTATUS
pdb_samba_dsdb_create_alias(struct pdb_methods
*m
,
1469 const char *name
, uint32
*rid
)
1471 TALLOC_CTX
*frame
= talloc_stackframe();
1472 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1473 m
->private_data
, struct pdb_samba_dsdb_state
);
1474 struct dom_sid
*sid
;
1479 /* Internally this uses transactions to ensure all the steps
1480 * happen or fail as one */
1481 status
= dsdb_add_domain_alias(state
->ldb
, frame
, name
, &sid
, &dn
);
1482 if (!NT_STATUS_IS_OK(status
)) {
1486 sid_peek_rid(sid
, rid
);
1488 return NT_STATUS_OK
;
1491 static NTSTATUS
pdb_samba_dsdb_delete_alias(struct pdb_methods
*m
,
1492 const struct dom_sid
*sid
)
1494 const char *attrs
[] = { NULL
};
1495 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1496 m
->private_data
, struct pdb_samba_dsdb_state
);
1497 struct ldb_message
*msg
;
1500 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1501 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1503 dn
= ldb_dn_new_fmt(tmp_ctx
, state
->ldb
, "<SID=%s>", dom_sid_string(tmp_ctx
, sid
));
1504 if (!dn
|| !ldb_dn_validate(dn
)) {
1505 talloc_free(tmp_ctx
);
1506 return NT_STATUS_NO_MEMORY
;
1509 if (ldb_transaction_start(state
->ldb
) != LDB_SUCCESS
) {
1510 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state
->ldb
)));
1511 return NT_STATUS_INTERNAL_ERROR
;
1514 rc
= dsdb_search_one(state
->ldb
, tmp_ctx
, &msg
, dn
, LDB_SCOPE_BASE
, attrs
, 0, "(objectclass=group)"
1515 "(|(grouptype=%d)(grouptype=%d)))",
1516 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1517 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1518 if (rc
== LDB_ERR_NO_SUCH_OBJECT
) {
1519 talloc_free(tmp_ctx
);
1520 ldb_transaction_cancel(state
->ldb
);
1521 return NT_STATUS_NO_SUCH_ALIAS
;
1523 rc
= ldb_delete(state
->ldb
, dn
);
1524 if (rc
== LDB_ERR_NO_SUCH_OBJECT
) {
1525 talloc_free(tmp_ctx
);
1526 ldb_transaction_cancel(state
->ldb
);
1527 return NT_STATUS_NO_SUCH_ALIAS
;
1528 } else if (rc
!= LDB_SUCCESS
) {
1529 DEBUG(10, ("ldb_delete failed %s\n",
1530 ldb_errstring(state
->ldb
)));
1531 ldb_transaction_cancel(state
->ldb
);
1532 return NT_STATUS_LDAP(rc
);
1535 if (ldb_transaction_commit(state
->ldb
) != LDB_SUCCESS
) {
1536 DEBUG(0, ("Failed to commit transaction in pdb_samba_dsdb_delete_alias(): %s\n",
1537 ldb_errstring(state
->ldb
)));
1538 return NT_STATUS_INTERNAL_ERROR
;
1541 return NT_STATUS_OK
;
1545 static NTSTATUS
pdb_samba_dsdb_set_aliasinfo(struct pdb_methods
*m
,
1546 const struct dom_sid
*sid
,
1547 struct acct_info
*info
)
1549 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1550 m
->private_data
, struct pdb_samba_dsdb_state
);
1551 struct tldap_context
*ld
;
1552 const char *attrs
[3] = { "objectSid", "description",
1554 struct ldb_message
**msg
;
1557 struct tldap_mod
*mods
;
1561 ld
= pdb_samba_dsdb_ld(state
);
1563 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1566 sidstr
= sid_binstring(talloc_tos(), sid
);
1567 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1569 rc
= pdb_samba_dsdb_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1570 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1571 &msg
, "(&(objectSid=%s)(objectclass=group)"
1572 "(|(grouptype=%d)(grouptype=%d)))",
1573 sidstr
, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1574 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1576 if (rc
!= LDB_SUCCESS
) {
1577 DEBUG(10, ("ldap_search failed %s\n",
1578 ldb_errstring(state
->ldb
)));
1579 return NT_STATUS_LDAP(rc
);
1581 switch talloc_array_length(msg
) {
1583 return NT_STATUS_NO_SUCH_ALIAS
;
1587 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1590 if (!tldap_entry_dn(msg
[0], &dn
)) {
1592 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1599 ok
&= tldap_make_mod_fmt(
1600 msg
[0], msg
, &num_mods
, &mods
, "description",
1601 "%s", info
->acct_desc
);
1602 ok
&= tldap_make_mod_fmt(
1603 msg
[0], msg
, &num_mods
, &mods
, "samAccountName",
1604 "%s", info
->acct_name
);
1607 return NT_STATUS_NO_MEMORY
;
1609 if (num_mods
== 0) {
1612 return NT_STATUS_OK
;
1615 rc
= tldap_modify(ld
, dn
, num_mods
, mods
, NULL
, 0, NULL
, 0);
1617 if (rc
!= LDB_SUCCESS
) {
1618 DEBUG(10, ("ldap_modify failed: %s\n",
1619 ldb_errstring(state
->ldb
)));
1620 return NT_STATUS_LDAP(rc
);
1622 return NT_STATUS_OK
;
1625 static NTSTATUS
pdb_samba_dsdb_add_aliasmem(struct pdb_methods
*m
,
1626 const struct dom_sid
*alias
,
1627 const struct dom_sid
*member
)
1630 TALLOC_CTX
*frame
= talloc_stackframe();
1631 status
= pdb_samba_dsdb_mod_groupmem_by_sid(m
, frame
, alias
, member
, LDB_FLAG_MOD_ADD
);
1636 static NTSTATUS
pdb_samba_dsdb_del_aliasmem(struct pdb_methods
*m
,
1637 const struct dom_sid
*alias
,
1638 const struct dom_sid
*member
)
1641 TALLOC_CTX
*frame
= talloc_stackframe();
1642 status
= pdb_samba_dsdb_mod_groupmem_by_sid(m
, frame
, alias
, member
, LDB_FLAG_MOD_DELETE
);
1647 static NTSTATUS
pdb_samba_dsdb_enum_aliasmem(struct pdb_methods
*m
,
1648 const struct dom_sid
*alias
,
1649 TALLOC_CTX
*mem_ctx
,
1650 struct dom_sid
**pmembers
,
1651 size_t *pnum_members
)
1653 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1654 m
->private_data
, struct pdb_samba_dsdb_state
);
1656 unsigned int num_members
;
1658 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1659 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1661 dn
= ldb_dn_new_fmt(tmp_ctx
, state
->ldb
, "<SID=%s>", dom_sid_string(tmp_ctx
, alias
));
1662 if (!dn
|| !ldb_dn_validate(dn
)) {
1663 return NT_STATUS_NO_MEMORY
;
1666 status
= dsdb_enum_group_mem(state
->ldb
, mem_ctx
, dn
, pmembers
, &num_members
);
1667 *pnum_members
= num_members
;
1668 if (NT_STATUS_IS_OK(status
)) {
1669 talloc_steal(mem_ctx
, pmembers
);
1671 talloc_free(tmp_ctx
);
1675 static NTSTATUS
pdb_samba_dsdb_enum_alias_memberships(struct pdb_methods
*m
,
1676 TALLOC_CTX
*mem_ctx
,
1677 const struct dom_sid
*domain_sid
,
1678 const struct dom_sid
*members
,
1680 uint32_t **palias_rids
,
1681 size_t *pnum_alias_rids
)
1683 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1684 m
->private_data
, struct pdb_samba_dsdb_state
);
1685 uint32_t *alias_rids
= NULL
;
1686 size_t num_alias_rids
= 0;
1688 struct dom_sid
*groupSIDs
= NULL
;
1689 unsigned int num_groupSIDs
= 0;
1692 const char *sid_string
;
1696 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1697 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1699 * TODO: Get the filter right so that we only get the aliases from
1700 * either the SAM or BUILTIN
1703 filter
= talloc_asprintf(tmp_ctx
, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1704 GROUP_TYPE_BUILTIN_LOCAL_GROUP
);
1705 if (filter
== NULL
) {
1706 return NT_STATUS_NO_MEMORY
;
1709 for (i
= 0; i
< num_members
; i
++) {
1710 sid_string
= dom_sid_string(tmp_ctx
, &members
[i
]);
1711 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string
, tmp_ctx
);
1713 sid_dn
= talloc_asprintf(tmp_ctx
, "<SID=%s>", sid_string
);
1714 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn
, tmp_ctx
);
1716 sid_blob
= data_blob_string_const(sid_dn
);
1718 status
= dsdb_expand_nested_groups(state
->ldb
, &sid_blob
, true, filter
,
1719 tmp_ctx
, &groupSIDs
, &num_groupSIDs
);
1720 if (!NT_STATUS_IS_OK(status
)) {
1721 talloc_free(tmp_ctx
);
1726 alias_rids
= talloc_array(mem_ctx
, uint32_t, num_groupSIDs
);
1727 if (alias_rids
== NULL
) {
1728 talloc_free(tmp_ctx
);
1729 return NT_STATUS_NO_MEMORY
;
1732 for (i
=0; i
<num_groupSIDs
; i
++) {
1733 if (sid_peek_check_rid(domain_sid
, &groupSIDs
[i
],
1734 &alias_rids
[num_alias_rids
])) {
1739 *palias_rids
= alias_rids
;
1740 *pnum_alias_rids
= num_alias_rids
;
1741 return NT_STATUS_OK
;
1744 static NTSTATUS
pdb_samba_dsdb_lookup_rids(struct pdb_methods
*m
,
1745 const struct dom_sid
*domain_sid
,
1749 enum lsa_SidType
*lsa_attrs
)
1751 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1752 m
->private_data
, struct pdb_samba_dsdb_state
);
1755 TALLOC_CTX
*tmp_ctx
;
1757 if (num_rids
== 0) {
1758 return NT_STATUS_NONE_MAPPED
;
1761 tmp_ctx
= talloc_stackframe();
1762 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx
);
1764 status
= dsdb_lookup_rids(state
->ldb
, tmp_ctx
, domain_sid
, num_rids
, rids
, names
, lsa_attrs
);
1765 talloc_free(tmp_ctx
);
1769 static NTSTATUS
pdb_samba_dsdb_lookup_names(struct pdb_methods
*m
,
1770 const struct dom_sid
*domain_sid
,
1772 const char **pp_names
,
1774 enum lsa_SidType
*attrs
)
1776 return NT_STATUS_NOT_IMPLEMENTED
;
1779 static NTSTATUS
pdb_samba_dsdb_get_account_policy(struct pdb_methods
*m
,
1780 enum pdb_policy_type type
,
1783 return account_policy_get(type
, value
)
1784 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1787 static NTSTATUS
pdb_samba_dsdb_set_account_policy(struct pdb_methods
*m
,
1788 enum pdb_policy_type type
,
1791 return account_policy_set(type
, value
)
1792 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1795 static NTSTATUS
pdb_samba_dsdb_get_seq_num(struct pdb_methods
*m
,
1796 time_t *seq_num_out
)
1798 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1799 m
->private_data
, struct pdb_samba_dsdb_state
);
1801 int ret
= ldb_sequence_number(state
->ldb
, LDB_SEQ_HIGHEST_SEQ
, &seq_num
);
1802 if (ret
== LDB_SUCCESS
) {
1803 *seq_num_out
= seq_num
;
1804 return NT_STATUS_OK
;
1806 return NT_STATUS_UNSUCCESSFUL
;
1810 struct pdb_samba_dsdb_search_state
{
1811 uint32_t acct_flags
;
1812 struct samr_displayentry
*entries
;
1813 uint32_t num_entries
;
1818 static bool pdb_samba_dsdb_next_entry(struct pdb_search
*search
,
1819 struct samr_displayentry
*entry
)
1821 struct pdb_samba_dsdb_search_state
*state
= talloc_get_type_abort(
1822 search
->private_data
, struct pdb_samba_dsdb_search_state
);
1824 if (state
->current
== state
->num_entries
) {
1828 entry
->idx
= state
->entries
[state
->current
].idx
;
1829 entry
->rid
= state
->entries
[state
->current
].rid
;
1830 entry
->acct_flags
= state
->entries
[state
->current
].acct_flags
;
1832 entry
->account_name
= talloc_strdup(
1833 search
, state
->entries
[state
->current
].account_name
);
1834 entry
->fullname
= talloc_strdup(
1835 search
, state
->entries
[state
->current
].fullname
);
1836 entry
->description
= talloc_strdup(
1837 search
, state
->entries
[state
->current
].description
);
1839 state
->current
+= 1;
1843 static void pdb_samba_dsdb_search_end(struct pdb_search
*search
)
1845 struct pdb_samba_dsdb_search_state
*state
= talloc_get_type_abort(
1846 search
->private_data
, struct pdb_samba_dsdb_search_state
);
1850 static bool pdb_samba_dsdb_search_filter(struct pdb_methods
*m
,
1851 struct pdb_search
*search
,
1852 struct pdb_samba_dsdb_search_state
**pstate
,
1853 const char *exp_fmt
, ...) _PRINTF_ATTRIBUTE(4, 5)
1855 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
1856 m
->private_data
, struct pdb_samba_dsdb_state
);
1857 struct pdb_samba_dsdb_search_state
*sstate
;
1858 const char * attrs
[] = { "objectSid", "sAMAccountName", "displayName",
1859 "userAccountControl", "description", NULL
};
1860 struct ldb_result
*res
;
1861 int i
, rc
, num_users
;
1864 char *expression
= NULL
;
1866 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1871 va_start(ap
, exp_fmt
);
1872 expression
= talloc_vasprintf(tmp_ctx
, exp_fmt
, ap
);
1876 talloc_free(tmp_ctx
);
1877 return LDB_ERR_OPERATIONS_ERROR
;
1880 sstate
= talloc_zero(tmp_ctx
, struct pdb_samba_dsdb_search_state
);
1881 if (sstate
== NULL
) {
1882 talloc_free(tmp_ctx
);
1886 rc
= dsdb_search(state
->ldb
, tmp_ctx
, &res
, ldb_get_default_basedn(state
->ldb
), LDB_SCOPE_SUBTREE
, attrs
, 0, "%s", expression
);
1887 if (rc
!= LDB_SUCCESS
) {
1888 talloc_free(tmp_ctx
);
1889 DEBUG(10, ("dsdb_search failed: %s\n",
1890 ldb_errstring(state
->ldb
)));
1894 num_users
= res
->count
;
1896 sstate
->entries
= talloc_array(sstate
, struct samr_displayentry
,
1898 if (sstate
->entries
== NULL
) {
1899 talloc_free(tmp_ctx
);
1900 DEBUG(10, ("talloc failed\n"));
1904 sstate
->num_entries
= 0;
1906 for (i
=0; i
<num_users
; i
++) {
1907 struct samr_displayentry
*e
;
1908 struct dom_sid
*sid
;
1910 e
= &sstate
->entries
[sstate
->num_entries
];
1912 e
->idx
= sstate
->num_entries
;
1913 sid
= samdb_result_dom_sid(tmp_ctx
, res
->msgs
[i
], "objectSid");
1915 talloc_free(tmp_ctx
);
1916 DEBUG(10, ("Could not pull SID\n"));
1919 sid_peek_rid(sid
, &e
->rid
);
1921 e
->acct_flags
= samdb_result_acct_flags(state
->ldb
, tmp_ctx
,
1923 ldb_get_default_basedn(state
->ldb
));
1924 e
->account_name
= ldb_msg_find_attr_as_string(
1925 res
->msgs
[i
], "samAccountName", NULL
);
1926 if (e
->account_name
== NULL
) {
1927 talloc_free(tmp_ctx
);
1930 e
->fullname
= ldb_msg_find_attr_as_string(
1931 res
->msgs
[i
], "displayName", "");
1932 e
->description
= ldb_msg_find_attr_as_string(
1933 res
->msgs
[i
], "description", "");
1935 sstate
->num_entries
+= 1;
1936 if (sstate
->num_entries
>= num_users
) {
1940 talloc_steal(sstate
->entries
, res
->msgs
);
1941 search
->private_data
= talloc_steal(search
, sstate
);
1942 search
->next_entry
= pdb_samba_dsdb_next_entry
;
1943 search
->search_end
= pdb_samba_dsdb_search_end
;
1945 talloc_free(tmp_ctx
);
1949 static bool pdb_samba_dsdb_search_users(struct pdb_methods
*m
,
1950 struct pdb_search
*search
,
1953 struct pdb_samba_dsdb_search_state
*sstate
;
1956 ret
= pdb_samba_dsdb_search_filter(m
, search
, &sstate
, "(objectclass=user)");
1960 sstate
->acct_flags
= acct_flags
;
1964 static bool pdb_samba_dsdb_search_groups(struct pdb_methods
*m
,
1965 struct pdb_search
*search
)
1967 struct pdb_samba_dsdb_search_state
*sstate
;
1970 ret
= pdb_samba_dsdb_search_filter(m
, search
, &sstate
,
1971 "(&(grouptype=%d)(objectclass=group))",
1972 GTYPE_SECURITY_GLOBAL_GROUP
);
1976 sstate
->acct_flags
= 0;
1980 static bool pdb_samba_dsdb_search_aliases(struct pdb_methods
*m
,
1981 struct pdb_search
*search
,
1982 const struct dom_sid
*sid
)
1984 struct pdb_samba_dsdb_search_state
*sstate
;
1987 ret
= pdb_samba_dsdb_search_filter(m
, search
, &sstate
,
1988 "(&(grouptype=%d)(objectclass=group))",
1989 sid_check_is_builtin(sid
)
1990 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1991 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1995 sstate
->acct_flags
= 0;
1999 static bool pdb_samba_dsdb_uid_to_sid(struct pdb_methods
*m
, uid_t uid
,
2000 struct dom_sid
*sid
)
2002 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
2003 m
->private_data
, struct pdb_samba_dsdb_state
);
2005 struct id_map id_map
;
2006 struct id_map
*id_maps
[2];
2007 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2012 id_map
.xid
.id
= uid
;
2013 id_map
.xid
.type
= ID_TYPE_UID
;
2014 id_maps
[0] = &id_map
;
2017 status
= idmap_xids_to_sids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
2018 if (!NT_STATUS_IS_OK(status
)) {
2019 talloc_free(tmp_ctx
);
2023 talloc_free(tmp_ctx
);
2027 static bool pdb_samba_dsdb_gid_to_sid(struct pdb_methods
*m
, gid_t gid
,
2028 struct dom_sid
*sid
)
2030 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
2031 m
->private_data
, struct pdb_samba_dsdb_state
);
2033 struct id_map id_map
;
2034 struct id_map
*id_maps
[2];
2035 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2040 id_map
.xid
.id
= gid
;
2041 id_map
.xid
.type
= ID_TYPE_GID
;
2042 id_maps
[0] = &id_map
;
2045 status
= idmap_xids_to_sids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
2046 if (!NT_STATUS_IS_OK(status
)) {
2050 talloc_free(tmp_ctx
);
2054 static bool pdb_samba_dsdb_sid_to_id(struct pdb_methods
*m
, const struct dom_sid
*sid
,
2057 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
2058 m
->private_data
, struct pdb_samba_dsdb_state
);
2059 struct id_map id_map
;
2060 struct id_map
*id_maps
[2];
2062 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2067 ZERO_STRUCT(id_map
);
2069 id_maps
[0] = &id_map
;
2072 status
= idmap_sids_to_xids(state
->idmap_ctx
, tmp_ctx
, id_maps
);
2073 talloc_free(tmp_ctx
);
2074 if (!NT_STATUS_IS_OK(status
)) {
2077 if (id_map
.xid
.type
!= ID_TYPE_NOT_SPECIFIED
) {
2084 static uint32_t pdb_samba_dsdb_capabilities(struct pdb_methods
*m
)
2086 return PDB_CAP_STORE_RIDS
| PDB_CAP_ADS
;
2089 static bool pdb_samba_dsdb_new_rid(struct pdb_methods
*m
, uint32
*rid
)
2094 static bool pdb_samba_dsdb_get_trusteddom_pw(struct pdb_methods
*m
,
2095 const char *domain
, char** pwd
,
2096 struct dom_sid
*sid
,
2097 time_t *pass_last_set_time
)
2102 static bool pdb_samba_dsdb_set_trusteddom_pw(struct pdb_methods
*m
,
2103 const char* domain
, const char* pwd
,
2104 const struct dom_sid
*sid
)
2109 static bool pdb_samba_dsdb_del_trusteddom_pw(struct pdb_methods
*m
,
2115 static NTSTATUS
pdb_samba_dsdb_enum_trusteddoms(struct pdb_methods
*m
,
2116 TALLOC_CTX
*mem_ctx
,
2117 uint32
*num_domains
,
2118 struct trustdom_info
***domains
)
2122 return NT_STATUS_OK
;
2125 static void pdb_samba_dsdb_init_methods(struct pdb_methods
*m
)
2127 m
->name
= "samba_dsdb";
2128 m
->get_domain_info
= pdb_samba_dsdb_get_domain_info
;
2129 m
->getsampwnam
= pdb_samba_dsdb_getsampwnam
;
2130 m
->getsampwsid
= pdb_samba_dsdb_getsampwsid
;
2131 m
->create_user
= pdb_samba_dsdb_create_user
;
2132 m
->delete_user
= pdb_samba_dsdb_delete_user
;
2133 m
->add_sam_account
= pdb_samba_dsdb_add_sam_account
;
2134 m
->update_sam_account
= pdb_samba_dsdb_update_sam_account
;
2135 m
->delete_sam_account
= pdb_samba_dsdb_delete_sam_account
;
2136 m
->rename_sam_account
= pdb_samba_dsdb_rename_sam_account
;
2137 m
->update_login_attempts
= pdb_samba_dsdb_update_login_attempts
;
2138 m
->getgrsid
= pdb_samba_dsdb_getgrsid
;
2139 m
->getgrgid
= pdb_samba_dsdb_getgrgid
;
2140 m
->getgrnam
= pdb_samba_dsdb_getgrnam
;
2141 m
->create_dom_group
= pdb_samba_dsdb_create_dom_group
;
2142 m
->delete_dom_group
= pdb_samba_dsdb_delete_dom_group
;
2143 m
->add_group_mapping_entry
= pdb_samba_dsdb_add_group_mapping_entry
;
2144 m
->update_group_mapping_entry
= pdb_samba_dsdb_update_group_mapping_entry
;
2145 m
->delete_group_mapping_entry
= pdb_samba_dsdb_delete_group_mapping_entry
;
2146 m
->enum_group_mapping
= pdb_samba_dsdb_enum_group_mapping
;
2147 m
->enum_group_members
= pdb_samba_dsdb_enum_group_members
;
2148 m
->enum_group_memberships
= pdb_samba_dsdb_enum_group_memberships
;
2149 m
->set_unix_primary_group
= pdb_samba_dsdb_set_unix_primary_group
;
2150 m
->add_groupmem
= pdb_samba_dsdb_add_groupmem
;
2151 m
->del_groupmem
= pdb_samba_dsdb_del_groupmem
;
2152 m
->create_alias
= pdb_samba_dsdb_create_alias
;
2153 m
->delete_alias
= pdb_samba_dsdb_delete_alias
;
2154 m
->get_aliasinfo
= pdb_default_get_aliasinfo
;
2155 m
->add_aliasmem
= pdb_samba_dsdb_add_aliasmem
;
2156 m
->del_aliasmem
= pdb_samba_dsdb_del_aliasmem
;
2157 m
->enum_aliasmem
= pdb_samba_dsdb_enum_aliasmem
;
2158 m
->enum_alias_memberships
= pdb_samba_dsdb_enum_alias_memberships
;
2159 m
->lookup_rids
= pdb_samba_dsdb_lookup_rids
;
2160 m
->lookup_names
= pdb_samba_dsdb_lookup_names
;
2161 m
->get_account_policy
= pdb_samba_dsdb_get_account_policy
;
2162 m
->set_account_policy
= pdb_samba_dsdb_set_account_policy
;
2163 m
->get_seq_num
= pdb_samba_dsdb_get_seq_num
;
2164 m
->search_users
= pdb_samba_dsdb_search_users
;
2165 m
->search_groups
= pdb_samba_dsdb_search_groups
;
2166 m
->search_aliases
= pdb_samba_dsdb_search_aliases
;
2167 m
->uid_to_sid
= pdb_samba_dsdb_uid_to_sid
;
2168 m
->gid_to_sid
= pdb_samba_dsdb_gid_to_sid
;
2169 m
->sid_to_id
= pdb_samba_dsdb_sid_to_id
;
2170 m
->capabilities
= pdb_samba_dsdb_capabilities
;
2171 m
->new_rid
= pdb_samba_dsdb_new_rid
;
2172 m
->get_trusteddom_pw
= pdb_samba_dsdb_get_trusteddom_pw
;
2173 m
->set_trusteddom_pw
= pdb_samba_dsdb_set_trusteddom_pw
;
2174 m
->del_trusteddom_pw
= pdb_samba_dsdb_del_trusteddom_pw
;
2175 m
->enum_trusteddoms
= pdb_samba_dsdb_enum_trusteddoms
;
2178 static void free_private_data(void **vp
)
2180 struct pdb_samba_dsdb_state
*state
= talloc_get_type_abort(
2181 *vp
, struct pdb_samba_dsdb_state
);
2182 talloc_unlink(state
, state
->ldb
);
2186 static NTSTATUS
pdb_samba_dsdb_init_secrets(struct pdb_methods
*m
)
2188 struct pdb_domain_info
*dom_info
;
2191 dom_info
= pdb_samba_dsdb_get_domain_info(m
, m
);
2193 return NT_STATUS_UNSUCCESSFUL
;
2196 secrets_clear_domain_protection(dom_info
->name
);
2197 ret
= secrets_store_domain_sid(dom_info
->name
,
2202 ret
= secrets_store_domain_guid(dom_info
->name
,
2207 ret
= secrets_mark_domain_protected(dom_info
->name
);
2213 TALLOC_FREE(dom_info
);
2215 return NT_STATUS_UNSUCCESSFUL
;
2217 return NT_STATUS_OK
;
2220 static NTSTATUS
pdb_init_samba_dsdb(struct pdb_methods
**pdb_method
,
2221 const char *location
)
2223 struct pdb_methods
*m
;
2224 struct pdb_samba_dsdb_state
*state
;
2227 if ( !NT_STATUS_IS_OK(status
= make_pdb_method( &m
)) ) {
2231 state
= talloc_zero(m
, struct pdb_samba_dsdb_state
);
2232 if (state
== NULL
) {
2235 m
->private_data
= state
;
2236 m
->free_private_data
= free_private_data
;
2237 pdb_samba_dsdb_init_methods(m
);
2239 state
->ev
= s4_event_context_init(state
);
2241 DEBUG(0, ("s4_event_context_init failed\n"));
2245 state
->lp_ctx
= loadparm_init_s3(state
, loadparm_s3_helpers());
2246 if (state
->lp_ctx
== NULL
) {
2247 DEBUG(0, ("loadparm_init_s3 failed\n"));
2252 state
->ldb
= samdb_connect_url(state
,
2255 system_session(state
->lp_ctx
),
2258 state
->ldb
= samdb_connect(state
,
2261 system_session(state
->lp_ctx
), 0);
2265 DEBUG(0, ("samdb_connect failed\n"));
2266 status
= NT_STATUS_INTERNAL_ERROR
;
2270 state
->idmap_ctx
= idmap_init(state
, state
->ev
,
2272 if (!state
->idmap_ctx
) {
2273 DEBUG(0, ("idmap failed\n"));
2274 status
= NT_STATUS_INTERNAL_ERROR
;
2278 status
= pdb_samba_dsdb_init_secrets(m
);
2279 if (!NT_STATUS_IS_OK(status
)) {
2280 DEBUG(10, ("pdb_samba_dsdb_init_secrets failed!\n"));
2285 return NT_STATUS_OK
;
2287 status
= NT_STATUS_NO_MEMORY
;
2293 NTSTATUS
pdb_samba_dsdb_init(void);
2294 NTSTATUS
pdb_samba_dsdb_init(void)
2296 NTSTATUS status
= smb_register_passdb(PASSDB_INTERFACE_VERSION
, "samba_dsdb",
2297 pdb_init_samba_dsdb
);
2298 if (!NT_STATUS_IS_OK(status
)) {
2301 return smb_register_passdb(PASSDB_INTERFACE_VERSION
, "samba4",
2302 pdb_init_samba_dsdb
);