2 Unix SMB/CIFS implementation.
3 pdb_ldap with ads schema
4 Copyright (C) Volker Lendecke 2009
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
23 struct samu *sam_acct,
25 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
29 struct pdb_ads_state {
30 struct tldap_context *ld;
31 struct dom_sid domainsid;
37 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
42 if (!tldap_pull_uint64(msg, attr, &tmp)) {
45 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
49 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
52 sid_peek_rid(sid, &rid);
56 struct pdb_ads_samu_private {
58 struct tldap_message *ldapmsg;
61 static struct samu *pdb_ads_init_guest(TALLOC_CTX *mem_ctx,
62 struct pdb_methods *m)
64 struct pdb_ads_state *state = talloc_get_type_abort(
65 m->private_data, struct pdb_ads_state);
66 struct dom_sid guest_sid;
70 sid_compose(&guest_sid, &state->domainsid, DOMAIN_USER_RID_GUEST);
72 guest = samu_new(mem_ctx);
77 status = pdb_ads_getsampwsid(m, guest, &guest_sid);
78 if (!NT_STATUS_IS_OK(status)) {
79 DEBUG(10, ("Could not init guest account: %s\n",
87 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
88 struct pdb_methods *m, struct samu *sam)
90 struct pdb_ads_samu_private *result;
93 result = (struct pdb_ads_samu_private *)
94 pdb_get_backend_private_data(sam, m);
97 return talloc_get_type_abort(
98 result, struct pdb_ads_samu_private);
102 * This is now a weirdness of the passdb API. For the guest user we
103 * are not asked first.
105 sid_peek_rid(pdb_get_user_sid(sam), &rid);
107 if (rid == DOMAIN_USER_RID_GUEST) {
108 struct samu *guest = pdb_ads_init_guest(talloc_tos(), m);
113 result = talloc_get_type_abort(
114 pdb_get_backend_private_data(guest, m),
115 struct pdb_ads_samu_private);
116 pdb_set_backend_private_data(
117 sam, talloc_move(sam, &result), NULL, m, PDB_SET);
119 return talloc_get_type_abort(
120 pdb_get_backend_private_data(sam, m),
121 struct pdb_ads_samu_private);
127 static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m,
129 struct tldap_message *entry)
131 struct pdb_ads_state *state = talloc_get_type_abort(
132 m->private_data, struct pdb_ads_state);
133 TALLOC_CTX *frame = talloc_stackframe();
134 struct pdb_ads_samu_private *priv;
135 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
142 priv = talloc(sam, struct pdb_ads_samu_private);
144 return NT_STATUS_NO_MEMORY;
146 if (!tldap_entry_dn(entry, &priv->dn)) {
148 return NT_STATUS_INTERNAL_DB_CORRUPTION;
151 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
153 DEBUG(10, ("no samAccountName\n"));
156 pdb_set_username(sam, str, PDB_SET);
159 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
160 pdb_set_logon_time(sam, tmp_time, PDB_SET);
162 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
163 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
165 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
166 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
168 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
169 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
172 str = tldap_talloc_single_attribute(entry, "samAccoutName",
175 pdb_set_username(sam, str, PDB_SET);
178 str = tldap_talloc_single_attribute(entry, "displayName",
181 pdb_set_fullname(sam, str, PDB_SET);
184 str = tldap_talloc_single_attribute(entry, "homeDirectory",
187 pdb_set_homedir(sam, str, PDB_SET);
190 str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
192 pdb_set_dir_drive(sam, str, PDB_SET);
195 str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
197 pdb_set_logon_script(sam, str, PDB_SET);
200 str = tldap_talloc_single_attribute(entry, "profilePath",
203 pdb_set_profile_path(sam, str, PDB_SET);
206 str = tldap_talloc_single_attribute(entry, "profilePath",
209 pdb_set_profile_path(sam, str, PDB_SET);
212 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
213 DEBUG(10, ("Could not pull SID\n"));
216 pdb_set_user_sid(sam, &sid, PDB_SET);
218 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
219 DEBUG(10, ("Could not pull userAccountControl\n"));
222 pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET);
224 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
225 if (blob.length != NT_HASH_LEN) {
226 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
227 (int)blob.length, NT_HASH_LEN));
230 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
233 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
234 if (blob.length != LM_HASH_LEN) {
235 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
236 (int)blob.length, LM_HASH_LEN));
239 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
242 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
243 sid_compose(&sid, &state->domainsid, n);
244 pdb_set_group_sid(sam, &sid, PDB_SET);
248 priv->ldapmsg = talloc_move(priv, &entry);
249 pdb_set_backend_private_data(sam, priv, NULL, m, PDB_SET);
251 status = NT_STATUS_OK;
257 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
258 struct tldap_message *existing,
260 int *pnum_mods, struct tldap_mod **pmods,
265 /* TODO: All fields :-) */
267 ret &= tldap_make_mod_fmt(
268 existing, mem_ctx, pnum_mods, pmods, "displayName",
269 "%s", pdb_get_fullname(sam));
271 ret &= tldap_make_mod_blob(
272 existing, mem_ctx, pnum_mods, pmods, "unicodePwd",
273 data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN));
275 ret &= tldap_make_mod_blob(
276 existing, mem_ctx, pnum_mods, pmods, "dBCSPwd",
277 data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN));
282 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
283 struct pdb_ads_state *state,
284 struct samu *sam_acct,
287 const char * attrs[] = {
288 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
289 "sAMAccountName", "displayName", "homeDirectory",
290 "homeDrive", "scriptPath", "profilePath", "description",
291 "userWorkstations", "comment", "userParameters", "objectSid",
292 "primaryGroupID", "userAccountControl", "logonHours",
293 "badPwdCount", "logonCount", "countryCode", "codePage",
294 "unicodePwd", "dBCSPwd" };
295 struct tldap_message **users;
298 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
299 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
300 &users, "%s", filter);
301 if (rc != TLDAP_SUCCESS) {
302 DEBUG(10, ("ldap_search failed %s\n",
303 tldap_errstr(debug_ctx(), state->ld, rc)));
304 return NT_STATUS_LDAP(rc);
307 count = talloc_array_length(users);
309 DEBUG(10, ("Expected 1 user, got %d\n", count));
310 return NT_STATUS_INTERNAL_DB_CORRUPTION;
313 return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]);
316 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
317 struct samu *sam_acct,
318 const char *username)
320 struct pdb_ads_state *state = talloc_get_type_abort(
321 m->private_data, struct pdb_ads_state);
324 filter = talloc_asprintf(
325 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
327 NT_STATUS_HAVE_NO_MEMORY(filter);
329 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
332 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
333 struct samu *sam_acct,
336 struct pdb_ads_state *state = talloc_get_type_abort(
337 m->private_data, struct pdb_ads_state);
338 char *sidstr, *filter;
340 sidstr = sid_binstring(talloc_tos(), sid);
341 NT_STATUS_HAVE_NO_MEMORY(sidstr);
343 filter = talloc_asprintf(
344 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
346 NT_STATUS_HAVE_NO_MEMORY(filter);
348 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
351 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
353 const char *name, uint32 acct_flags,
356 struct pdb_ads_state *state = talloc_get_type_abort(
357 m->private_data, struct pdb_ads_state);
358 const char *attrs[1] = { "objectSid" };
359 struct tldap_mod *mods = NULL;
361 struct tldap_message **user;
367 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
370 return NT_STATUS_NO_MEMORY;
373 /* TODO: Create machines etc */
376 ok &= tldap_make_mod_fmt(
377 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
378 ok &= tldap_make_mod_fmt(
379 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
382 return NT_STATUS_NO_MEMORY;
385 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
386 if (rc != TLDAP_SUCCESS) {
387 DEBUG(10, ("ldap_add failed %s\n",
388 tldap_errstr(debug_ctx(), state->ld, rc)));
390 return NT_STATUS_LDAP(rc);
393 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
394 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &user,
395 "(&(objectclass=user)(samaccountname=%s))",
397 if (rc != TLDAP_SUCCESS) {
398 DEBUG(10, ("Could not find just created user %s: %s\n",
399 name, tldap_errstr(debug_ctx(), state->ld, rc)));
401 return NT_STATUS_LDAP(rc);
404 if (talloc_array_length(user) != 1) {
405 DEBUG(10, ("Got %d users, expected one\n",
406 (int)talloc_array_length(user)));
408 return NT_STATUS_LDAP(rc);
411 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
412 DEBUG(10, ("Could not fetch objectSid from user %s\n",
415 return NT_STATUS_INTERNAL_DB_CORRUPTION;
418 sid_peek_rid(&sid, rid);
423 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
427 struct pdb_ads_state *state = talloc_get_type_abort(
428 m->private_data, struct pdb_ads_state);
429 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
432 rc = tldap_delete(state->ld, priv->dn, NULL, NULL);
433 if (rc != TLDAP_SUCCESS) {
434 DEBUG(10, ("ldap_delete for %s failed: %s\n", priv->dn,
435 tldap_errstr(debug_ctx(), state->ld, rc)));
436 return NT_STATUS_LDAP(rc);
441 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
442 struct samu *sampass)
444 return NT_STATUS_NOT_IMPLEMENTED;
447 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
450 struct pdb_ads_state *state = talloc_get_type_abort(
451 m->private_data, struct pdb_ads_state);
452 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
453 struct tldap_mod *mods = NULL;
454 int rc, num_mods = 0;
456 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
457 &num_mods, &mods, sam)) {
458 return NT_STATUS_NO_MEMORY;
461 rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, NULL);
462 if (rc != TLDAP_SUCCESS) {
463 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
464 tldap_errstr(debug_ctx(), state->ld, rc)));
465 return NT_STATUS_LDAP(rc);
473 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
474 struct samu *username)
476 return NT_STATUS_NOT_IMPLEMENTED;
479 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
480 struct samu *oldname,
483 return NT_STATUS_NOT_IMPLEMENTED;
486 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
487 struct samu *sam_acct,
490 return NT_STATUS_NOT_IMPLEMENTED;
493 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
496 struct pdb_ads_state *state = talloc_get_type_abort(
497 m->private_data, struct pdb_ads_state);
498 const char *attrs[4] = { "objectSid", "description", "samAccountName",
501 struct tldap_message **group;
505 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
506 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
507 &group, "%s", filter);
508 if (rc != TLDAP_SUCCESS) {
509 DEBUG(10, ("ldap_search failed %s\n",
510 tldap_errstr(debug_ctx(), state->ld, rc)));
511 return NT_STATUS_LDAP(rc);
513 if (talloc_array_length(group) != 1) {
514 DEBUG(10, ("Expected 1 user, got %d\n",
515 (int)talloc_array_length(group)));
516 return NT_STATUS_INTERNAL_DB_CORRUPTION;
519 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
520 return NT_STATUS_INTERNAL_DB_CORRUPTION;
522 map->gid = pdb_ads_sid2gid(&map->sid);
524 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
525 return NT_STATUS_INTERNAL_DB_CORRUPTION;
528 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
529 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
530 map->sid_name_use = SID_NAME_ALIAS;
532 case GTYPE_SECURITY_GLOBAL_GROUP:
533 map->sid_name_use = SID_NAME_DOM_GRP;
536 return NT_STATUS_INTERNAL_DB_CORRUPTION;
539 str = tldap_talloc_single_attribute(group[0], "samAccountName",
542 return NT_STATUS_INTERNAL_DB_CORRUPTION;
544 fstrcpy(map->nt_name, str);
547 str = tldap_talloc_single_attribute(group[0], "description",
550 fstrcpy(map->comment, str);
553 map->comment[0] = '\0';
560 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
566 filter = talloc_asprintf(talloc_tos(),
567 "(&(objectsid=%s)(objectclass=group))",
568 sid_string_talloc(talloc_tos(), &sid));
569 if (filter == NULL) {
570 return NT_STATUS_NO_MEMORY;
573 status = pdb_ads_getgrfilter(m, map, filter);
578 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
582 pdb_ads_gid_to_sid(m, gid, &sid);
583 return pdb_ads_getgrsid(m, map, sid);
586 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
592 filter = talloc_asprintf(talloc_tos(),
593 "(&(samaccountname=%s)(objectclass=group))",
595 if (filter == NULL) {
596 return NT_STATUS_NO_MEMORY;
599 status = pdb_ads_getgrfilter(m, map, filter);
604 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
605 TALLOC_CTX *mem_ctx, const char *name,
608 TALLOC_CTX *frame = talloc_stackframe();
609 struct pdb_ads_state *state = talloc_get_type_abort(
610 m->private_data, struct pdb_ads_state);
611 const char *attrs[1] = { "objectSid" };
613 struct tldap_mod *mods = NULL;
614 struct tldap_message **alias;
620 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
624 return NT_STATUS_NO_MEMORY;
627 ok &= tldap_make_mod_fmt(
628 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
630 ok &= tldap_make_mod_fmt(
631 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
632 ok &= tldap_make_mod_fmt(
633 NULL, talloc_tos(), &num_mods, &mods, "groupType",
634 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
638 return NT_STATUS_NO_MEMORY;
641 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
642 if (rc != TLDAP_SUCCESS) {
643 DEBUG(10, ("ldap_add failed %s\n",
644 tldap_errstr(debug_ctx(), state->ld, rc)));
646 return NT_STATUS_LDAP(rc);
649 rc = tldap_search_fmt(
650 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
651 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
652 "(&(objectclass=group)(samaccountname=%s))", name);
653 if (rc != TLDAP_SUCCESS) {
654 DEBUG(10, ("Could not find just created alias %s: %s\n",
655 name, tldap_errstr(debug_ctx(), state->ld, rc)));
657 return NT_STATUS_LDAP(rc);
660 if (talloc_array_length(alias) != 1) {
661 DEBUG(10, ("Got %d alias, expected one\n",
662 (int)talloc_array_length(alias)));
664 return NT_STATUS_LDAP(rc);
667 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
668 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
671 return NT_STATUS_INTERNAL_DB_CORRUPTION;
674 sid_peek_rid(&sid, rid);
679 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
680 TALLOC_CTX *mem_ctx, uint32 rid)
682 return NT_STATUS_NOT_IMPLEMENTED;
685 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
688 return NT_STATUS_NOT_IMPLEMENTED;
691 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
694 return NT_STATUS_NOT_IMPLEMENTED;
697 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
700 return NT_STATUS_NOT_IMPLEMENTED;
703 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
705 enum lsa_SidType sid_name_use,
707 size_t *p_num_entries,
710 return NT_STATUS_NOT_IMPLEMENTED;
713 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
715 const DOM_SID *group,
716 uint32 **pp_member_rids,
717 size_t *p_num_members)
719 return NT_STATUS_NOT_IMPLEMENTED;
722 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
727 size_t *p_num_groups)
729 struct pdb_ads_state *state = talloc_get_type_abort(
730 m->private_data, struct pdb_ads_state);
731 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
733 const char *attrs[1] = { "objectSid" };
734 struct tldap_message **groups;
737 struct dom_sid *group_sids;
740 rc = tldap_search_fmt(
741 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
742 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
743 "(&(member=%s)(grouptype=%d)(objectclass=group))",
744 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
745 if (rc != TLDAP_SUCCESS) {
746 DEBUG(10, ("ldap_search failed %s\n",
747 tldap_errstr(debug_ctx(), state->ld, rc)));
748 return NT_STATUS_LDAP(rc);
751 count = talloc_array_length(groups);
753 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
754 if (group_sids == NULL) {
755 return NT_STATUS_NO_MEMORY;
757 gids = talloc_array(mem_ctx, gid_t, count);
759 TALLOC_FREE(group_sids);
760 return NT_STATUS_NO_MEMORY;
764 for (i=0; i<count; i++) {
765 if (!tldap_pull_binsid(groups[i], "objectSid",
766 &group_sids[num_groups])) {
769 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
772 if (num_groups == count) {
777 *pp_sids = group_sids;
779 *p_num_groups = num_groups;
783 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
787 return NT_STATUS_NOT_IMPLEMENTED;
790 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
792 uint32 group_rid, uint32 member_rid)
794 return NT_STATUS_NOT_IMPLEMENTED;
797 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
799 uint32 group_rid, uint32 member_rid)
801 return NT_STATUS_NOT_IMPLEMENTED;
804 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
805 const char *name, uint32 *rid)
807 TALLOC_CTX *frame = talloc_stackframe();
808 struct pdb_ads_state *state = talloc_get_type_abort(
809 m->private_data, struct pdb_ads_state);
810 const char *attrs[1] = { "objectSid" };
812 struct tldap_mod *mods = NULL;
813 struct tldap_message **alias;
819 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
823 return NT_STATUS_NO_MEMORY;
826 ok &= tldap_make_mod_fmt(
827 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
829 ok &= tldap_make_mod_fmt(
830 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
831 ok &= tldap_make_mod_fmt(
832 NULL, talloc_tos(), &num_mods, &mods, "groupType",
833 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
837 return NT_STATUS_NO_MEMORY;
840 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
841 if (rc != TLDAP_SUCCESS) {
842 DEBUG(10, ("ldap_add failed %s\n",
843 tldap_errstr(debug_ctx(), state->ld, rc)));
845 return NT_STATUS_LDAP(rc);
848 rc = tldap_search_fmt(
849 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
850 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
851 "(&(objectclass=group)(samaccountname=%s))", name);
852 if (rc != TLDAP_SUCCESS) {
853 DEBUG(10, ("Could not find just created alias %s: %s\n",
854 name, tldap_errstr(debug_ctx(), state->ld, rc)));
856 return NT_STATUS_LDAP(rc);
859 if (talloc_array_length(alias) != 1) {
860 DEBUG(10, ("Got %d alias, expected one\n",
861 (int)talloc_array_length(alias)));
863 return NT_STATUS_LDAP(rc);
866 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
867 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
870 return NT_STATUS_INTERNAL_DB_CORRUPTION;
873 sid_peek_rid(&sid, rid);
878 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
881 struct pdb_ads_state *state = talloc_get_type_abort(
882 m->private_data, struct pdb_ads_state);
883 struct tldap_message **alias;
887 sidstr = sid_binstring(talloc_tos(), sid);
888 if (sidstr == NULL) {
889 return NT_STATUS_NO_MEMORY;
892 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
893 NULL, 0, 0, talloc_tos(), &alias,
894 "(&(objectSid=%s)(objectclass=group)"
895 "(|(grouptype=%d)(grouptype=%d)))",
896 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
897 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
899 if (rc != TLDAP_SUCCESS) {
900 DEBUG(10, ("ldap_search failed: %s\n",
901 tldap_errstr(debug_ctx(), state->ld, rc)));
903 return NT_STATUS_LDAP(rc);
905 if (talloc_array_length(alias) != 1) {
906 DEBUG(10, ("Expected 1 alias, got %d\n",
907 (int)talloc_array_length(alias)));
908 return NT_STATUS_INTERNAL_DB_CORRUPTION;
910 if (!tldap_entry_dn(alias[0], &dn)) {
911 DEBUG(10, ("Could not get DN for alias %s\n",
912 sid_string_dbg(sid)));
913 return NT_STATUS_INTERNAL_ERROR;
916 rc = tldap_delete(state->ld, dn, NULL, NULL);
917 if (rc != TLDAP_SUCCESS) {
918 DEBUG(10, ("ldap_delete failed: %s\n",
919 tldap_errstr(debug_ctx(), state->ld, rc)));
921 return NT_STATUS_LDAP(rc);
927 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
929 struct acct_info *info)
931 return NT_STATUS_NOT_IMPLEMENTED;
934 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
936 struct acct_info *info)
938 return NT_STATUS_NOT_IMPLEMENTED;
941 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
942 const struct dom_sid *sid,
943 TALLOC_CTX *mem_ctx, char **pdn)
945 struct tldap_message **msg;
949 sidstr = sid_binstring(talloc_tos(), sid);
950 NT_STATUS_HAVE_NO_MEMORY(sidstr);
952 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
953 NULL, 0, 0, talloc_tos(), &msg,
954 "(objectsid=%s)", sidstr);
956 if (rc != TLDAP_SUCCESS) {
957 DEBUG(10, ("ldap_search failed %s\n",
958 tldap_errstr(debug_ctx(), state->ld, rc)));
959 return NT_STATUS_LDAP(rc);
962 switch talloc_array_length(msg) {
964 return NT_STATUS_NOT_FOUND;
968 return NT_STATUS_INTERNAL_DB_CORRUPTION;
971 if (!tldap_entry_dn(msg[0], &dn)) {
972 return NT_STATUS_INTERNAL_DB_CORRUPTION;
975 dn = talloc_strdup(mem_ctx, dn);
977 return NT_STATUS_NO_MEMORY;
985 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
986 const DOM_SID *alias,
987 const DOM_SID *member,
990 struct pdb_ads_state *state = talloc_get_type_abort(
991 m->private_data, struct pdb_ads_state);
992 TALLOC_CTX *frame = talloc_stackframe();
993 struct tldap_mod *mods;
995 char *aliasdn, *memberdn;
998 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
999 if (!NT_STATUS_IS_OK(status)) {
1000 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1001 sid_string_dbg(alias), nt_errstr(status)));
1003 return NT_STATUS_NO_SUCH_ALIAS;
1005 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1006 if (!NT_STATUS_IS_OK(status)) {
1007 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1008 sid_string_dbg(member), nt_errstr(status)));
1015 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1016 "member", memberdn)) {
1018 return NT_STATUS_NO_MEMORY;
1021 rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
1023 if (rc != TLDAP_SUCCESS) {
1024 DEBUG(10, ("ldap_modify failed: %s\n",
1025 tldap_errstr(debug_ctx(), state->ld, rc)));
1026 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1027 return NT_STATUS_MEMBER_IN_ALIAS;
1029 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1030 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1032 return NT_STATUS_LDAP(rc);
1035 return NT_STATUS_OK;
1038 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1039 const DOM_SID *alias,
1040 const DOM_SID *member)
1042 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1045 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1046 const DOM_SID *alias,
1047 const DOM_SID *member)
1049 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1052 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1053 struct dom_sid *psid)
1055 const char *attrs[1] = { "objectSid" };
1056 struct tldap_message **msg;
1062 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1063 dnblob->data, dnblob->length, &dn, &len,
1067 rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1068 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1069 &msg, "(objectclass=*)");
1071 if (talloc_array_length(msg) != 1) {
1072 DEBUG(10, ("Got %d objects, expected one\n",
1073 (int)talloc_array_length(msg)));
1078 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1083 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1084 const DOM_SID *alias,
1085 TALLOC_CTX *mem_ctx,
1087 size_t *pnum_members)
1089 struct pdb_ads_state *state = talloc_get_type_abort(
1090 m->private_data, struct pdb_ads_state);
1091 const char *attrs[1] = { "member" };
1093 struct tldap_message **msg;
1094 int i, rc, num_members;
1096 struct dom_sid *members;
1098 sidstr = sid_binstring(talloc_tos(), alias);
1099 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1101 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1102 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1103 "(objectsid=%s)", sidstr);
1104 TALLOC_FREE(sidstr);
1105 if (rc != TLDAP_SUCCESS) {
1106 DEBUG(10, ("ldap_search failed %s\n",
1107 tldap_errstr(debug_ctx(), state->ld, rc)));
1108 return NT_STATUS_LDAP(rc);
1110 switch talloc_array_length(msg) {
1112 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1117 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1121 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1122 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1125 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1126 if (members == NULL) {
1127 return NT_STATUS_NO_MEMORY;
1130 for (i=0; i<num_members; i++) {
1131 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1132 TALLOC_FREE(members);
1133 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1137 *pmembers = members;
1138 *pnum_members = num_members;
1139 return NT_STATUS_OK;
1142 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1143 TALLOC_CTX *mem_ctx,
1144 const DOM_SID *domain_sid,
1145 const DOM_SID *members,
1147 uint32 **pp_alias_rids,
1148 size_t *p_num_alias_rids)
1150 return NT_STATUS_NOT_IMPLEMENTED;
1153 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1154 const DOM_SID *domain_sid,
1157 const char **pp_names,
1158 enum lsa_SidType *attrs)
1160 return NT_STATUS_NOT_IMPLEMENTED;
1163 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1164 const DOM_SID *domain_sid,
1166 const char **pp_names,
1168 enum lsa_SidType *attrs)
1170 return NT_STATUS_NOT_IMPLEMENTED;
1173 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1174 int policy_index, uint32 *value)
1176 return account_policy_get(policy_index, value)
1177 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1180 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1181 int policy_index, uint32 value)
1183 return account_policy_set(policy_index, value)
1184 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1187 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1190 return NT_STATUS_NOT_IMPLEMENTED;
1193 struct pdb_ads_search_state {
1194 uint32_t acct_flags;
1195 struct samr_displayentry *entries;
1196 uint32_t num_entries;
1201 static bool pdb_ads_next_entry(struct pdb_search *search,
1202 struct samr_displayentry *entry)
1204 struct pdb_ads_search_state *state = talloc_get_type_abort(
1205 search->private_data, struct pdb_ads_search_state);
1207 if (state->current == state->num_entries) {
1211 entry->idx = state->entries[state->current].idx;
1212 entry->rid = state->entries[state->current].rid;
1213 entry->acct_flags = state->entries[state->current].acct_flags;
1215 entry->account_name = talloc_strdup(
1216 search, state->entries[state->current].account_name);
1217 entry->fullname = talloc_strdup(
1218 search, state->entries[state->current].fullname);
1219 entry->description = talloc_strdup(
1220 search, state->entries[state->current].description);
1222 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1223 || (entry->description == NULL)) {
1224 DEBUG(0, ("talloc_strdup failed\n"));
1228 state->current += 1;
1232 static void pdb_ads_search_end(struct pdb_search *search)
1234 struct pdb_ads_search_state *state = talloc_get_type_abort(
1235 search->private_data, struct pdb_ads_search_state);
1239 static bool pdb_ads_search_filter(struct pdb_methods *m,
1240 struct pdb_search *search,
1242 struct pdb_ads_search_state **pstate)
1244 struct pdb_ads_state *state = talloc_get_type_abort(
1245 m->private_data, struct pdb_ads_state);
1246 struct pdb_ads_search_state *sstate;
1247 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1248 "userAccountControl", "description" };
1249 struct tldap_message **users;
1250 int i, rc, num_users;
1252 sstate = talloc_zero(search, struct pdb_ads_search_state);
1253 if (sstate == NULL) {
1257 rc = tldap_search_fmt(
1258 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1259 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1261 if (rc != TLDAP_SUCCESS) {
1262 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1263 tldap_errstr(debug_ctx(), state->ld, rc)));
1267 num_users = talloc_array_length(users);
1269 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1271 if (sstate->entries == NULL) {
1272 DEBUG(10, ("talloc failed\n"));
1276 sstate->num_entries = 0;
1278 for (i=0; i<num_users; i++) {
1279 struct samr_displayentry *e;
1282 e = &sstate->entries[sstate->num_entries];
1284 e->idx = sstate->num_entries;
1285 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1286 DEBUG(10, ("Could not pull sid\n"));
1289 sid_peek_rid(&sid, &e->rid);
1290 e->acct_flags = ACB_NORMAL;
1291 e->account_name = tldap_talloc_single_attribute(
1292 users[i], "samAccountName", sstate->entries);
1293 if (e->account_name == NULL) {
1296 e->fullname = tldap_talloc_single_attribute(
1297 users[i], "displayName", sstate->entries);
1298 if (e->fullname == NULL) {
1301 e->description = tldap_talloc_single_attribute(
1302 users[i], "description", sstate->entries);
1303 if (e->description == NULL) {
1304 e->description = "";
1307 sstate->num_entries += 1;
1308 if (sstate->num_entries >= num_users) {
1313 search->private_data = sstate;
1314 search->next_entry = pdb_ads_next_entry;
1315 search->search_end = pdb_ads_search_end;
1320 static bool pdb_ads_search_users(struct pdb_methods *m,
1321 struct pdb_search *search,
1324 struct pdb_ads_search_state *sstate;
1327 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1331 sstate->acct_flags = acct_flags;
1335 static bool pdb_ads_search_groups(struct pdb_methods *m,
1336 struct pdb_search *search)
1338 struct pdb_ads_search_state *sstate;
1342 filter = talloc_asprintf(talloc_tos(),
1343 "(&(grouptype=%d)(objectclass=group))",
1344 GTYPE_SECURITY_GLOBAL_GROUP);
1345 if (filter == NULL) {
1348 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1349 TALLOC_FREE(filter);
1353 sstate->acct_flags = 0;
1357 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1358 struct pdb_search *search,
1361 struct pdb_ads_search_state *sstate;
1365 filter = talloc_asprintf(
1366 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1367 sid_check_is_builtin(sid)
1368 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1369 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1371 if (filter == NULL) {
1374 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1375 TALLOC_FREE(filter);
1379 sstate->acct_flags = 0;
1383 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1389 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1392 struct pdb_ads_state *state = talloc_get_type_abort(
1393 m->private_data, struct pdb_ads_state);
1394 sid_compose(sid, &state->domainsid, uid);
1398 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1401 struct pdb_ads_state *state = talloc_get_type_abort(
1402 m->private_data, struct pdb_ads_state);
1403 sid_compose(sid, &state->domainsid, gid);
1407 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1408 union unid_t *id, enum lsa_SidType *type)
1410 struct pdb_ads_state *state = talloc_get_type_abort(
1411 m->private_data, struct pdb_ads_state);
1412 struct tldap_message **msg;
1418 * This is a big, big hack: Just hard-code the rid as uid/gid.
1421 sid_peek_rid(sid, &rid);
1423 sidstr = sid_binstring(talloc_tos(), sid);
1424 if (sidstr == NULL) {
1428 rc = tldap_search_fmt(
1429 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1430 NULL, 0, 0, talloc_tos(), &msg,
1431 "(&(objectsid=%s)(objectclass=user))", sidstr);
1432 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1434 *type = SID_NAME_USER;
1435 TALLOC_FREE(sidstr);
1439 rc = tldap_search_fmt(
1440 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1441 NULL, 0, 0, talloc_tos(), &msg,
1442 "(&(objectsid=%s)(objectclass=group))", sidstr);
1443 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1445 *type = SID_NAME_DOM_GRP;
1446 TALLOC_FREE(sidstr);
1450 TALLOC_FREE(sidstr);
1454 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1459 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1464 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1465 const char *domain, char** pwd,
1467 time_t *pass_last_set_time)
1472 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1473 const char* domain, const char* pwd,
1479 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1485 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1486 TALLOC_CTX *mem_ctx,
1487 uint32 *num_domains,
1488 struct trustdom_info ***domains)
1490 return NT_STATUS_NOT_IMPLEMENTED;
1493 static void pdb_ads_init_methods(struct pdb_methods *m)
1496 m->getsampwnam = pdb_ads_getsampwnam;
1497 m->getsampwsid = pdb_ads_getsampwsid;
1498 m->create_user = pdb_ads_create_user;
1499 m->delete_user = pdb_ads_delete_user;
1500 m->add_sam_account = pdb_ads_add_sam_account;
1501 m->update_sam_account = pdb_ads_update_sam_account;
1502 m->delete_sam_account = pdb_ads_delete_sam_account;
1503 m->rename_sam_account = pdb_ads_rename_sam_account;
1504 m->update_login_attempts = pdb_ads_update_login_attempts;
1505 m->getgrsid = pdb_ads_getgrsid;
1506 m->getgrgid = pdb_ads_getgrgid;
1507 m->getgrnam = pdb_ads_getgrnam;
1508 m->create_dom_group = pdb_ads_create_dom_group;
1509 m->delete_dom_group = pdb_ads_delete_dom_group;
1510 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1511 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1512 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1513 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1514 m->enum_group_members = pdb_ads_enum_group_members;
1515 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1516 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1517 m->add_groupmem = pdb_ads_add_groupmem;
1518 m->del_groupmem = pdb_ads_del_groupmem;
1519 m->create_alias = pdb_ads_create_alias;
1520 m->delete_alias = pdb_ads_delete_alias;
1521 m->get_aliasinfo = pdb_ads_get_aliasinfo;
1522 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1523 m->add_aliasmem = pdb_ads_add_aliasmem;
1524 m->del_aliasmem = pdb_ads_del_aliasmem;
1525 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1526 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1527 m->lookup_rids = pdb_ads_lookup_rids;
1528 m->lookup_names = pdb_ads_lookup_names;
1529 m->get_account_policy = pdb_ads_get_account_policy;
1530 m->set_account_policy = pdb_ads_set_account_policy;
1531 m->get_seq_num = pdb_ads_get_seq_num;
1532 m->search_users = pdb_ads_search_users;
1533 m->search_groups = pdb_ads_search_groups;
1534 m->search_aliases = pdb_ads_search_aliases;
1535 m->uid_to_rid = pdb_ads_uid_to_rid;
1536 m->uid_to_sid = pdb_ads_uid_to_sid;
1537 m->gid_to_sid = pdb_ads_gid_to_sid;
1538 m->sid_to_id = pdb_ads_sid_to_id;
1539 m->rid_algorithm = pdb_ads_rid_algorithm;
1540 m->new_rid = pdb_ads_new_rid;
1541 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1542 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1543 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1544 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1547 static void free_private_data(void **vp)
1549 struct pdb_ads_state *state = talloc_get_type_abort(
1550 *vp, struct pdb_ads_state);
1552 TALLOC_FREE(state->ld);
1556 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1557 const char *location)
1559 const char *rootdse_attrs[2] = {
1560 "defaultNamingContext", "configurationNamingContext" };
1561 const char *domain_attrs[1] = { "objectSid" };
1562 const char *ncname_attrs[1] = { "netbiosname" };
1563 struct tldap_message **rootdse, **domain, **ncname;
1564 TALLOC_CTX *frame = talloc_stackframe();
1565 struct sockaddr_un sunaddr;
1570 ZERO_STRUCT(sunaddr);
1571 sunaddr.sun_family = AF_UNIX;
1572 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1574 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1576 if (!NT_STATUS_IS_OK(status)) {
1577 DEBUG(10, ("Could not connect to %s: %s\n", location,
1578 nt_errstr(status)));
1582 state->ld = tldap_context_create(state, fd);
1583 if (state->ld == NULL) {
1585 status = NT_STATUS_NO_MEMORY;
1589 rc = tldap_search_fmt(
1590 state->ld, "", TLDAP_SCOPE_BASE,
1591 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1592 talloc_tos(), &rootdse, "(objectclass=*)");
1593 if (rc != TLDAP_SUCCESS) {
1594 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1595 tldap_errstr(debug_ctx(), state->ld, rc)));
1596 status = NT_STATUS_LDAP(rc);
1599 if (talloc_array_length(rootdse) != 1) {
1600 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1604 state->domaindn = tldap_talloc_single_attribute(
1605 rootdse[0], "defaultNamingContext", state);
1606 if (state->domaindn == NULL) {
1607 DEBUG(10, ("Could not get defaultNamingContext\n"));
1608 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1611 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1613 state->configdn = tldap_talloc_single_attribute(
1614 rootdse[0], "configurationNamingContext", state);
1615 if (state->domaindn == NULL) {
1616 DEBUG(10, ("Could not get configurationNamingContext\n"));
1617 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1620 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1623 * Figure out our domain's SID
1625 rc = tldap_search_fmt(
1626 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1627 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1628 talloc_tos(), &domain, "(objectclass=*)");
1629 if (rc != TLDAP_SUCCESS) {
1630 DEBUG(10, ("Could not retrieve domain: %s\n",
1631 tldap_errstr(debug_ctx(), state->ld, rc)));
1632 status = NT_STATUS_LDAP(rc);
1636 num_domains = talloc_array_length(domain);
1637 if (num_domains != 1) {
1638 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1639 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1642 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1643 DEBUG(10, ("Could not retrieve domain SID\n"));
1644 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1647 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1650 * Figure out our domain's short name
1652 rc = tldap_search_fmt(
1653 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1654 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1655 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1656 if (rc != TLDAP_SUCCESS) {
1657 DEBUG(10, ("Could not retrieve ncname: %s\n",
1658 tldap_errstr(debug_ctx(), state->ld, rc)));
1659 status = NT_STATUS_LDAP(rc);
1662 if (talloc_array_length(ncname) != 1) {
1663 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1667 state->netbiosname = tldap_talloc_single_attribute(
1668 ncname[0], "netbiosname", state);
1669 if (state->netbiosname == NULL) {
1670 DEBUG(10, ("Could not get netbiosname\n"));
1671 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1674 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1676 if (!strequal(lp_workgroup(), state->netbiosname)) {
1677 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1678 state->netbiosname, lp_workgroup()));
1679 status = NT_STATUS_NO_SUCH_DOMAIN;
1683 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1685 status = NT_STATUS_OK;
1691 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1692 const char *location)
1694 struct pdb_methods *m;
1695 struct pdb_ads_state *state;
1699 m = talloc(talloc_autofree_context(), struct pdb_methods);
1701 return NT_STATUS_NO_MEMORY;
1703 state = talloc(m, struct pdb_ads_state);
1704 if (state == NULL) {
1707 m->private_data = state;
1708 m->free_private_data = free_private_data;
1709 pdb_ads_init_methods(m);
1711 if (location == NULL) {
1712 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1716 if (location == NULL) {
1720 status = pdb_ads_connect(state, location);
1721 if (!NT_STATUS_IS_OK(status)) {
1722 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1727 return NT_STATUS_OK;
1729 status = NT_STATUS_NO_MEMORY;
1735 NTSTATUS pdb_ads_init(void);
1736 NTSTATUS pdb_ads_init(void)
1738 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",