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[] = { "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;
944 map->sid_name_use = SID_NAME_DOM_GRP;
948 id_maps[0] = &id_map;
951 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
952 talloc_free(tmp_ctx);
953 if (!NT_STATUS_IS_OK(status)) {
954 talloc_free(tmp_ctx);
957 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
958 map->gid = id_map.xid.id;
960 DEBUG(1, (__location__ "Did not get GUID when mapping SID for %s", expression));
961 talloc_free(tmp_ctx);
962 return NT_STATUS_INTERNAL_DB_CORRUPTION;
964 } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
965 DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
966 talloc_free(tmp_ctx);
967 return NT_STATUS_INTERNAL_DB_CORRUPTION;
970 str = ldb_msg_find_attr_as_string(msg, "samAccountName",
973 talloc_free(tmp_ctx);
974 return NT_STATUS_INTERNAL_DB_CORRUPTION;
976 map->nt_name = talloc_strdup(map, str);
978 talloc_free(tmp_ctx);
979 return NT_STATUS_NO_MEMORY;
982 str = ldb_msg_find_attr_as_string(msg, "description",
985 map->comment = talloc_strdup(map, str);
987 map->comment = talloc_strdup(map, "");
990 talloc_free(tmp_ctx);
991 return NT_STATUS_NO_MEMORY;
994 talloc_free(tmp_ctx);
998 static NTSTATUS pdb_samba_dsdb_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
1004 filter = talloc_asprintf(talloc_tos(),
1005 "(&(objectsid=%s)(objectclass=group))",
1006 sid_string_talloc(talloc_tos(), &sid));
1007 if (filter == NULL) {
1008 return NT_STATUS_NO_MEMORY;
1011 status = pdb_samba_dsdb_getgrfilter(m, map, filter);
1012 TALLOC_FREE(filter);
1016 static NTSTATUS pdb_samba_dsdb_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
1019 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1020 m->private_data, struct pdb_samba_dsdb_state);
1022 struct id_map id_map;
1023 struct id_map *id_maps[2];
1024 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1025 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1027 id_map.xid.id = gid;
1028 id_map.xid.type = ID_TYPE_GID;
1029 id_maps[0] = &id_map;
1032 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1033 if (!NT_STATUS_IS_OK(status)) {
1036 status = pdb_samba_dsdb_getgrsid(m, map, *id_map.sid);
1037 talloc_free(tmp_ctx);
1041 static NTSTATUS pdb_samba_dsdb_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
1047 filter = talloc_asprintf(talloc_tos(),
1048 "(&(samaccountname=%s)(objectclass=group))",
1050 if (filter == NULL) {
1051 return NT_STATUS_NO_MEMORY;
1054 status = pdb_samba_dsdb_getgrfilter(m, map, filter);
1055 TALLOC_FREE(filter);
1059 static NTSTATUS pdb_samba_dsdb_create_dom_group(struct pdb_methods *m,
1060 TALLOC_CTX *mem_ctx, const char *name,
1063 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1064 m->private_data, struct pdb_samba_dsdb_state);
1066 struct dom_sid *sid;
1068 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1069 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1071 status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
1072 if (!NT_STATUS_IS_OK(status)) {
1073 talloc_free(tmp_ctx);
1077 sid_peek_rid(sid, rid);
1078 talloc_free(tmp_ctx);
1079 return NT_STATUS_OK;
1082 static NTSTATUS pdb_samba_dsdb_delete_dom_group(struct pdb_methods *m,
1083 TALLOC_CTX *mem_ctx, uint32 rid)
1085 const char *attrs[] = { NULL };
1086 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1087 m->private_data, struct pdb_samba_dsdb_state);
1089 struct ldb_message *msg;
1092 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1093 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1095 sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
1097 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1098 DEBUG(0, ("Unable to start transaction in pdb_samba_dsdb_delete_dom_group()\n"));
1099 return NT_STATUS_INTERNAL_ERROR;
1102 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
1103 if (!dn || !ldb_dn_validate(dn)) {
1104 talloc_free(tmp_ctx);
1105 ldb_transaction_cancel(state->ldb);
1106 return NT_STATUS_NO_MEMORY;
1108 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
1109 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1110 talloc_free(tmp_ctx);
1111 ldb_transaction_cancel(state->ldb);
1112 return NT_STATUS_NO_SUCH_GROUP;
1114 rc = ldb_delete(state->ldb, dn);
1115 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1116 talloc_free(tmp_ctx);
1117 ldb_transaction_cancel(state->ldb);
1118 return NT_STATUS_NO_SUCH_GROUP;
1119 } else if (rc != LDB_SUCCESS) {
1120 DEBUG(10, ("ldb_delete failed %s\n",
1121 ldb_errstring(state->ldb)));
1122 ldb_transaction_cancel(state->ldb);
1123 return NT_STATUS_LDAP(rc);
1126 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1127 DEBUG(0, ("Unable to commit transaction in pdb_samba_dsdb_delete_dom_group()\n"));
1128 return NT_STATUS_INTERNAL_ERROR;
1130 return NT_STATUS_OK;
1133 static NTSTATUS pdb_samba_dsdb_add_group_mapping_entry(struct pdb_methods *m,
1136 return NT_STATUS_NOT_IMPLEMENTED;
1139 static NTSTATUS pdb_samba_dsdb_update_group_mapping_entry(struct pdb_methods *m,
1142 return NT_STATUS_NOT_IMPLEMENTED;
1145 static NTSTATUS pdb_samba_dsdb_delete_group_mapping_entry(struct pdb_methods *m,
1148 return NT_STATUS_NOT_IMPLEMENTED;
1151 static NTSTATUS pdb_samba_dsdb_enum_group_mapping(struct pdb_methods *m,
1152 const struct dom_sid *sid,
1153 enum lsa_SidType sid_name_use,
1154 GROUP_MAP ***pp_rmap,
1155 size_t *p_num_entries,
1158 return NT_STATUS_NOT_IMPLEMENTED;
1161 static NTSTATUS pdb_samba_dsdb_enum_group_members(struct pdb_methods *m,
1162 TALLOC_CTX *mem_ctx,
1163 const struct dom_sid *group,
1164 uint32_t **pmembers,
1165 size_t *pnum_members)
1167 unsigned int i, num_sids, num_members;
1168 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1169 m->private_data, struct pdb_samba_dsdb_state);
1170 struct dom_sid *members_as_sids;
1171 struct dom_sid *dom_sid;
1176 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1177 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1179 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
1180 if (!dn || !ldb_dn_validate(dn)) {
1181 return NT_STATUS_NO_MEMORY;
1184 status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
1185 if (!NT_STATUS_IS_OK(status)) {
1186 talloc_free(tmp_ctx);
1189 status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
1190 if (!NT_STATUS_IS_OK(status)) {
1191 talloc_free(tmp_ctx);
1195 *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
1196 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*pmembers, tmp_ctx);
1199 for (i = 0; i < num_sids; i++) {
1200 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
1203 status = dom_sid_split_rid(NULL, &members_as_sids[i],
1204 NULL, &members[num_members]);
1205 if (!NT_STATUS_IS_OK(status)) {
1206 talloc_free(tmp_ctx);
1211 *pnum_members = num_members;
1212 return NT_STATUS_OK;
1215 /* Just convert the primary group SID into a group */
1216 static NTSTATUS fake_enum_group_memberships(struct pdb_samba_dsdb_state *state,
1217 TALLOC_CTX *mem_ctx,
1219 struct dom_sid **pp_sids,
1221 uint32_t *p_num_groups)
1224 size_t num_groups = 0;
1225 struct dom_sid *group_sids = NULL;
1227 TALLOC_CTX *tmp_ctx;
1229 tmp_ctx = talloc_new(mem_ctx);
1230 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1232 if (user->group_sid) {
1233 struct id_map *id_maps[2];
1234 struct id_map id_map;
1238 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1239 if (group_sids == NULL) {
1240 talloc_free(tmp_ctx);
1241 return NT_STATUS_NO_MEMORY;
1243 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1245 talloc_free(tmp_ctx);
1246 return NT_STATUS_NO_MEMORY;
1249 group_sids[0] = *user->group_sid;
1251 ZERO_STRUCT(id_map);
1252 id_map.sid = &group_sids[0];
1253 id_maps[0] = &id_map;
1256 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1257 if (!NT_STATUS_IS_OK(status)) {
1258 talloc_free(tmp_ctx);
1261 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1262 gids[0] = id_map.xid.id;
1264 DEBUG(1, (__location__
1265 "Group %s, of which %s is a member, could not be converted to a GID\n",
1266 dom_sid_string(tmp_ctx, &group_sids[0]),
1267 dom_sid_string(tmp_ctx, &user->user_sid)));
1268 talloc_free(tmp_ctx);
1269 /* We must error out, otherwise a user might
1270 * avoid a DENY acl based on a group they
1272 return NT_STATUS_NO_SUCH_GROUP;
1276 *pp_sids = talloc_steal(mem_ctx, group_sids);
1277 *pp_gids = talloc_steal(mem_ctx, gids);
1278 *p_num_groups = num_groups;
1279 talloc_free(tmp_ctx);
1280 return NT_STATUS_OK;
1283 static NTSTATUS pdb_samba_dsdb_enum_group_memberships(struct pdb_methods *m,
1284 TALLOC_CTX *mem_ctx,
1286 struct dom_sid **pp_sids,
1288 uint32_t *p_num_groups)
1290 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1291 m->private_data, struct pdb_samba_dsdb_state);
1292 struct ldb_message *msg = pdb_samba_dsdb_get_samu_private(
1294 const char *attrs[] = { "tokenGroups", NULL};
1295 struct ldb_message *tokengroups_msg;
1296 struct ldb_message_element *tokengroups;
1299 unsigned int count = 0;
1301 struct dom_sid *group_sids;
1303 TALLOC_CTX *tmp_ctx;
1306 /* Fake up some things here */
1307 return fake_enum_group_memberships(state,
1310 pp_gids, p_num_groups);
1313 tmp_ctx = talloc_new(mem_ctx);
1314 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1316 rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1318 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1319 talloc_free(tmp_ctx);
1320 return NT_STATUS_NO_SUCH_USER;
1321 } else if (rc != LDB_SUCCESS) {
1322 DEBUG(10, ("dsdb_search_one failed %s\n",
1323 ldb_errstring(state->ldb)));
1324 talloc_free(tmp_ctx);
1325 return NT_STATUS_LDAP(rc);
1328 tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1331 count = tokengroups->num_values;
1334 group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1335 if (group_sids == NULL) {
1336 talloc_free(tmp_ctx);
1337 return NT_STATUS_NO_MEMORY;
1339 gids = talloc_array(tmp_ctx, gid_t, count);
1341 talloc_free(tmp_ctx);
1342 return NT_STATUS_NO_MEMORY;
1346 for (i=0; i<count; i++) {
1347 struct id_map *id_maps[2];
1348 struct id_map id_map;
1349 struct ldb_val *v = &tokengroups->values[i];
1350 enum ndr_err_code ndr_err
1351 = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1352 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1353 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1354 talloc_free(tmp_ctx);
1355 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1358 ZERO_STRUCT(id_map);
1359 id_map.sid = &group_sids[num_groups];
1360 id_maps[0] = &id_map;
1363 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1364 if (!NT_STATUS_IS_OK(status)) {
1365 talloc_free(tmp_ctx);
1368 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1369 gids[num_groups] = id_map.xid.id;
1371 DEBUG(1, (__location__
1372 "Group %s, of which %s is a member, could not be converted to a GID\n",
1373 dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1374 ldb_dn_get_linearized(msg->dn)));
1375 talloc_free(tmp_ctx);
1376 /* We must error out, otherwise a user might
1377 * avoid a DENY acl based on a group they
1379 return NT_STATUS_NO_SUCH_GROUP;
1383 if (num_groups == count) {
1388 *pp_sids = talloc_steal(mem_ctx, group_sids);
1389 *pp_gids = talloc_steal(mem_ctx, gids);
1390 *p_num_groups = num_groups;
1391 talloc_free(tmp_ctx);
1392 return NT_STATUS_OK;
1395 static NTSTATUS pdb_samba_dsdb_set_unix_primary_group(struct pdb_methods *m,
1396 TALLOC_CTX *mem_ctx,
1399 return NT_STATUS_NOT_IMPLEMENTED;
1402 static NTSTATUS pdb_samba_dsdb_mod_groupmem_by_sid(struct pdb_methods *m,
1403 TALLOC_CTX *mem_ctx,
1404 const struct dom_sid *groupsid,
1405 const struct dom_sid *membersid,
1408 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1409 m->private_data, struct pdb_samba_dsdb_state);
1410 struct ldb_message *msg;
1412 struct ldb_message_element *el;
1413 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1414 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1415 msg = ldb_msg_new(tmp_ctx);
1416 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, tmp_ctx);
1418 msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1419 if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1420 talloc_free(tmp_ctx);
1421 return NT_STATUS_NO_MEMORY;
1423 ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1424 if (ret != LDB_SUCCESS) {
1425 talloc_free(tmp_ctx);
1426 return NT_STATUS_NO_MEMORY;
1428 el = ldb_msg_find_element(msg, "member");
1431 /* No need for transactions here, the ldb auto-transaction
1432 * code will handle things for the single operation */
1433 ret = ldb_modify(state->ldb, msg);
1434 talloc_free(tmp_ctx);
1435 if (ret != LDB_SUCCESS) {
1436 DEBUG(10, ("ldb_modify failed: %s\n",
1437 ldb_errstring(state->ldb)));
1438 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1439 return NT_STATUS_MEMBER_IN_GROUP;
1441 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1442 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1444 return NT_STATUS_LDAP(ret);
1447 return NT_STATUS_OK;
1450 static NTSTATUS pdb_samba_dsdb_mod_groupmem(struct pdb_methods *m,
1451 TALLOC_CTX *mem_ctx,
1452 uint32 grouprid, uint32 memberrid,
1455 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1456 m->private_data, struct pdb_samba_dsdb_state);
1457 const struct dom_sid *dom_sid, *groupsid, *membersid;
1459 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1460 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1462 dom_sid = samdb_domain_sid(state->ldb);
1464 groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1465 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupsid, tmp_ctx);
1466 membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1467 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(membersid, tmp_ctx);
1468 status = pdb_samba_dsdb_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1469 talloc_free(tmp_ctx);
1473 static NTSTATUS pdb_samba_dsdb_add_groupmem(struct pdb_methods *m,
1474 TALLOC_CTX *mem_ctx,
1475 uint32 group_rid, uint32 member_rid)
1477 return pdb_samba_dsdb_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1481 static NTSTATUS pdb_samba_dsdb_del_groupmem(struct pdb_methods *m,
1482 TALLOC_CTX *mem_ctx,
1483 uint32 group_rid, uint32 member_rid)
1485 return pdb_samba_dsdb_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1486 LDB_FLAG_MOD_DELETE);
1489 static NTSTATUS pdb_samba_dsdb_create_alias(struct pdb_methods *m,
1490 const char *name, uint32 *rid)
1492 TALLOC_CTX *frame = talloc_stackframe();
1493 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1494 m->private_data, struct pdb_samba_dsdb_state);
1495 struct dom_sid *sid;
1500 /* Internally this uses transactions to ensure all the steps
1501 * happen or fail as one */
1502 status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1503 if (!NT_STATUS_IS_OK(status)) {
1507 sid_peek_rid(sid, rid);
1509 return NT_STATUS_OK;
1512 static NTSTATUS pdb_samba_dsdb_delete_alias(struct pdb_methods *m,
1513 const struct dom_sid *sid)
1515 const char *attrs[] = { NULL };
1516 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1517 m->private_data, struct pdb_samba_dsdb_state);
1518 struct ldb_message *msg;
1521 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1522 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1524 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1525 if (!dn || !ldb_dn_validate(dn)) {
1526 talloc_free(tmp_ctx);
1527 return NT_STATUS_NO_MEMORY;
1530 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1531 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1532 return NT_STATUS_INTERNAL_ERROR;
1535 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1536 "(|(grouptype=%d)(grouptype=%d)))",
1537 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1538 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1539 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1540 talloc_free(tmp_ctx);
1541 ldb_transaction_cancel(state->ldb);
1542 return NT_STATUS_NO_SUCH_ALIAS;
1544 rc = ldb_delete(state->ldb, dn);
1545 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1546 talloc_free(tmp_ctx);
1547 ldb_transaction_cancel(state->ldb);
1548 return NT_STATUS_NO_SUCH_ALIAS;
1549 } else if (rc != LDB_SUCCESS) {
1550 DEBUG(10, ("ldb_delete failed %s\n",
1551 ldb_errstring(state->ldb)));
1552 ldb_transaction_cancel(state->ldb);
1553 return NT_STATUS_LDAP(rc);
1556 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1557 DEBUG(0, ("Failed to commit transaction in pdb_samba_dsdb_delete_alias(): %s\n",
1558 ldb_errstring(state->ldb)));
1559 return NT_STATUS_INTERNAL_ERROR;
1562 return NT_STATUS_OK;
1566 static NTSTATUS pdb_samba_dsdb_set_aliasinfo(struct pdb_methods *m,
1567 const struct dom_sid *sid,
1568 struct acct_info *info)
1570 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1571 m->private_data, struct pdb_samba_dsdb_state);
1572 struct tldap_context *ld;
1573 const char *attrs[3] = { "objectSid", "description",
1575 struct ldb_message **msg;
1578 struct tldap_mod *mods;
1582 ld = pdb_samba_dsdb_ld(state);
1584 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1587 sidstr = sid_binstring(talloc_tos(), sid);
1588 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1590 rc = pdb_samba_dsdb_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1591 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1592 &msg, "(&(objectSid=%s)(objectclass=group)"
1593 "(|(grouptype=%d)(grouptype=%d)))",
1594 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1595 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1597 if (rc != LDB_SUCCESS) {
1598 DEBUG(10, ("ldap_search failed %s\n",
1599 ldb_errstring(state->ldb)));
1600 return NT_STATUS_LDAP(rc);
1602 switch talloc_array_length(msg) {
1604 return NT_STATUS_NO_SUCH_ALIAS;
1608 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1611 if (!tldap_entry_dn(msg[0], &dn)) {
1613 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1620 ok &= tldap_make_mod_fmt(
1621 msg[0], msg, &num_mods, &mods, "description",
1622 "%s", info->acct_desc);
1623 ok &= tldap_make_mod_fmt(
1624 msg[0], msg, &num_mods, &mods, "samAccountName",
1625 "%s", info->acct_name);
1628 return NT_STATUS_NO_MEMORY;
1630 if (num_mods == 0) {
1633 return NT_STATUS_OK;
1636 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1638 if (rc != LDB_SUCCESS) {
1639 DEBUG(10, ("ldap_modify failed: %s\n",
1640 ldb_errstring(state->ldb)));
1641 return NT_STATUS_LDAP(rc);
1643 return NT_STATUS_OK;
1646 static NTSTATUS pdb_samba_dsdb_add_aliasmem(struct pdb_methods *m,
1647 const struct dom_sid *alias,
1648 const struct dom_sid *member)
1651 TALLOC_CTX *frame = talloc_stackframe();
1652 status = pdb_samba_dsdb_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1657 static NTSTATUS pdb_samba_dsdb_del_aliasmem(struct pdb_methods *m,
1658 const struct dom_sid *alias,
1659 const struct dom_sid *member)
1662 TALLOC_CTX *frame = talloc_stackframe();
1663 status = pdb_samba_dsdb_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1668 static NTSTATUS pdb_samba_dsdb_enum_aliasmem(struct pdb_methods *m,
1669 const struct dom_sid *alias,
1670 TALLOC_CTX *mem_ctx,
1671 struct dom_sid **pmembers,
1672 size_t *pnum_members)
1674 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1675 m->private_data, struct pdb_samba_dsdb_state);
1677 unsigned int num_members;
1679 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1680 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1682 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1683 if (!dn || !ldb_dn_validate(dn)) {
1684 return NT_STATUS_NO_MEMORY;
1687 status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1688 *pnum_members = num_members;
1689 if (NT_STATUS_IS_OK(status)) {
1690 talloc_steal(mem_ctx, pmembers);
1692 talloc_free(tmp_ctx);
1696 static NTSTATUS pdb_samba_dsdb_enum_alias_memberships(struct pdb_methods *m,
1697 TALLOC_CTX *mem_ctx,
1698 const struct dom_sid *domain_sid,
1699 const struct dom_sid *members,
1701 uint32_t **palias_rids,
1702 size_t *pnum_alias_rids)
1704 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1705 m->private_data, struct pdb_samba_dsdb_state);
1706 uint32_t *alias_rids = NULL;
1707 size_t num_alias_rids = 0;
1709 struct dom_sid *groupSIDs = NULL;
1710 unsigned int num_groupSIDs = 0;
1713 const char *sid_string;
1717 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1718 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1720 * TODO: Get the filter right so that we only get the aliases from
1721 * either the SAM or BUILTIN
1724 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1725 GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1726 if (filter == NULL) {
1727 return NT_STATUS_NO_MEMORY;
1730 for (i = 0; i < num_members; i++) {
1731 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1732 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, tmp_ctx);
1734 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1735 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, tmp_ctx);
1737 sid_blob = data_blob_string_const(sid_dn);
1739 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1740 tmp_ctx, &groupSIDs, &num_groupSIDs);
1741 if (!NT_STATUS_IS_OK(status)) {
1742 talloc_free(tmp_ctx);
1747 alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1748 if (alias_rids == NULL) {
1749 talloc_free(tmp_ctx);
1750 return NT_STATUS_NO_MEMORY;
1753 for (i=0; i<num_groupSIDs; i++) {
1754 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1755 &alias_rids[num_alias_rids])) {
1760 *palias_rids = alias_rids;
1761 *pnum_alias_rids = num_alias_rids;
1762 return NT_STATUS_OK;
1765 static NTSTATUS pdb_samba_dsdb_lookup_rids(struct pdb_methods *m,
1766 const struct dom_sid *domain_sid,
1770 enum lsa_SidType *lsa_attrs)
1772 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1773 m->private_data, struct pdb_samba_dsdb_state);
1776 TALLOC_CTX *tmp_ctx;
1778 if (num_rids == 0) {
1779 return NT_STATUS_NONE_MAPPED;
1782 tmp_ctx = talloc_stackframe();
1783 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1785 status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1786 talloc_free(tmp_ctx);
1790 static NTSTATUS pdb_samba_dsdb_lookup_names(struct pdb_methods *m,
1791 const struct dom_sid *domain_sid,
1793 const char **pp_names,
1795 enum lsa_SidType *attrs)
1797 return NT_STATUS_NOT_IMPLEMENTED;
1800 static NTSTATUS pdb_samba_dsdb_get_account_policy(struct pdb_methods *m,
1801 enum pdb_policy_type type,
1804 return account_policy_get(type, value)
1805 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1808 static NTSTATUS pdb_samba_dsdb_set_account_policy(struct pdb_methods *m,
1809 enum pdb_policy_type type,
1812 return account_policy_set(type, value)
1813 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1816 static NTSTATUS pdb_samba_dsdb_get_seq_num(struct pdb_methods *m,
1817 time_t *seq_num_out)
1819 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1820 m->private_data, struct pdb_samba_dsdb_state);
1822 int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1823 if (ret == LDB_SUCCESS) {
1824 *seq_num_out = seq_num;
1825 return NT_STATUS_OK;
1827 return NT_STATUS_UNSUCCESSFUL;
1831 struct pdb_samba_dsdb_search_state {
1832 uint32_t acct_flags;
1833 struct samr_displayentry *entries;
1834 uint32_t num_entries;
1839 static bool pdb_samba_dsdb_next_entry(struct pdb_search *search,
1840 struct samr_displayentry *entry)
1842 struct pdb_samba_dsdb_search_state *state = talloc_get_type_abort(
1843 search->private_data, struct pdb_samba_dsdb_search_state);
1845 if (state->current == state->num_entries) {
1849 entry->idx = state->entries[state->current].idx;
1850 entry->rid = state->entries[state->current].rid;
1851 entry->acct_flags = state->entries[state->current].acct_flags;
1853 entry->account_name = talloc_strdup(
1854 search, state->entries[state->current].account_name);
1855 entry->fullname = talloc_strdup(
1856 search, state->entries[state->current].fullname);
1857 entry->description = talloc_strdup(
1858 search, state->entries[state->current].description);
1860 state->current += 1;
1864 static void pdb_samba_dsdb_search_end(struct pdb_search *search)
1866 struct pdb_samba_dsdb_search_state *state = talloc_get_type_abort(
1867 search->private_data, struct pdb_samba_dsdb_search_state);
1871 static bool pdb_samba_dsdb_search_filter(struct pdb_methods *m,
1872 struct pdb_search *search,
1873 struct pdb_samba_dsdb_search_state **pstate,
1874 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1876 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1877 m->private_data, struct pdb_samba_dsdb_state);
1878 struct pdb_samba_dsdb_search_state *sstate;
1879 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1880 "userAccountControl", "description", NULL };
1881 struct ldb_result *res;
1882 int i, rc, num_users;
1885 char *expression = NULL;
1887 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1892 va_start(ap, exp_fmt);
1893 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1897 talloc_free(tmp_ctx);
1898 return LDB_ERR_OPERATIONS_ERROR;
1901 sstate = talloc_zero(tmp_ctx, struct pdb_samba_dsdb_search_state);
1902 if (sstate == NULL) {
1903 talloc_free(tmp_ctx);
1907 rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1908 if (rc != LDB_SUCCESS) {
1909 talloc_free(tmp_ctx);
1910 DEBUG(10, ("dsdb_search failed: %s\n",
1911 ldb_errstring(state->ldb)));
1915 num_users = res->count;
1917 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1919 if (sstate->entries == NULL) {
1920 talloc_free(tmp_ctx);
1921 DEBUG(10, ("talloc failed\n"));
1925 sstate->num_entries = 0;
1927 for (i=0; i<num_users; i++) {
1928 struct samr_displayentry *e;
1929 struct dom_sid *sid;
1931 e = &sstate->entries[sstate->num_entries];
1933 e->idx = sstate->num_entries;
1934 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1936 talloc_free(tmp_ctx);
1937 DEBUG(10, ("Could not pull SID\n"));
1940 sid_peek_rid(sid, &e->rid);
1942 e->acct_flags = samdb_result_acct_flags(state->ldb, tmp_ctx,
1944 ldb_get_default_basedn(state->ldb));
1945 e->account_name = ldb_msg_find_attr_as_string(
1946 res->msgs[i], "samAccountName", NULL);
1947 if (e->account_name == NULL) {
1948 talloc_free(tmp_ctx);
1951 e->fullname = ldb_msg_find_attr_as_string(
1952 res->msgs[i], "displayName", "");
1953 e->description = ldb_msg_find_attr_as_string(
1954 res->msgs[i], "description", "");
1956 sstate->num_entries += 1;
1957 if (sstate->num_entries >= num_users) {
1961 talloc_steal(sstate->entries, res->msgs);
1962 search->private_data = talloc_steal(search, sstate);
1963 search->next_entry = pdb_samba_dsdb_next_entry;
1964 search->search_end = pdb_samba_dsdb_search_end;
1966 talloc_free(tmp_ctx);
1970 static bool pdb_samba_dsdb_search_users(struct pdb_methods *m,
1971 struct pdb_search *search,
1974 struct pdb_samba_dsdb_search_state *sstate;
1977 ret = pdb_samba_dsdb_search_filter(m, search, &sstate, "(objectclass=user)");
1981 sstate->acct_flags = acct_flags;
1985 static bool pdb_samba_dsdb_search_groups(struct pdb_methods *m,
1986 struct pdb_search *search)
1988 struct pdb_samba_dsdb_search_state *sstate;
1991 ret = pdb_samba_dsdb_search_filter(m, search, &sstate,
1992 "(&(grouptype=%d)(objectclass=group))",
1993 GTYPE_SECURITY_GLOBAL_GROUP);
1997 sstate->acct_flags = 0;
2001 static bool pdb_samba_dsdb_search_aliases(struct pdb_methods *m,
2002 struct pdb_search *search,
2003 const struct dom_sid *sid)
2005 struct pdb_samba_dsdb_search_state *sstate;
2008 ret = pdb_samba_dsdb_search_filter(m, search, &sstate,
2009 "(&(grouptype=%d)(objectclass=group))",
2010 sid_check_is_builtin(sid)
2011 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2012 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
2016 sstate->acct_flags = 0;
2020 static bool pdb_samba_dsdb_uid_to_sid(struct pdb_methods *m, uid_t uid,
2021 struct dom_sid *sid)
2023 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2024 m->private_data, struct pdb_samba_dsdb_state);
2026 struct id_map id_map;
2027 struct id_map *id_maps[2];
2028 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2033 id_map.xid.id = uid;
2034 id_map.xid.type = ID_TYPE_UID;
2035 id_maps[0] = &id_map;
2038 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2039 if (!NT_STATUS_IS_OK(status)) {
2040 talloc_free(tmp_ctx);
2044 talloc_free(tmp_ctx);
2048 static bool pdb_samba_dsdb_gid_to_sid(struct pdb_methods *m, gid_t gid,
2049 struct dom_sid *sid)
2051 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2052 m->private_data, struct pdb_samba_dsdb_state);
2054 struct id_map id_map;
2055 struct id_map *id_maps[2];
2056 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2061 id_map.xid.id = gid;
2062 id_map.xid.type = ID_TYPE_GID;
2063 id_maps[0] = &id_map;
2066 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2067 if (!NT_STATUS_IS_OK(status)) {
2071 talloc_free(tmp_ctx);
2075 static bool pdb_samba_dsdb_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2078 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2079 m->private_data, struct pdb_samba_dsdb_state);
2080 struct id_map id_map;
2081 struct id_map *id_maps[2];
2083 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2088 ZERO_STRUCT(id_map);
2089 id_map.sid = discard_const_p(struct dom_sid, sid);
2090 id_maps[0] = &id_map;
2093 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2094 talloc_free(tmp_ctx);
2095 if (!NT_STATUS_IS_OK(status)) {
2098 if (id_map.xid.type != ID_TYPE_NOT_SPECIFIED) {
2105 static uint32_t pdb_samba_dsdb_capabilities(struct pdb_methods *m)
2107 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2110 static bool pdb_samba_dsdb_new_rid(struct pdb_methods *m, uint32 *rid)
2115 static bool pdb_samba_dsdb_get_trusteddom_pw(struct pdb_methods *m,
2116 const char *domain, char** pwd,
2117 struct dom_sid *sid,
2118 time_t *pass_last_set_time)
2123 static bool pdb_samba_dsdb_set_trusteddom_pw(struct pdb_methods *m,
2124 const char* domain, const char* pwd,
2125 const struct dom_sid *sid)
2130 static bool pdb_samba_dsdb_del_trusteddom_pw(struct pdb_methods *m,
2136 static NTSTATUS pdb_samba_dsdb_enum_trusteddoms(struct pdb_methods *m,
2137 TALLOC_CTX *mem_ctx,
2138 uint32 *num_domains,
2139 struct trustdom_info ***domains)
2143 return NT_STATUS_OK;
2146 static bool pdb_samba_dsdb_is_responsible_for_wellknown(struct pdb_methods *m)
2151 static void pdb_samba_dsdb_init_methods(struct pdb_methods *m)
2153 m->name = "samba_dsdb";
2154 m->get_domain_info = pdb_samba_dsdb_get_domain_info;
2155 m->getsampwnam = pdb_samba_dsdb_getsampwnam;
2156 m->getsampwsid = pdb_samba_dsdb_getsampwsid;
2157 m->create_user = pdb_samba_dsdb_create_user;
2158 m->delete_user = pdb_samba_dsdb_delete_user;
2159 m->add_sam_account = pdb_samba_dsdb_add_sam_account;
2160 m->update_sam_account = pdb_samba_dsdb_update_sam_account;
2161 m->delete_sam_account = pdb_samba_dsdb_delete_sam_account;
2162 m->rename_sam_account = pdb_samba_dsdb_rename_sam_account;
2163 m->update_login_attempts = pdb_samba_dsdb_update_login_attempts;
2164 m->getgrsid = pdb_samba_dsdb_getgrsid;
2165 m->getgrgid = pdb_samba_dsdb_getgrgid;
2166 m->getgrnam = pdb_samba_dsdb_getgrnam;
2167 m->create_dom_group = pdb_samba_dsdb_create_dom_group;
2168 m->delete_dom_group = pdb_samba_dsdb_delete_dom_group;
2169 m->add_group_mapping_entry = pdb_samba_dsdb_add_group_mapping_entry;
2170 m->update_group_mapping_entry = pdb_samba_dsdb_update_group_mapping_entry;
2171 m->delete_group_mapping_entry = pdb_samba_dsdb_delete_group_mapping_entry;
2172 m->enum_group_mapping = pdb_samba_dsdb_enum_group_mapping;
2173 m->enum_group_members = pdb_samba_dsdb_enum_group_members;
2174 m->enum_group_memberships = pdb_samba_dsdb_enum_group_memberships;
2175 m->set_unix_primary_group = pdb_samba_dsdb_set_unix_primary_group;
2176 m->add_groupmem = pdb_samba_dsdb_add_groupmem;
2177 m->del_groupmem = pdb_samba_dsdb_del_groupmem;
2178 m->create_alias = pdb_samba_dsdb_create_alias;
2179 m->delete_alias = pdb_samba_dsdb_delete_alias;
2180 m->get_aliasinfo = pdb_default_get_aliasinfo;
2181 m->add_aliasmem = pdb_samba_dsdb_add_aliasmem;
2182 m->del_aliasmem = pdb_samba_dsdb_del_aliasmem;
2183 m->enum_aliasmem = pdb_samba_dsdb_enum_aliasmem;
2184 m->enum_alias_memberships = pdb_samba_dsdb_enum_alias_memberships;
2185 m->lookup_rids = pdb_samba_dsdb_lookup_rids;
2186 m->lookup_names = pdb_samba_dsdb_lookup_names;
2187 m->get_account_policy = pdb_samba_dsdb_get_account_policy;
2188 m->set_account_policy = pdb_samba_dsdb_set_account_policy;
2189 m->get_seq_num = pdb_samba_dsdb_get_seq_num;
2190 m->search_users = pdb_samba_dsdb_search_users;
2191 m->search_groups = pdb_samba_dsdb_search_groups;
2192 m->search_aliases = pdb_samba_dsdb_search_aliases;
2193 m->uid_to_sid = pdb_samba_dsdb_uid_to_sid;
2194 m->gid_to_sid = pdb_samba_dsdb_gid_to_sid;
2195 m->sid_to_id = pdb_samba_dsdb_sid_to_id;
2196 m->capabilities = pdb_samba_dsdb_capabilities;
2197 m->new_rid = pdb_samba_dsdb_new_rid;
2198 m->get_trusteddom_pw = pdb_samba_dsdb_get_trusteddom_pw;
2199 m->set_trusteddom_pw = pdb_samba_dsdb_set_trusteddom_pw;
2200 m->del_trusteddom_pw = pdb_samba_dsdb_del_trusteddom_pw;
2201 m->enum_trusteddoms = pdb_samba_dsdb_enum_trusteddoms;
2202 m->is_responsible_for_wellknown =
2203 pdb_samba_dsdb_is_responsible_for_wellknown;
2206 static void free_private_data(void **vp)
2208 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2209 *vp, struct pdb_samba_dsdb_state);
2210 talloc_unlink(state, state->ldb);
2214 static NTSTATUS pdb_samba_dsdb_init_secrets(struct pdb_methods *m)
2216 struct pdb_domain_info *dom_info;
2217 struct dom_sid stored_sid;
2218 struct GUID stored_guid;
2219 bool sid_exists_and_matches = false;
2220 bool guid_exists_and_matches = false;
2223 dom_info = pdb_samba_dsdb_get_domain_info(m, m);
2225 return NT_STATUS_UNSUCCESSFUL;
2228 ret = secrets_fetch_domain_sid(dom_info->name, &stored_sid);
2230 if (dom_sid_equal(&stored_sid, &dom_info->sid)) {
2231 sid_exists_and_matches = true;
2235 if (sid_exists_and_matches == false) {
2236 secrets_clear_domain_protection(dom_info->name);
2237 ret = secrets_store_domain_sid(dom_info->name,
2239 ret &= secrets_mark_domain_protected(dom_info->name);
2245 ret = secrets_fetch_domain_guid(dom_info->name, &stored_guid);
2247 if (GUID_equal(&stored_guid, &dom_info->guid)) {
2248 guid_exists_and_matches = true;
2252 if (guid_exists_and_matches == false) {
2253 secrets_clear_domain_protection(dom_info->name);
2254 ret = secrets_store_domain_guid(dom_info->name,
2256 ret &= secrets_mark_domain_protected(dom_info->name);
2263 TALLOC_FREE(dom_info);
2265 return NT_STATUS_UNSUCCESSFUL;
2267 return NT_STATUS_OK;
2270 static NTSTATUS pdb_init_samba_dsdb(struct pdb_methods **pdb_method,
2271 const char *location)
2273 struct pdb_methods *m;
2274 struct pdb_samba_dsdb_state *state;
2277 if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2281 state = talloc_zero(m, struct pdb_samba_dsdb_state);
2282 if (state == NULL) {
2285 m->private_data = state;
2286 m->free_private_data = free_private_data;
2287 pdb_samba_dsdb_init_methods(m);
2289 state->ev = s4_event_context_init(state);
2291 DEBUG(0, ("s4_event_context_init failed\n"));
2295 state->lp_ctx = loadparm_init_s3(state, loadparm_s3_helpers());
2296 if (state->lp_ctx == NULL) {
2297 DEBUG(0, ("loadparm_init_s3 failed\n"));
2302 state->ldb = samdb_connect_url(state,
2305 system_session(state->lp_ctx),
2308 state->ldb = samdb_connect(state,
2311 system_session(state->lp_ctx), 0);
2315 DEBUG(0, ("samdb_connect failed\n"));
2316 status = NT_STATUS_INTERNAL_ERROR;
2320 state->idmap_ctx = idmap_init(state, state->ev,
2322 if (!state->idmap_ctx) {
2323 DEBUG(0, ("idmap failed\n"));
2324 status = NT_STATUS_INTERNAL_ERROR;
2328 status = pdb_samba_dsdb_init_secrets(m);
2329 if (!NT_STATUS_IS_OK(status)) {
2330 DEBUG(10, ("pdb_samba_dsdb_init_secrets failed!\n"));
2335 return NT_STATUS_OK;
2337 status = NT_STATUS_NO_MEMORY;
2343 NTSTATUS pdb_samba_dsdb_init(void);
2344 NTSTATUS pdb_samba_dsdb_init(void)
2346 NTSTATUS status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba_dsdb",
2347 pdb_init_samba_dsdb);
2348 if (!NT_STATUS_IS_OK(status)) {
2351 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
2352 pdb_init_samba_dsdb);