2 Unix SMB/CIFS implementation.
3 pdb glue module for samba4
4 Copyright (C) Volker Lendecke 2009-2011
5 Copyright (C) Andrew Bartlett 2010
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"
38 struct pdb_samba4_state {
39 struct tevent_context *ev;
40 struct ldb_context *ldb;
41 struct idmap_context *idmap_ctx;
42 struct loadparm_context *lp_ctx;
45 static NTSTATUS pdb_samba4_getsampwsid(struct pdb_methods *m,
46 struct samu *sam_acct,
47 const struct dom_sid *sid);
48 static NTSTATUS pdb_samba4_getsamupriv(struct pdb_samba4_state *state,
51 struct ldb_message **pmsg);
52 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
53 union unid_t *id, enum lsa_SidType *type);
55 static bool pdb_samba4_pull_time(struct ldb_message *msg, const char *attr,
59 if (! ldb_msg_find_element(msg, attr)) {
62 tmp = ldb_msg_find_attr_as_uint64(msg, attr, 0);
63 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
67 static struct pdb_domain_info *pdb_samba4_get_domain_info(
68 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
70 struct pdb_samba4_state *state = talloc_get_type_abort(
71 m->private_data, struct pdb_samba4_state);
72 struct pdb_domain_info *info;
73 struct dom_sid *domain_sid;
74 struct ldb_dn *forest_dn, *domain_dn;
75 struct ldb_result *dom_res = NULL;
76 const char *dom_attrs[] = {
85 info = talloc(mem_ctx, struct pdb_domain_info);
90 domain_dn = ldb_get_default_basedn(state->ldb);
92 ret = ldb_search(state->ldb, info, &dom_res,
93 domain_dn, LDB_SCOPE_BASE, dom_attrs, NULL);
94 if (ret != LDB_SUCCESS) {
97 if (dom_res->count != 1) {
101 info->guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
103 domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
107 info->sid = *domain_sid;
109 TALLOC_FREE(dom_res);
111 info->name = talloc_strdup(info, lpcfg_sam_name(state->lp_ctx));
112 info->dns_domain = ldb_dn_canonical_string(info, domain_dn);
114 if (!info->dns_domain) {
117 p = strchr(info->dns_domain, '/');
122 forest_dn = ldb_get_root_basedn(state->ldb);
127 info->dns_forest = ldb_dn_canonical_string(info, forest_dn);
128 if (!info->dns_forest) {
131 p = strchr(info->dns_forest, '/');
139 TALLOC_FREE(dom_res);
144 static struct ldb_message *pdb_samba4_get_samu_private(
145 struct pdb_methods *m, struct samu *sam)
147 struct pdb_samba4_state *state = talloc_get_type_abort(
148 m->private_data, struct pdb_samba4_state);
149 struct ldb_message *msg;
150 char *sidstr, *filter;
153 msg = (struct ldb_message *)
154 pdb_get_backend_private_data(sam, m);
157 return talloc_get_type_abort(msg, struct ldb_message);
160 sidstr = dom_sid_string(talloc_tos(), pdb_get_user_sid(sam));
161 if (sidstr == NULL) {
165 filter = talloc_asprintf(
166 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
168 if (filter == NULL) {
172 status = pdb_samba4_getsamupriv(state, filter, sam, &msg);
174 if (!NT_STATUS_IS_OK(status)) {
181 static NTSTATUS pdb_samba4_init_sam_from_priv(struct pdb_methods *m,
183 struct ldb_message *msg)
185 struct pdb_samba4_state *state = talloc_get_type_abort(
186 m->private_data, struct pdb_samba4_state);
187 TALLOC_CTX *frame = talloc_stackframe();
188 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
191 struct dom_sid *sid, group_sid;
193 const DATA_BLOB *blob;
195 str = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
197 DEBUG(10, ("no samAccountName\n"));
200 pdb_set_username(sam, str, PDB_SET);
202 if (pdb_samba4_pull_time(msg, "lastLogon", &tmp_time)) {
203 pdb_set_logon_time(sam, tmp_time, PDB_SET);
205 if (pdb_samba4_pull_time(msg, "lastLogoff", &tmp_time)) {
206 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
208 if (pdb_samba4_pull_time(msg, "pwdLastSet", &tmp_time)) {
209 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
211 if (pdb_samba4_pull_time(msg, "accountExpires", &tmp_time)) {
212 pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
215 str = ldb_msg_find_attr_as_string(msg, "displayName",
218 pdb_set_fullname(sam, str, PDB_SET);
221 str = ldb_msg_find_attr_as_string(msg, "homeDirectory",
224 pdb_set_homedir(sam, str, PDB_SET);
227 str = ldb_msg_find_attr_as_string(msg, "homeDrive", NULL);
229 pdb_set_dir_drive(sam, str, PDB_SET);
232 str = ldb_msg_find_attr_as_string(msg, "scriptPath", NULL);
234 pdb_set_logon_script(sam, str, PDB_SET);
237 str = ldb_msg_find_attr_as_string(msg, "profilePath",
240 pdb_set_profile_path(sam, str, PDB_SET);
243 str = ldb_msg_find_attr_as_string(msg, "profilePath",
246 pdb_set_profile_path(sam, str, PDB_SET);
249 str = ldb_msg_find_attr_as_string(msg, "comment",
252 pdb_set_comment(sam, str, PDB_SET);
255 str = ldb_msg_find_attr_as_string(msg, "description",
258 pdb_set_acct_desc(sam, str, PDB_SET);
261 str = ldb_msg_find_attr_as_string(msg, "userWorkstations",
264 pdb_set_workstations(sam, str, PDB_SET);
267 str = ldb_msg_find_attr_as_string(msg, "userParameters",
270 pdb_set_munged_dial(sam, str, PDB_SET);
273 sid = samdb_result_dom_sid(talloc_tos(), msg, "objectSid");
275 DEBUG(10, ("Could not pull SID\n"));
278 pdb_set_user_sid(sam, sid, PDB_SET);
280 n = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
282 DEBUG(10, ("Could not pull userAccountControl\n"));
285 pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
287 blob = ldb_msg_find_ldb_val(msg, "unicodePwd");
289 if (blob->length != NT_HASH_LEN) {
290 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
291 (int)blob->length, NT_HASH_LEN));
294 pdb_set_nt_passwd(sam, blob->data, PDB_SET);
297 blob = ldb_msg_find_ldb_val(msg, "dBCSPwd");
299 if (blob->length != LM_HASH_LEN) {
300 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
301 (int)blob->length, LM_HASH_LEN));
304 pdb_set_lanman_passwd(sam, blob->data, PDB_SET);
307 n = ldb_msg_find_attr_as_uint(msg, "primaryGroupID", 0);
309 DEBUG(10, ("Could not pull primaryGroupID\n"));
312 sid_compose(&group_sid, samdb_domain_sid(state->ldb), n);
313 pdb_set_group_sid(sam, &group_sid, PDB_SET);
315 status = NT_STATUS_OK;
321 static bool pdb_samba4_add_time(struct ldb_message *msg,
322 const char *attrib, time_t t)
326 unix_to_nt_time(&nt_time, t);
328 return ldb_msg_add_fmt(msg, attrib, "%llu", (unsigned long long) nt_time);
331 static int pdb_samba4_replace_by_sam(struct pdb_samba4_state *state,
332 bool (*need_update)(const struct samu *,
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(talloc_tos());
351 /* build modify request */
352 ret = ldb_build_mod_req(&req, state->ldb, talloc_tos(), msg, NULL, NULL,
353 ldb_op_default_callback,
355 if (ret != LDB_SUCCESS) {
360 pw = pdb_get_plaintext_passwd(sam);
361 if (need_update(sam, PDB_PLAINTEXT_PW)) {
363 return LDB_ERR_OPERATIONS_ERROR;
366 ret |= ldb_msg_add_string(msg, "clearTextPassword", pw);
368 bool changed_lm_pw = false;
369 bool changed_nt_pw = false;
370 bool changed_history = false;
371 if (need_update(sam, PDB_LMPASSWD)) {
373 val.data = pdb_get_lanman_passwd(sam);
375 samdb_msg_add_delete(state->ldb, msg, msg,
378 val.length = LM_HASH_LEN;
379 ret |= ldb_msg_add_value(msg, "dBCSPwd", &val, NULL);
381 changed_lm_pw = true;
383 if (need_update(sam, PDB_NTPASSWD)) {
385 val.data = pdb_get_nt_passwd(sam);
387 samdb_msg_add_delete(state->ldb, msg, msg,
390 val.length = NT_HASH_LEN;
391 ret |= ldb_msg_add_value(msg, "unicodePwd", &val, NULL);
393 changed_nt_pw = true;
396 /* Try to ensure we don't get out of sync */
397 if (changed_lm_pw && !changed_nt_pw) {
398 samdb_msg_add_delete(state->ldb, msg, msg,
400 } else if (changed_nt_pw && !changed_lm_pw) {
401 samdb_msg_add_delete(state->ldb, msg, msg,
404 if (changed_lm_pw || changed_nt_pw) {
405 samdb_msg_add_delete(state->ldb, msg, msg,
406 "supplementalCredentials");
410 /* If we set a plaintext password, the system will
411 * force the pwdLastSet to now(), and it isn't worth
412 * working around this for the real world use cases of
414 if (need_update(sam, PDB_PASSLASTSET)) {
415 ret |= pdb_samba4_add_time(msg, "pwdLastSet",
416 pdb_get_pass_last_set_time(sam));
419 if (need_update(sam, PDB_PWHISTORY)) {
420 uint32_t current_hist_len;
421 const uint8_t *history = pdb_get_pw_history(sam, ¤t_hist_len);
423 bool invalid_history = false;
424 struct samr_Password *history_hashes = talloc_array(talloc_tos(), struct samr_Password,
427 invalid_history = true;
430 static const uint8_t zeros[16];
431 /* Parse the history into the correct format */
432 for (i = 0; i < current_hist_len; i++) {
433 if (memcmp(&history[i*PW_HISTORY_ENTRY_LEN], zeros, 16) != 0) {
434 /* If the history is in the old format, with a salted hash, then we can't migrate it to AD format */
435 invalid_history = true;
438 /* Copy out the 2nd 16 bytes of the 32 byte password history, containing the NT hash */
439 memcpy(history_hashes[i].hash,
440 &history[(i*PW_HISTORY_ENTRY_LEN) + PW_HISTORY_SALT_LEN],
441 sizeof(history_hashes[i].hash));
444 if (invalid_history) {
445 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
448 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
451 ret |= samdb_msg_add_hashes(state->ldb, msg, msg,
456 changed_history = true;
458 if (changed_lm_pw || changed_nt_pw || changed_history) {
459 /* These attributes can only be modified directly by using a special control */
460 dsdb_flags = DSDB_BYPASS_PASSWORD_HASH;
464 /* PDB_USERSID is only allowed on ADD, handled in caller */
465 if (need_update(sam, PDB_GROUPSID)) {
466 const struct dom_sid *sid = pdb_get_group_sid(sam);
468 NTSTATUS status = dom_sid_split_rid(NULL, sid, NULL, &rid);
469 if (!NT_STATUS_IS_OK(status)) {
470 return LDB_ERR_OPERATIONS_ERROR;
472 if (!dom_sid_in_domain(samdb_domain_sid(state->ldb), sid)) {
473 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
475 ret |= samdb_msg_add_uint(state->ldb, msg, msg, "primaryGroupID", rid);
477 if (need_update(sam, PDB_FULLNAME)) {
478 ret |= ldb_msg_add_string(msg, "displayName", pdb_get_fullname(sam));
481 if (need_update(sam, PDB_SMBHOME)) {
482 ret |= ldb_msg_add_string(msg, "homeDirectory",
483 pdb_get_homedir(sam));
486 if (need_update(sam, PDB_PROFILE)) {
487 ret |= ldb_msg_add_string(msg, "profilePath",
488 pdb_get_profile_path(sam));
491 if (need_update(sam, PDB_DRIVE)) {
492 ret |= ldb_msg_add_string(msg, "homeDrive",
493 pdb_get_dir_drive(sam));
496 if (need_update(sam, PDB_LOGONSCRIPT)) {
497 ret |= ldb_msg_add_string(msg, "scriptPath",
498 pdb_get_logon_script(sam));
501 if (need_update(sam, PDB_KICKOFFTIME)) {
502 ret |= pdb_samba4_add_time(msg, "accountExpires",
503 pdb_get_kickoff_time(sam));
506 if (need_update(sam, PDB_USERNAME)) {
507 ret |= ldb_msg_add_string(msg, "samAccountName",
508 pdb_get_username(sam));
511 if (need_update(sam, PDB_HOURSLEN) || need_update(sam, PDB_HOURS)) {
512 struct ldb_val hours = data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam));
513 ret |= ldb_msg_add_value(msg, "logonHours",
517 if (need_update(sam, PDB_ACCTCTRL)) {
518 ret |= samdb_msg_add_acct_flags(state->ldb, msg, msg,
519 "userAccountControl", pdb_get_acct_ctrl(sam));
522 if (need_update(sam, PDB_COMMENT)) {
523 ret |= ldb_msg_add_string(msg, "comment",
524 pdb_get_comment(sam));
527 if (need_update(sam, PDB_ACCTDESC)) {
528 ret |= ldb_msg_add_string(msg, "description",
529 pdb_get_acct_desc(sam));
532 if (need_update(sam, PDB_WORKSTATIONS)) {
533 ret |= ldb_msg_add_string(msg, "userWorkstations",
534 pdb_get_workstations(sam));
537 /* This will need work, it is actually a UTF8 'string' with internal NULLs, to handle TS parameters */
538 if (need_update(sam, PDB_MUNGEDDIAL)) {
539 ret |= ldb_msg_add_string(msg, "userParameters",
540 pdb_get_munged_dial(sam));
543 if (need_update(sam, PDB_COUNTRY_CODE)) {
544 ret |= ldb_msg_add_fmt(msg, "countryCode",
545 "%i", (int)pdb_get_country_code(sam));
548 if (need_update(sam, PDB_CODE_PAGE)) {
549 ret |= ldb_msg_add_fmt(msg, "codePage",
550 "%i", (int)pdb_get_code_page(sam));
553 /* Not yet handled here or not meaningful for modifies on a Samba4 backend:
556 PDB_BAD_PASSWORD_TIME,
557 PDB_CANCHANGETIME, - these are calculated per policy, not stored
558 PDB_MUSTCHANGETIME, - these are calculated per policy, not stored
560 PDB_NTUSERNAME, - this makes no sense, and never really did
562 PDB_USERSID, - Handled in pdb_samba4_add_sam_account()
564 PDB_BAD_PASSWORD_COUNT,
567 PDB_BACKEND_PRIVATE_DATA,
570 if (ret != LDB_SUCCESS) {
571 return LDB_ERR_OPERATIONS_ERROR;
574 if (msg->num_elements == 0) {
575 /* Nothing to do, just return success */
579 ret = dsdb_replace(state->ldb, msg, dsdb_flags);
581 if (ret != LDB_SUCCESS) {
582 DEBUG(0,("Failed to modify account record %s to set user attributes: %s\n",
583 ldb_dn_get_linearized(msg->dn),
584 ldb_errstring(state->ldb)));
590 static NTSTATUS pdb_samba4_getsamupriv(struct pdb_samba4_state *state,
593 struct ldb_message **msg)
595 const char * attrs[] = {
596 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
597 "sAMAccountName", "displayName", "homeDirectory",
598 "homeDrive", "scriptPath", "profilePath", "description",
599 "userWorkstations", "comment", "userParameters", "objectSid",
600 "primaryGroupID", "userAccountControl", "logonHours",
601 "badPwdCount", "logonCount", "countryCode", "codePage",
602 "unicodePwd", "dBCSPwd", NULL };
604 int rc = dsdb_search_one(state->ldb, mem_ctx, msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", filter);
605 if (rc != LDB_SUCCESS) {
606 DEBUG(10, ("ldap_search failed %s\n",
607 ldb_errstring(state->ldb)));
608 return NT_STATUS_LDAP(rc);
614 static NTSTATUS pdb_samba4_getsampwfilter(struct pdb_methods *m,
615 struct pdb_samba4_state *state,
616 struct samu *sam_acct,
617 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
619 struct ldb_message *priv;
622 char *expression = NULL;
623 TALLOC_CTX *tmp_ctx = talloc_new(state);
624 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
626 va_start(ap, exp_fmt);
627 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
631 talloc_free(tmp_ctx);
632 return NT_STATUS_NO_MEMORY;
635 status = pdb_samba4_getsamupriv(state, expression, sam_acct, &priv);
636 talloc_free(tmp_ctx);
637 if (!NT_STATUS_IS_OK(status)) {
638 DEBUG(10, ("pdb_samba4_getsamupriv failed: %s\n",
643 status = pdb_samba4_init_sam_from_priv(m, sam_acct, priv);
644 if (!NT_STATUS_IS_OK(status)) {
645 DEBUG(10, ("pdb_samba4_init_sam_from_priv failed: %s\n",
651 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
655 static NTSTATUS pdb_samba4_getsampwnam(struct pdb_methods *m,
656 struct samu *sam_acct,
657 const char *username)
659 struct pdb_samba4_state *state = talloc_get_type_abort(
660 m->private_data, struct pdb_samba4_state);
662 return pdb_samba4_getsampwfilter(m, state, sam_acct,
663 "(&(samaccountname=%s)(objectclass=user))",
667 static NTSTATUS pdb_samba4_getsampwsid(struct pdb_methods *m,
668 struct samu *sam_acct,
669 const struct dom_sid *sid)
672 struct pdb_samba4_state *state = talloc_get_type_abort(
673 m->private_data, struct pdb_samba4_state);
676 sidstr = dom_sid_string(talloc_tos(), sid);
677 NT_STATUS_HAVE_NO_MEMORY(sidstr);
679 status = pdb_samba4_getsampwfilter(m, state, sam_acct,
680 "(&(objectsid=%s)(objectclass=user))",
686 static NTSTATUS pdb_samba4_create_user(struct pdb_methods *m,
688 const char *name, uint32 acct_flags,
691 struct pdb_samba4_state *state = talloc_get_type_abort(
692 m->private_data, struct pdb_samba4_state);
696 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
697 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
699 /* Internally this uses transactions to ensure all the steps
700 * happen or fail as one */
701 status = dsdb_add_user(state->ldb, tmp_ctx, name, acct_flags, NULL,
703 if (!NT_STATUS_IS_OK(status)) {
704 talloc_free(tmp_ctx);
707 sid_peek_rid(sid, rid);
708 talloc_free(tmp_ctx);
712 static NTSTATUS pdb_samba4_delete_user(struct pdb_methods *m,
716 struct pdb_samba4_state *state = talloc_get_type_abort(
717 m->private_data, struct pdb_samba4_state);
720 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
721 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
723 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, pdb_get_user_sid(sam)));
724 if (!dn || !ldb_dn_validate(dn)) {
725 talloc_free(tmp_ctx);
726 return NT_STATUS_NO_MEMORY;
728 rc = ldb_delete(state->ldb, dn);
730 if (rc != LDB_SUCCESS) {
731 DEBUG(10, ("ldb_delete for %s failed: %s\n", ldb_dn_get_linearized(dn),
732 ldb_errstring(state->ldb)));
733 talloc_free(tmp_ctx);
734 return NT_STATUS_LDAP(rc);
736 talloc_free(tmp_ctx);
740 /* This interface takes a fully populated struct samu and places it in
741 * the database. This is not implemented at this time as we need to
742 * be careful around the creation of arbitary SIDs (ie, we must ensrue
743 * they are not left in a RID pool */
744 static NTSTATUS pdb_samba4_add_sam_account(struct pdb_methods *m,
745 struct samu *sampass)
750 struct pdb_samba4_state *state = talloc_get_type_abort(
751 m->private_data, struct pdb_samba4_state);
752 uint32_t acb_flags = pdb_get_acct_ctrl(sampass);
753 const char *username = pdb_get_username(sampass);
754 const struct dom_sid *user_sid = pdb_get_user_sid(sampass);
755 TALLOC_CTX *tframe = talloc_stackframe();
757 acb_flags &= (ACB_NORMAL|ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST);
759 ret = ldb_transaction_start(state->ldb);
760 if (ret != LDB_SUCCESS) {
762 return NT_STATUS_LOCK_NOT_GRANTED;
765 status = dsdb_add_user(state->ldb, talloc_tos(), username,
766 acb_flags, user_sid, NULL, &dn);
767 if (!NT_STATUS_IS_OK(status)) {
768 ldb_transaction_cancel(state->ldb);
773 ret = pdb_samba4_replace_by_sam(state, pdb_element_is_set_or_changed,
775 if (ret != LDB_SUCCESS) {
776 ldb_transaction_cancel(state->ldb);
778 return dsdb_ldb_err_to_ntstatus(ret);
781 ret = ldb_transaction_commit(state->ldb);
782 if (ret != LDB_SUCCESS) {
783 DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
784 ldb_dn_get_linearized(dn),
785 ldb_errstring(state->ldb)));
787 return NT_STATUS_INTERNAL_DB_CORRUPTION;
794 * Update the Samba4 LDB with the changes from a struct samu.
796 * This takes care not to update elements that have not been changed
799 static NTSTATUS pdb_samba4_update_sam_account(struct pdb_methods *m,
802 struct pdb_samba4_state *state = talloc_get_type_abort(
803 m->private_data, struct pdb_samba4_state);
804 struct ldb_message *msg = pdb_samba4_get_samu_private(
808 ret = pdb_samba4_replace_by_sam(state, pdb_element_is_changed, msg->dn,
810 return dsdb_ldb_err_to_ntstatus(ret);
813 static NTSTATUS pdb_samba4_delete_sam_account(struct pdb_methods *m,
814 struct samu *username)
817 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
818 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
819 status = pdb_samba4_delete_user(m, tmp_ctx, username);
820 talloc_free(tmp_ctx);
824 static NTSTATUS pdb_samba4_rename_sam_account(struct pdb_methods *m,
825 struct samu *oldname,
828 return NT_STATUS_NOT_IMPLEMENTED;
831 /* This is not implemented, as this module is exptected to be used
832 * with auth_samba4, and this is responible for login counters etc
835 static NTSTATUS pdb_samba4_update_login_attempts(struct pdb_methods *m,
836 struct samu *sam_acct,
839 return NT_STATUS_NOT_IMPLEMENTED;
842 static NTSTATUS pdb_samba4_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
843 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
845 struct pdb_samba4_state *state = talloc_get_type_abort(
846 m->private_data, struct pdb_samba4_state);
847 const char *attrs[] = { "objectSid", "description", "samAccountName",
849 struct ldb_message *msg;
851 char *expression = NULL;
856 TALLOC_CTX *tmp_ctx = talloc_stackframe();
857 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
859 va_start(ap, exp_fmt);
860 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
864 talloc_free(tmp_ctx);
865 return NT_STATUS_NO_MEMORY;
868 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
869 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
870 talloc_free(tmp_ctx);
871 return NT_STATUS_NO_SUCH_GROUP;
872 } else if (rc != LDB_SUCCESS) {
873 talloc_free(tmp_ctx);
874 DEBUG(10, ("dsdb_search_one failed %s\n",
875 ldb_errstring(state->ldb)));
876 return NT_STATUS_LDAP(rc);
879 sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
881 talloc_free(tmp_ctx);
882 DEBUG(10, ("Could not pull SID\n"));
883 return NT_STATUS_INTERNAL_DB_CORRUPTION;
888 if (!pdb_samba4_sid_to_id(m, sid, &id, &map->sid_name_use)) {
889 talloc_free(tmp_ctx);
890 return NT_STATUS_NO_SUCH_GROUP;
892 if (map->sid_name_use == SID_NAME_USER) {
893 DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
894 return NT_STATUS_INTERNAL_DB_CORRUPTION;
898 str = ldb_msg_find_attr_as_string(msg, "samAccountName",
901 talloc_free(tmp_ctx);
902 return NT_STATUS_INTERNAL_DB_CORRUPTION;
904 fstrcpy(map->nt_name, str);
906 str = ldb_msg_find_attr_as_string(msg, "description",
909 fstrcpy(map->comment, str);
911 map->comment[0] = '\0';
914 talloc_free(tmp_ctx);
918 static NTSTATUS pdb_samba4_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
924 filter = talloc_asprintf(talloc_tos(),
925 "(&(objectsid=%s)(objectclass=group))",
926 sid_string_talloc(talloc_tos(), &sid));
927 if (filter == NULL) {
928 return NT_STATUS_NO_MEMORY;
931 status = pdb_samba4_getgrfilter(m, map, filter);
936 static NTSTATUS pdb_samba4_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
939 struct pdb_samba4_state *state = talloc_get_type_abort(
940 m->private_data, struct pdb_samba4_state);
942 struct id_map id_map;
943 struct id_map *id_maps[2];
944 TALLOC_CTX *tmp_ctx = talloc_stackframe();
945 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
948 id_map.xid.type = ID_TYPE_GID;
949 id_maps[0] = &id_map;
952 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
953 if (!NT_STATUS_IS_OK(status)) {
956 status = pdb_samba4_getgrsid(m, map, *id_map.sid);
957 talloc_free(tmp_ctx);
961 static NTSTATUS pdb_samba4_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
967 filter = talloc_asprintf(talloc_tos(),
968 "(&(samaccountname=%s)(objectclass=group))",
970 if (filter == NULL) {
971 return NT_STATUS_NO_MEMORY;
974 status = pdb_samba4_getgrfilter(m, map, filter);
979 static NTSTATUS pdb_samba4_create_dom_group(struct pdb_methods *m,
980 TALLOC_CTX *mem_ctx, const char *name,
983 struct pdb_samba4_state *state = talloc_get_type_abort(
984 m->private_data, struct pdb_samba4_state);
988 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
989 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
991 status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
992 if (!NT_STATUS_IS_OK(status)) {
993 talloc_free(tmp_ctx);
997 sid_peek_rid(sid, rid);
998 talloc_free(tmp_ctx);
1002 static NTSTATUS pdb_samba4_delete_dom_group(struct pdb_methods *m,
1003 TALLOC_CTX *mem_ctx, uint32 rid)
1005 const char *attrs[] = { NULL };
1006 struct pdb_samba4_state *state = talloc_get_type_abort(
1007 m->private_data, struct pdb_samba4_state);
1009 struct ldb_message *msg;
1012 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1013 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1015 sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
1017 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1018 DEBUG(0, ("Unable to start transaction in pdb_samba4_delete_dom_group()\n"));
1019 return NT_STATUS_INTERNAL_ERROR;
1022 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
1023 if (!dn || !ldb_dn_validate(dn)) {
1024 talloc_free(tmp_ctx);
1025 ldb_transaction_cancel(state->ldb);
1026 return NT_STATUS_NO_MEMORY;
1028 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
1029 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1030 talloc_free(tmp_ctx);
1031 ldb_transaction_cancel(state->ldb);
1032 return NT_STATUS_NO_SUCH_GROUP;
1034 rc = ldb_delete(state->ldb, dn);
1035 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1036 talloc_free(tmp_ctx);
1037 ldb_transaction_cancel(state->ldb);
1038 return NT_STATUS_NO_SUCH_GROUP;
1039 } else if (rc != LDB_SUCCESS) {
1040 DEBUG(10, ("ldb_delete failed %s\n",
1041 ldb_errstring(state->ldb)));
1042 ldb_transaction_cancel(state->ldb);
1043 return NT_STATUS_LDAP(rc);
1046 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1047 DEBUG(0, ("Unable to commit transaction in pdb_samba4_delete_dom_group()\n"));
1048 return NT_STATUS_INTERNAL_ERROR;
1050 return NT_STATUS_OK;
1053 static NTSTATUS pdb_samba4_add_group_mapping_entry(struct pdb_methods *m,
1056 return NT_STATUS_NOT_IMPLEMENTED;
1059 static NTSTATUS pdb_samba4_update_group_mapping_entry(struct pdb_methods *m,
1062 return NT_STATUS_NOT_IMPLEMENTED;
1065 static NTSTATUS pdb_samba4_delete_group_mapping_entry(struct pdb_methods *m,
1068 return NT_STATUS_NOT_IMPLEMENTED;
1071 static NTSTATUS pdb_samba4_enum_group_mapping(struct pdb_methods *m,
1072 const struct dom_sid *sid,
1073 enum lsa_SidType sid_name_use,
1074 GROUP_MAP **pp_rmap,
1075 size_t *p_num_entries,
1078 return NT_STATUS_NOT_IMPLEMENTED;
1081 static NTSTATUS pdb_samba4_enum_group_members(struct pdb_methods *m,
1082 TALLOC_CTX *mem_ctx,
1083 const struct dom_sid *group,
1084 uint32_t **pmembers,
1085 size_t *pnum_members)
1087 unsigned int i, num_sids, num_members;
1088 struct pdb_samba4_state *state = talloc_get_type_abort(
1089 m->private_data, struct pdb_samba4_state);
1090 struct dom_sid *members_as_sids;
1091 struct dom_sid *dom_sid;
1096 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1097 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1099 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
1100 if (!dn || !ldb_dn_validate(dn)) {
1101 return NT_STATUS_NO_MEMORY;
1104 status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
1105 if (!NT_STATUS_IS_OK(status)) {
1106 talloc_free(tmp_ctx);
1109 status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
1110 if (!NT_STATUS_IS_OK(status)) {
1111 talloc_free(tmp_ctx);
1115 *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
1116 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*pmembers, tmp_ctx);
1119 for (i = 0; i < num_sids; i++) {
1120 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
1123 status = dom_sid_split_rid(NULL, &members_as_sids[i],
1124 NULL, &members[num_members]);
1125 if (!NT_STATUS_IS_OK(status)) {
1126 talloc_free(tmp_ctx);
1131 *pnum_members = num_members;
1132 return NT_STATUS_OK;
1135 /* Just convert the primary group SID into a group */
1136 static NTSTATUS fake_enum_group_memberships(struct pdb_samba4_state *state,
1137 TALLOC_CTX *mem_ctx,
1139 struct dom_sid **pp_sids,
1141 uint32_t *p_num_groups)
1144 size_t num_groups = 0;
1145 struct dom_sid *group_sids;
1147 TALLOC_CTX *tmp_ctx;
1149 tmp_ctx = talloc_new(mem_ctx);
1150 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1152 if (user->group_sid) {
1153 struct id_map *id_maps[2];
1154 struct id_map id_map;
1158 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1159 if (group_sids == NULL) {
1160 talloc_free(tmp_ctx);
1161 return NT_STATUS_NO_MEMORY;
1163 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1165 talloc_free(tmp_ctx);
1166 return NT_STATUS_NO_MEMORY;
1169 group_sids[0] = *user->group_sid;
1171 ZERO_STRUCT(id_map);
1172 id_map.sid = &group_sids[0];
1173 id_maps[0] = &id_map;
1176 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1177 if (!NT_STATUS_IS_OK(status)) {
1178 talloc_free(tmp_ctx);
1181 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1182 gids[0] = id_map.xid.id;
1184 DEBUG(1, (__location__
1185 "Group %s, of which %s is a member, could not be converted to a GID\n",
1186 dom_sid_string(tmp_ctx, &group_sids[0]),
1187 dom_sid_string(tmp_ctx, &user->user_sid)));
1188 talloc_free(tmp_ctx);
1189 /* We must error out, otherwise a user might
1190 * avoid a DENY acl based on a group they
1192 return NT_STATUS_NO_SUCH_GROUP;
1196 *pp_sids = talloc_steal(mem_ctx, group_sids);
1197 *pp_gids = talloc_steal(mem_ctx, gids);
1198 *p_num_groups = num_groups;
1199 talloc_free(tmp_ctx);
1200 return NT_STATUS_OK;
1203 static NTSTATUS pdb_samba4_enum_group_memberships(struct pdb_methods *m,
1204 TALLOC_CTX *mem_ctx,
1206 struct dom_sid **pp_sids,
1208 uint32_t *p_num_groups)
1210 struct pdb_samba4_state *state = talloc_get_type_abort(
1211 m->private_data, struct pdb_samba4_state);
1212 struct ldb_message *msg = pdb_samba4_get_samu_private(
1214 const char *attrs[] = { "tokenGroups", NULL};
1215 struct ldb_message *tokengroups_msg;
1216 struct ldb_message_element *tokengroups;
1219 unsigned int count = 0;
1221 struct dom_sid *group_sids;
1223 TALLOC_CTX *tmp_ctx;
1226 /* Fake up some things here */
1227 return fake_enum_group_memberships(state,
1230 pp_gids, p_num_groups);
1233 tmp_ctx = talloc_new(mem_ctx);
1234 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1236 rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1238 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1239 talloc_free(tmp_ctx);
1240 return NT_STATUS_NO_SUCH_USER;
1241 } else if (rc != LDB_SUCCESS) {
1242 DEBUG(10, ("dsdb_search_one failed %s\n",
1243 ldb_errstring(state->ldb)));
1244 talloc_free(tmp_ctx);
1245 return NT_STATUS_LDAP(rc);
1248 tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1251 count = tokengroups->num_values;
1254 group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1255 if (group_sids == NULL) {
1256 talloc_free(tmp_ctx);
1257 return NT_STATUS_NO_MEMORY;
1259 gids = talloc_array(tmp_ctx, gid_t, count);
1261 talloc_free(tmp_ctx);
1262 return NT_STATUS_NO_MEMORY;
1266 for (i=0; i<count; i++) {
1267 struct id_map *id_maps[2];
1268 struct id_map id_map;
1269 struct ldb_val *v = &tokengroups->values[i];
1270 enum ndr_err_code ndr_err
1271 = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1272 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1273 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1274 talloc_free(tmp_ctx);
1275 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1278 ZERO_STRUCT(id_map);
1279 id_map.sid = &group_sids[num_groups];
1280 id_maps[0] = &id_map;
1283 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1284 if (!NT_STATUS_IS_OK(status)) {
1285 talloc_free(tmp_ctx);
1288 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1289 gids[num_groups] = id_map.xid.id;
1291 DEBUG(1, (__location__
1292 "Group %s, of which %s is a member, could not be converted to a GID\n",
1293 dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1294 ldb_dn_get_linearized(msg->dn)));
1295 talloc_free(tmp_ctx);
1296 /* We must error out, otherwise a user might
1297 * avoid a DENY acl based on a group they
1299 return NT_STATUS_NO_SUCH_GROUP;
1303 if (num_groups == count) {
1308 *pp_sids = talloc_steal(mem_ctx, group_sids);
1309 *pp_gids = talloc_steal(mem_ctx, gids);
1310 *p_num_groups = num_groups;
1311 talloc_free(tmp_ctx);
1312 return NT_STATUS_OK;
1315 static NTSTATUS pdb_samba4_set_unix_primary_group(struct pdb_methods *m,
1316 TALLOC_CTX *mem_ctx,
1319 return NT_STATUS_NOT_IMPLEMENTED;
1322 static NTSTATUS pdb_samba4_mod_groupmem_by_sid(struct pdb_methods *m,
1323 TALLOC_CTX *mem_ctx,
1324 const struct dom_sid *groupsid,
1325 const struct dom_sid *membersid,
1328 struct pdb_samba4_state *state = talloc_get_type_abort(
1329 m->private_data, struct pdb_samba4_state);
1330 struct ldb_message *msg;
1332 struct ldb_message_element *el;
1333 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1334 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1335 msg = ldb_msg_new(tmp_ctx);
1336 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, tmp_ctx);
1338 msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1339 if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1340 talloc_free(tmp_ctx);
1341 return NT_STATUS_NO_MEMORY;
1343 ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1344 if (ret != LDB_SUCCESS) {
1345 talloc_free(tmp_ctx);
1346 return NT_STATUS_NO_MEMORY;
1348 el = ldb_msg_find_element(msg, "member");
1351 /* No need for transactions here, the ldb auto-transaction
1352 * code will handle things for the single operation */
1353 ret = ldb_modify(state->ldb, msg);
1354 talloc_free(tmp_ctx);
1355 if (ret != LDB_SUCCESS) {
1356 DEBUG(10, ("ldb_modify failed: %s\n",
1357 ldb_errstring(state->ldb)));
1358 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1359 return NT_STATUS_MEMBER_IN_GROUP;
1361 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1362 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1364 return NT_STATUS_LDAP(ret);
1367 return NT_STATUS_OK;
1370 static NTSTATUS pdb_samba4_mod_groupmem(struct pdb_methods *m,
1371 TALLOC_CTX *mem_ctx,
1372 uint32 grouprid, uint32 memberrid,
1375 struct pdb_samba4_state *state = talloc_get_type_abort(
1376 m->private_data, struct pdb_samba4_state);
1377 const struct dom_sid *dom_sid, *groupsid, *membersid;
1379 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1380 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1382 dom_sid = samdb_domain_sid(state->ldb);
1384 groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1385 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupsid, tmp_ctx);
1386 membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1387 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(membersid, tmp_ctx);
1388 status = pdb_samba4_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1389 talloc_free(tmp_ctx);
1393 static NTSTATUS pdb_samba4_add_groupmem(struct pdb_methods *m,
1394 TALLOC_CTX *mem_ctx,
1395 uint32 group_rid, uint32 member_rid)
1397 return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1401 static NTSTATUS pdb_samba4_del_groupmem(struct pdb_methods *m,
1402 TALLOC_CTX *mem_ctx,
1403 uint32 group_rid, uint32 member_rid)
1405 return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1406 LDB_FLAG_MOD_DELETE);
1409 static NTSTATUS pdb_samba4_create_alias(struct pdb_methods *m,
1410 const char *name, uint32 *rid)
1412 TALLOC_CTX *frame = talloc_stackframe();
1413 struct pdb_samba4_state *state = talloc_get_type_abort(
1414 m->private_data, struct pdb_samba4_state);
1415 struct dom_sid *sid;
1420 /* Internally this uses transactions to ensure all the steps
1421 * happen or fail as one */
1422 status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1423 if (!NT_STATUS_IS_OK(status)) {
1427 sid_peek_rid(sid, rid);
1429 return NT_STATUS_OK;
1432 static NTSTATUS pdb_samba4_delete_alias(struct pdb_methods *m,
1433 const struct dom_sid *sid)
1435 const char *attrs[] = { NULL };
1436 struct pdb_samba4_state *state = talloc_get_type_abort(
1437 m->private_data, struct pdb_samba4_state);
1438 struct ldb_message *msg;
1441 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1442 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1444 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1445 if (!dn || !ldb_dn_validate(dn)) {
1446 talloc_free(tmp_ctx);
1447 return NT_STATUS_NO_MEMORY;
1450 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1451 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1452 return NT_STATUS_INTERNAL_ERROR;
1455 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1456 "(|(grouptype=%d)(grouptype=%d)))",
1457 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1458 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1459 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1460 talloc_free(tmp_ctx);
1461 ldb_transaction_cancel(state->ldb);
1462 return NT_STATUS_NO_SUCH_ALIAS;
1464 rc = ldb_delete(state->ldb, dn);
1465 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1466 talloc_free(tmp_ctx);
1467 ldb_transaction_cancel(state->ldb);
1468 return NT_STATUS_NO_SUCH_ALIAS;
1469 } else if (rc != LDB_SUCCESS) {
1470 DEBUG(10, ("ldb_delete failed %s\n",
1471 ldb_errstring(state->ldb)));
1472 ldb_transaction_cancel(state->ldb);
1473 return NT_STATUS_LDAP(rc);
1476 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1477 DEBUG(0, ("Failed to commit transaction in pdb_samba4_delete_alias(): %s\n",
1478 ldb_errstring(state->ldb)));
1479 return NT_STATUS_INTERNAL_ERROR;
1482 return NT_STATUS_OK;
1486 static NTSTATUS pdb_samba4_set_aliasinfo(struct pdb_methods *m,
1487 const struct dom_sid *sid,
1488 struct acct_info *info)
1490 struct pdb_samba4_state *state = talloc_get_type_abort(
1491 m->private_data, struct pdb_samba4_state);
1492 struct tldap_context *ld;
1493 const char *attrs[3] = { "objectSid", "description",
1495 struct ldb_message **msg;
1498 struct tldap_mod *mods;
1502 ld = pdb_samba4_ld(state);
1504 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1507 sidstr = sid_binstring(talloc_tos(), sid);
1508 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1510 rc = pdb_samba4_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1511 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1512 &msg, "(&(objectSid=%s)(objectclass=group)"
1513 "(|(grouptype=%d)(grouptype=%d)))",
1514 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1515 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1517 if (rc != LDB_SUCCESS) {
1518 DEBUG(10, ("ldap_search failed %s\n",
1519 ldb_errstring(state->ldb)));
1520 return NT_STATUS_LDAP(rc);
1522 switch talloc_array_length(msg) {
1524 return NT_STATUS_NO_SUCH_ALIAS;
1528 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1531 if (!tldap_entry_dn(msg[0], &dn)) {
1533 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1540 ok &= tldap_make_mod_fmt(
1541 msg[0], msg, &num_mods, &mods, "description",
1542 "%s", info->acct_desc);
1543 ok &= tldap_make_mod_fmt(
1544 msg[0], msg, &num_mods, &mods, "samAccountName",
1545 "%s", info->acct_name);
1548 return NT_STATUS_NO_MEMORY;
1550 if (num_mods == 0) {
1553 return NT_STATUS_OK;
1556 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1558 if (rc != LDB_SUCCESS) {
1559 DEBUG(10, ("ldap_modify failed: %s\n",
1560 ldb_errstring(state->ldb)));
1561 return NT_STATUS_LDAP(rc);
1563 return NT_STATUS_OK;
1566 static NTSTATUS pdb_samba4_add_aliasmem(struct pdb_methods *m,
1567 const struct dom_sid *alias,
1568 const struct dom_sid *member)
1571 TALLOC_CTX *frame = talloc_stackframe();
1572 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1577 static NTSTATUS pdb_samba4_del_aliasmem(struct pdb_methods *m,
1578 const struct dom_sid *alias,
1579 const struct dom_sid *member)
1582 TALLOC_CTX *frame = talloc_stackframe();
1583 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1588 static NTSTATUS pdb_samba4_enum_aliasmem(struct pdb_methods *m,
1589 const struct dom_sid *alias,
1590 TALLOC_CTX *mem_ctx,
1591 struct dom_sid **pmembers,
1592 size_t *pnum_members)
1594 struct pdb_samba4_state *state = talloc_get_type_abort(
1595 m->private_data, struct pdb_samba4_state);
1597 unsigned int num_members;
1599 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1600 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1602 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1603 if (!dn || !ldb_dn_validate(dn)) {
1604 return NT_STATUS_NO_MEMORY;
1607 status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1608 *pnum_members = num_members;
1609 if (NT_STATUS_IS_OK(status)) {
1610 talloc_steal(mem_ctx, pmembers);
1612 talloc_free(tmp_ctx);
1616 static NTSTATUS pdb_samba4_enum_alias_memberships(struct pdb_methods *m,
1617 TALLOC_CTX *mem_ctx,
1618 const struct dom_sid *domain_sid,
1619 const struct dom_sid *members,
1621 uint32_t **palias_rids,
1622 size_t *pnum_alias_rids)
1624 struct pdb_samba4_state *state = talloc_get_type_abort(
1625 m->private_data, struct pdb_samba4_state);
1626 uint32_t *alias_rids = NULL;
1627 size_t num_alias_rids = 0;
1629 struct dom_sid *groupSIDs = NULL;
1630 unsigned int num_groupSIDs = 0;
1633 const char *sid_string;
1637 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1638 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1640 * TODO: Get the filter right so that we only get the aliases from
1641 * either the SAM or BUILTIN
1644 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1645 GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1646 if (filter == NULL) {
1647 return NT_STATUS_NO_MEMORY;
1650 for (i = 0; i < num_members; i++) {
1651 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1652 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, tmp_ctx);
1654 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1655 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, tmp_ctx);
1657 sid_blob = data_blob_string_const(sid_dn);
1659 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1660 tmp_ctx, &groupSIDs, &num_groupSIDs);
1661 if (!NT_STATUS_IS_OK(status)) {
1662 talloc_free(tmp_ctx);
1667 alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1668 if (alias_rids == NULL) {
1669 talloc_free(tmp_ctx);
1670 return NT_STATUS_NO_MEMORY;
1673 for (i=0; i<num_groupSIDs; i++) {
1674 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1675 &alias_rids[num_alias_rids])) {
1680 *palias_rids = alias_rids;
1681 *pnum_alias_rids = num_alias_rids;
1682 return NT_STATUS_OK;
1685 static NTSTATUS pdb_samba4_lookup_rids(struct pdb_methods *m,
1686 const struct dom_sid *domain_sid,
1690 enum lsa_SidType *lsa_attrs)
1692 struct pdb_samba4_state *state = talloc_get_type_abort(
1693 m->private_data, struct pdb_samba4_state);
1696 TALLOC_CTX *tmp_ctx;
1698 if (num_rids == 0) {
1699 return NT_STATUS_NONE_MAPPED;
1702 tmp_ctx = talloc_stackframe();
1703 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1705 status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1706 talloc_free(tmp_ctx);
1710 static NTSTATUS pdb_samba4_lookup_names(struct pdb_methods *m,
1711 const struct dom_sid *domain_sid,
1713 const char **pp_names,
1715 enum lsa_SidType *attrs)
1717 return NT_STATUS_NOT_IMPLEMENTED;
1720 static NTSTATUS pdb_samba4_get_account_policy(struct pdb_methods *m,
1721 enum pdb_policy_type type,
1724 return account_policy_get(type, value)
1725 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1728 static NTSTATUS pdb_samba4_set_account_policy(struct pdb_methods *m,
1729 enum pdb_policy_type type,
1732 return account_policy_set(type, value)
1733 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1736 static NTSTATUS pdb_samba4_get_seq_num(struct pdb_methods *m,
1737 time_t *seq_num_out)
1739 struct pdb_samba4_state *state = talloc_get_type_abort(
1740 m->private_data, struct pdb_samba4_state);
1742 int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1743 if (ret == LDB_SUCCESS) {
1744 *seq_num_out = seq_num;
1745 return NT_STATUS_OK;
1747 return NT_STATUS_UNSUCCESSFUL;
1751 struct pdb_samba4_search_state {
1752 uint32_t acct_flags;
1753 struct samr_displayentry *entries;
1754 uint32_t num_entries;
1759 static bool pdb_samba4_next_entry(struct pdb_search *search,
1760 struct samr_displayentry *entry)
1762 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1763 search->private_data, struct pdb_samba4_search_state);
1765 if (state->current == state->num_entries) {
1769 entry->idx = state->entries[state->current].idx;
1770 entry->rid = state->entries[state->current].rid;
1771 entry->acct_flags = state->entries[state->current].acct_flags;
1773 entry->account_name = talloc_strdup(
1774 search, state->entries[state->current].account_name);
1775 entry->fullname = talloc_strdup(
1776 search, state->entries[state->current].fullname);
1777 entry->description = talloc_strdup(
1778 search, state->entries[state->current].description);
1780 state->current += 1;
1784 static void pdb_samba4_search_end(struct pdb_search *search)
1786 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1787 search->private_data, struct pdb_samba4_search_state);
1791 static bool pdb_samba4_search_filter(struct pdb_methods *m,
1792 struct pdb_search *search,
1793 struct pdb_samba4_search_state **pstate,
1794 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1796 struct pdb_samba4_state *state = talloc_get_type_abort(
1797 m->private_data, struct pdb_samba4_state);
1798 struct pdb_samba4_search_state *sstate;
1799 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1800 "userAccountControl", "description", NULL };
1801 struct ldb_result *res;
1802 int i, rc, num_users;
1805 char *expression = NULL;
1807 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1812 va_start(ap, exp_fmt);
1813 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1817 talloc_free(tmp_ctx);
1818 return LDB_ERR_OPERATIONS_ERROR;
1821 sstate = talloc_zero(tmp_ctx, struct pdb_samba4_search_state);
1822 if (sstate == NULL) {
1823 talloc_free(tmp_ctx);
1827 rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1828 if (rc != LDB_SUCCESS) {
1829 talloc_free(tmp_ctx);
1830 DEBUG(10, ("dsdb_search failed: %s\n",
1831 ldb_errstring(state->ldb)));
1835 num_users = res->count;
1837 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1839 if (sstate->entries == NULL) {
1840 talloc_free(tmp_ctx);
1841 DEBUG(10, ("talloc failed\n"));
1845 sstate->num_entries = 0;
1847 for (i=0; i<num_users; i++) {
1848 struct samr_displayentry *e;
1849 struct dom_sid *sid;
1851 e = &sstate->entries[sstate->num_entries];
1853 e->idx = sstate->num_entries;
1854 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1856 talloc_free(tmp_ctx);
1857 DEBUG(10, ("Could not pull SID\n"));
1860 sid_peek_rid(sid, &e->rid);
1862 e->acct_flags = samdb_result_acct_flags(state->ldb, tmp_ctx,
1864 ldb_get_default_basedn(state->ldb));
1865 e->account_name = ldb_msg_find_attr_as_string(
1866 res->msgs[i], "samAccountName", NULL);
1867 if (e->account_name == NULL) {
1868 talloc_free(tmp_ctx);
1871 e->fullname = ldb_msg_find_attr_as_string(
1872 res->msgs[i], "displayName", "");
1873 e->description = ldb_msg_find_attr_as_string(
1874 res->msgs[i], "description", "");
1876 sstate->num_entries += 1;
1877 if (sstate->num_entries >= num_users) {
1881 talloc_steal(sstate->entries, res->msgs);
1882 search->private_data = talloc_steal(search, sstate);
1883 search->next_entry = pdb_samba4_next_entry;
1884 search->search_end = pdb_samba4_search_end;
1886 talloc_free(tmp_ctx);
1890 static bool pdb_samba4_search_users(struct pdb_methods *m,
1891 struct pdb_search *search,
1894 struct pdb_samba4_search_state *sstate;
1897 ret = pdb_samba4_search_filter(m, search, &sstate, "(objectclass=user)");
1901 sstate->acct_flags = acct_flags;
1905 static bool pdb_samba4_search_groups(struct pdb_methods *m,
1906 struct pdb_search *search)
1908 struct pdb_samba4_search_state *sstate;
1911 ret = pdb_samba4_search_filter(m, search, &sstate,
1912 "(&(grouptype=%d)(objectclass=group))",
1913 GTYPE_SECURITY_GLOBAL_GROUP);
1917 sstate->acct_flags = 0;
1921 static bool pdb_samba4_search_aliases(struct pdb_methods *m,
1922 struct pdb_search *search,
1923 const struct dom_sid *sid)
1925 struct pdb_samba4_search_state *sstate;
1928 ret = pdb_samba4_search_filter(m, search, &sstate,
1929 "(&(grouptype=%d)(objectclass=group))",
1930 sid_check_is_builtin(sid)
1931 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1932 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1936 sstate->acct_flags = 0;
1940 static bool pdb_samba4_uid_to_sid(struct pdb_methods *m, uid_t uid,
1941 struct dom_sid *sid)
1943 struct pdb_samba4_state *state = talloc_get_type_abort(
1944 m->private_data, struct pdb_samba4_state);
1946 struct id_map id_map;
1947 struct id_map *id_maps[2];
1948 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1953 id_map.xid.id = uid;
1954 id_map.xid.type = ID_TYPE_UID;
1955 id_maps[0] = &id_map;
1958 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1959 if (!NT_STATUS_IS_OK(status)) {
1960 talloc_free(tmp_ctx);
1964 talloc_free(tmp_ctx);
1968 static bool pdb_samba4_gid_to_sid(struct pdb_methods *m, gid_t gid,
1969 struct dom_sid *sid)
1971 struct pdb_samba4_state *state = talloc_get_type_abort(
1972 m->private_data, struct pdb_samba4_state);
1974 struct id_map id_map;
1975 struct id_map *id_maps[2];
1976 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1981 id_map.xid.id = gid;
1982 id_map.xid.type = ID_TYPE_GID;
1983 id_maps[0] = &id_map;
1986 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1987 if (!NT_STATUS_IS_OK(status)) {
1991 talloc_free(tmp_ctx);
1995 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
1996 union unid_t *id, enum lsa_SidType *type)
1998 struct pdb_samba4_state *state = talloc_get_type_abort(
1999 m->private_data, struct pdb_samba4_state);
2000 struct id_map id_map;
2001 struct id_map *id_maps[2];
2002 const char *attrs[] = { "objectClass", "groupType", NULL };
2003 struct ldb_message *msg;
2007 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2012 ZERO_STRUCT(id_map);
2014 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
2015 if (!dn || !ldb_dn_validate(dn)) {
2016 talloc_free(tmp_ctx);
2019 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, NULL);
2020 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
2021 DEBUG(5, (__location__ "SID to Unix ID lookup failed because SID %s could not be found in the samdb\n", dom_sid_string(tmp_ctx, sid)));
2022 talloc_free(tmp_ctx);
2025 if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
2026 uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
2027 switch (grouptype) {
2028 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
2029 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
2030 *type = SID_NAME_ALIAS;
2032 case GTYPE_SECURITY_GLOBAL_GROUP:
2033 *type = SID_NAME_DOM_GRP;
2036 talloc_free(tmp_ctx);
2037 DEBUG(10, ("Could not pull groupType\n"));
2041 *type = SID_NAME_DOM_GRP;
2043 ZERO_STRUCT(id_map);
2045 id_maps[0] = &id_map;
2048 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2049 talloc_free(tmp_ctx);
2050 if (!NT_STATUS_IS_OK(status)) {
2053 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
2054 id->gid = id_map.xid.id;
2058 } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
2059 *type = SID_NAME_USER;
2060 ZERO_STRUCT(id_map);
2062 id_maps[0] = &id_map;
2065 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2066 talloc_free(tmp_ctx);
2067 if (!NT_STATUS_IS_OK(status)) {
2070 if (id_map.xid.type == ID_TYPE_UID || id_map.xid.type == ID_TYPE_BOTH) {
2071 id->uid = id_map.xid.id;
2076 DEBUG(5, (__location__ "SID to Unix ID lookup failed because SID %s was found, but was not a user or group\n", dom_sid_string(tmp_ctx, sid)));
2077 talloc_free(tmp_ctx);
2081 static uint32_t pdb_samba4_capabilities(struct pdb_methods *m)
2083 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2086 static bool pdb_samba4_new_rid(struct pdb_methods *m, uint32 *rid)
2091 static bool pdb_samba4_get_trusteddom_pw(struct pdb_methods *m,
2092 const char *domain, char** pwd,
2093 struct dom_sid *sid,
2094 time_t *pass_last_set_time)
2099 static bool pdb_samba4_set_trusteddom_pw(struct pdb_methods *m,
2100 const char* domain, const char* pwd,
2101 const struct dom_sid *sid)
2106 static bool pdb_samba4_del_trusteddom_pw(struct pdb_methods *m,
2112 static NTSTATUS pdb_samba4_enum_trusteddoms(struct pdb_methods *m,
2113 TALLOC_CTX *mem_ctx,
2114 uint32 *num_domains,
2115 struct trustdom_info ***domains)
2119 return NT_STATUS_OK;
2122 static void pdb_samba4_init_methods(struct pdb_methods *m)
2125 m->get_domain_info = pdb_samba4_get_domain_info;
2126 m->getsampwnam = pdb_samba4_getsampwnam;
2127 m->getsampwsid = pdb_samba4_getsampwsid;
2128 m->create_user = pdb_samba4_create_user;
2129 m->delete_user = pdb_samba4_delete_user;
2130 m->add_sam_account = pdb_samba4_add_sam_account;
2131 m->update_sam_account = pdb_samba4_update_sam_account;
2132 m->delete_sam_account = pdb_samba4_delete_sam_account;
2133 m->rename_sam_account = pdb_samba4_rename_sam_account;
2134 m->update_login_attempts = pdb_samba4_update_login_attempts;
2135 m->getgrsid = pdb_samba4_getgrsid;
2136 m->getgrgid = pdb_samba4_getgrgid;
2137 m->getgrnam = pdb_samba4_getgrnam;
2138 m->create_dom_group = pdb_samba4_create_dom_group;
2139 m->delete_dom_group = pdb_samba4_delete_dom_group;
2140 m->add_group_mapping_entry = pdb_samba4_add_group_mapping_entry;
2141 m->update_group_mapping_entry = pdb_samba4_update_group_mapping_entry;
2142 m->delete_group_mapping_entry = pdb_samba4_delete_group_mapping_entry;
2143 m->enum_group_mapping = pdb_samba4_enum_group_mapping;
2144 m->enum_group_members = pdb_samba4_enum_group_members;
2145 m->enum_group_memberships = pdb_samba4_enum_group_memberships;
2146 m->set_unix_primary_group = pdb_samba4_set_unix_primary_group;
2147 m->add_groupmem = pdb_samba4_add_groupmem;
2148 m->del_groupmem = pdb_samba4_del_groupmem;
2149 m->create_alias = pdb_samba4_create_alias;
2150 m->delete_alias = pdb_samba4_delete_alias;
2151 m->get_aliasinfo = pdb_default_get_aliasinfo;
2152 m->add_aliasmem = pdb_samba4_add_aliasmem;
2153 m->del_aliasmem = pdb_samba4_del_aliasmem;
2154 m->enum_aliasmem = pdb_samba4_enum_aliasmem;
2155 m->enum_alias_memberships = pdb_samba4_enum_alias_memberships;
2156 m->lookup_rids = pdb_samba4_lookup_rids;
2157 m->lookup_names = pdb_samba4_lookup_names;
2158 m->get_account_policy = pdb_samba4_get_account_policy;
2159 m->set_account_policy = pdb_samba4_set_account_policy;
2160 m->get_seq_num = pdb_samba4_get_seq_num;
2161 m->search_users = pdb_samba4_search_users;
2162 m->search_groups = pdb_samba4_search_groups;
2163 m->search_aliases = pdb_samba4_search_aliases;
2164 m->uid_to_sid = pdb_samba4_uid_to_sid;
2165 m->gid_to_sid = pdb_samba4_gid_to_sid;
2166 m->sid_to_id = pdb_samba4_sid_to_id;
2167 m->capabilities = pdb_samba4_capabilities;
2168 m->new_rid = pdb_samba4_new_rid;
2169 m->get_trusteddom_pw = pdb_samba4_get_trusteddom_pw;
2170 m->set_trusteddom_pw = pdb_samba4_set_trusteddom_pw;
2171 m->del_trusteddom_pw = pdb_samba4_del_trusteddom_pw;
2172 m->enum_trusteddoms = pdb_samba4_enum_trusteddoms;
2175 static void free_private_data(void **vp)
2177 struct pdb_samba4_state *state = talloc_get_type_abort(
2178 *vp, struct pdb_samba4_state);
2179 talloc_unlink(state, state->ldb);
2183 static NTSTATUS pdb_init_samba4(struct pdb_methods **pdb_method,
2184 const char *location)
2186 struct pdb_methods *m;
2187 struct pdb_samba4_state *state;
2190 if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2194 state = talloc_zero(m, struct pdb_samba4_state);
2195 if (state == NULL) {
2198 m->private_data = state;
2199 m->free_private_data = free_private_data;
2200 pdb_samba4_init_methods(m);
2202 state->ev = s4_event_context_init(state);
2204 DEBUG(0, ("s4_event_context_init failed\n"));
2208 state->lp_ctx = loadparm_init_s3(state, loadparm_s3_context());
2209 if (state->lp_ctx == NULL) {
2210 DEBUG(0, ("loadparm_init_s3 failed\n"));
2215 state->ldb = samdb_connect_url(state,
2218 system_session(state->lp_ctx),
2221 state->ldb = samdb_connect(state,
2224 system_session(state->lp_ctx), 0);
2228 DEBUG(0, ("samdb_connect failed\n"));
2229 status = NT_STATUS_INTERNAL_ERROR;
2233 state->idmap_ctx = idmap_init(state, state->ev,
2235 if (!state->idmap_ctx) {
2236 DEBUG(0, ("idmap failed\n"));
2237 status = NT_STATUS_INTERNAL_ERROR;
2242 return NT_STATUS_OK;
2244 status = NT_STATUS_NO_MEMORY;
2250 NTSTATUS pdb_samba4_init(void);
2251 NTSTATUS pdb_samba4_init(void)
2253 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",