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,
27 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
28 struct dom_sid *psid);
31 struct pdb_ads_state {
32 struct tldap_context *ld;
33 struct dom_sid domainsid;
39 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
44 if (!tldap_pull_uint64(msg, attr, &tmp)) {
47 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
51 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
54 sid_peek_rid(sid, &rid);
58 struct pdb_ads_samu_private {
60 struct tldap_message *ldapmsg;
63 static struct samu *pdb_ads_init_guest(TALLOC_CTX *mem_ctx,
64 struct pdb_methods *m)
66 struct pdb_ads_state *state = talloc_get_type_abort(
67 m->private_data, struct pdb_ads_state);
68 struct dom_sid guest_sid;
72 sid_compose(&guest_sid, &state->domainsid, DOMAIN_USER_RID_GUEST);
74 guest = samu_new(mem_ctx);
79 status = pdb_ads_getsampwsid(m, guest, &guest_sid);
80 if (!NT_STATUS_IS_OK(status)) {
81 DEBUG(10, ("Could not init guest account: %s\n",
89 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
90 struct pdb_methods *m, struct samu *sam)
92 struct pdb_ads_samu_private *result;
95 result = (struct pdb_ads_samu_private *)
96 pdb_get_backend_private_data(sam, m);
99 return talloc_get_type_abort(
100 result, struct pdb_ads_samu_private);
104 * This is now a weirdness of the passdb API. For the guest user we
105 * are not asked first.
107 sid_peek_rid(pdb_get_user_sid(sam), &rid);
109 if (rid == DOMAIN_USER_RID_GUEST) {
110 struct samu *guest = pdb_ads_init_guest(talloc_tos(), m);
115 result = talloc_get_type_abort(
116 pdb_get_backend_private_data(guest, m),
117 struct pdb_ads_samu_private);
118 pdb_set_backend_private_data(
119 sam, talloc_move(sam, &result), NULL, m, PDB_SET);
121 return talloc_get_type_abort(
122 pdb_get_backend_private_data(sam, m),
123 struct pdb_ads_samu_private);
129 static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m,
131 struct tldap_message *entry)
133 struct pdb_ads_state *state = talloc_get_type_abort(
134 m->private_data, struct pdb_ads_state);
135 TALLOC_CTX *frame = talloc_stackframe();
136 struct pdb_ads_samu_private *priv;
137 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
144 priv = talloc(sam, struct pdb_ads_samu_private);
146 return NT_STATUS_NO_MEMORY;
148 if (!tldap_entry_dn(entry, &priv->dn)) {
150 return NT_STATUS_INTERNAL_DB_CORRUPTION;
153 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
155 DEBUG(10, ("no samAccountName\n"));
158 pdb_set_username(sam, str, PDB_SET);
161 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
162 pdb_set_logon_time(sam, tmp_time, PDB_SET);
164 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
165 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
167 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
168 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
170 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
171 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
174 str = tldap_talloc_single_attribute(entry, "samAccoutName",
177 pdb_set_username(sam, str, PDB_SET);
180 str = tldap_talloc_single_attribute(entry, "displayName",
183 pdb_set_fullname(sam, str, PDB_SET);
186 str = tldap_talloc_single_attribute(entry, "homeDirectory",
189 pdb_set_homedir(sam, str, PDB_SET);
192 str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
194 pdb_set_dir_drive(sam, str, PDB_SET);
197 str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
199 pdb_set_logon_script(sam, str, PDB_SET);
202 str = tldap_talloc_single_attribute(entry, "profilePath",
205 pdb_set_profile_path(sam, str, PDB_SET);
208 str = tldap_talloc_single_attribute(entry, "profilePath",
211 pdb_set_profile_path(sam, str, PDB_SET);
214 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
215 DEBUG(10, ("Could not pull SID\n"));
218 pdb_set_user_sid(sam, &sid, PDB_SET);
220 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
221 DEBUG(10, ("Could not pull userAccountControl\n"));
224 pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET);
226 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
227 if (blob.length != NT_HASH_LEN) {
228 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
229 (int)blob.length, NT_HASH_LEN));
232 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
235 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
236 if (blob.length != LM_HASH_LEN) {
237 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
238 (int)blob.length, LM_HASH_LEN));
241 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
244 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
245 sid_compose(&sid, &state->domainsid, n);
246 pdb_set_group_sid(sam, &sid, PDB_SET);
250 priv->ldapmsg = talloc_move(priv, &entry);
251 pdb_set_backend_private_data(sam, priv, NULL, m, PDB_SET);
253 status = NT_STATUS_OK;
259 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
260 struct tldap_message *existing,
262 int *pnum_mods, struct tldap_mod **pmods,
267 /* TODO: All fields :-) */
269 ret &= tldap_make_mod_fmt(
270 existing, mem_ctx, pnum_mods, pmods, "displayName",
271 "%s", pdb_get_fullname(sam));
273 ret &= tldap_make_mod_blob(
274 existing, mem_ctx, pnum_mods, pmods, "unicodePwd",
275 data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN));
277 ret &= tldap_make_mod_blob(
278 existing, mem_ctx, pnum_mods, pmods, "dBCSPwd",
279 data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN));
284 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
285 struct pdb_ads_state *state,
286 struct samu *sam_acct,
289 const char * attrs[] = {
290 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
291 "sAMAccountName", "displayName", "homeDirectory",
292 "homeDrive", "scriptPath", "profilePath", "description",
293 "userWorkstations", "comment", "userParameters", "objectSid",
294 "primaryGroupID", "userAccountControl", "logonHours",
295 "badPwdCount", "logonCount", "countryCode", "codePage",
296 "unicodePwd", "dBCSPwd" };
297 struct tldap_message **users;
300 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
301 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
302 &users, "%s", filter);
303 if (rc != TLDAP_SUCCESS) {
304 DEBUG(10, ("ldap_search failed %s\n",
305 tldap_errstr(debug_ctx(), state->ld, rc)));
306 return NT_STATUS_LDAP(rc);
309 count = talloc_array_length(users);
311 DEBUG(10, ("Expected 1 user, got %d\n", count));
312 return NT_STATUS_INTERNAL_DB_CORRUPTION;
315 return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]);
318 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
319 struct samu *sam_acct,
320 const char *username)
322 struct pdb_ads_state *state = talloc_get_type_abort(
323 m->private_data, struct pdb_ads_state);
326 filter = talloc_asprintf(
327 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
329 NT_STATUS_HAVE_NO_MEMORY(filter);
331 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
334 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
335 struct samu *sam_acct,
338 struct pdb_ads_state *state = talloc_get_type_abort(
339 m->private_data, struct pdb_ads_state);
340 char *sidstr, *filter;
342 sidstr = sid_binstring(talloc_tos(), sid);
343 NT_STATUS_HAVE_NO_MEMORY(sidstr);
345 filter = talloc_asprintf(
346 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
348 NT_STATUS_HAVE_NO_MEMORY(filter);
350 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
353 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
355 const char *name, uint32 acct_flags,
358 struct pdb_ads_state *state = talloc_get_type_abort(
359 m->private_data, struct pdb_ads_state);
360 const char *attrs[1] = { "objectSid" };
361 struct tldap_mod *mods = NULL;
363 struct tldap_message **user;
369 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
372 return NT_STATUS_NO_MEMORY;
375 /* TODO: Create machines etc */
378 ok &= tldap_make_mod_fmt(
379 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
380 ok &= tldap_make_mod_fmt(
381 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
384 return NT_STATUS_NO_MEMORY;
387 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
388 if (rc != TLDAP_SUCCESS) {
389 DEBUG(10, ("ldap_add failed %s\n",
390 tldap_errstr(debug_ctx(), state->ld, rc)));
392 return NT_STATUS_LDAP(rc);
395 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
396 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &user,
397 "(&(objectclass=user)(samaccountname=%s))",
399 if (rc != TLDAP_SUCCESS) {
400 DEBUG(10, ("Could not find just created user %s: %s\n",
401 name, tldap_errstr(debug_ctx(), state->ld, rc)));
403 return NT_STATUS_LDAP(rc);
406 if (talloc_array_length(user) != 1) {
407 DEBUG(10, ("Got %d users, expected one\n",
408 (int)talloc_array_length(user)));
410 return NT_STATUS_LDAP(rc);
413 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
414 DEBUG(10, ("Could not fetch objectSid from user %s\n",
417 return NT_STATUS_INTERNAL_DB_CORRUPTION;
420 sid_peek_rid(&sid, rid);
425 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
429 struct pdb_ads_state *state = talloc_get_type_abort(
430 m->private_data, struct pdb_ads_state);
431 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
434 rc = tldap_delete(state->ld, priv->dn, NULL, NULL);
435 if (rc != TLDAP_SUCCESS) {
436 DEBUG(10, ("ldap_delete for %s failed: %s\n", priv->dn,
437 tldap_errstr(debug_ctx(), state->ld, rc)));
438 return NT_STATUS_LDAP(rc);
443 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
444 struct samu *sampass)
446 return NT_STATUS_NOT_IMPLEMENTED;
449 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
452 struct pdb_ads_state *state = talloc_get_type_abort(
453 m->private_data, struct pdb_ads_state);
454 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
455 struct tldap_mod *mods = NULL;
456 int rc, num_mods = 0;
458 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
459 &num_mods, &mods, sam)) {
460 return NT_STATUS_NO_MEMORY;
463 rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, NULL);
464 if (rc != TLDAP_SUCCESS) {
465 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
466 tldap_errstr(debug_ctx(), state->ld, rc)));
467 return NT_STATUS_LDAP(rc);
475 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
476 struct samu *username)
478 return NT_STATUS_NOT_IMPLEMENTED;
481 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
482 struct samu *oldname,
485 return NT_STATUS_NOT_IMPLEMENTED;
488 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
489 struct samu *sam_acct,
492 return NT_STATUS_NOT_IMPLEMENTED;
495 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
498 struct pdb_ads_state *state = talloc_get_type_abort(
499 m->private_data, struct pdb_ads_state);
500 const char *attrs[4] = { "objectSid", "description", "samAccountName",
503 struct tldap_message **group;
507 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
508 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
509 &group, "%s", filter);
510 if (rc != TLDAP_SUCCESS) {
511 DEBUG(10, ("ldap_search failed %s\n",
512 tldap_errstr(debug_ctx(), state->ld, rc)));
513 return NT_STATUS_LDAP(rc);
515 if (talloc_array_length(group) != 1) {
516 DEBUG(10, ("Expected 1 user, got %d\n",
517 (int)talloc_array_length(group)));
518 return NT_STATUS_INTERNAL_DB_CORRUPTION;
521 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
522 return NT_STATUS_INTERNAL_DB_CORRUPTION;
524 map->gid = pdb_ads_sid2gid(&map->sid);
526 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
527 return NT_STATUS_INTERNAL_DB_CORRUPTION;
530 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
531 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
532 map->sid_name_use = SID_NAME_ALIAS;
534 case GTYPE_SECURITY_GLOBAL_GROUP:
535 map->sid_name_use = SID_NAME_DOM_GRP;
538 return NT_STATUS_INTERNAL_DB_CORRUPTION;
541 str = tldap_talloc_single_attribute(group[0], "samAccountName",
544 return NT_STATUS_INTERNAL_DB_CORRUPTION;
546 fstrcpy(map->nt_name, str);
549 str = tldap_talloc_single_attribute(group[0], "description",
552 fstrcpy(map->comment, str);
555 map->comment[0] = '\0';
562 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
568 filter = talloc_asprintf(talloc_tos(),
569 "(&(objectsid=%s)(objectclass=group))",
570 sid_string_talloc(talloc_tos(), &sid));
571 if (filter == NULL) {
572 return NT_STATUS_NO_MEMORY;
575 status = pdb_ads_getgrfilter(m, map, filter);
580 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
584 pdb_ads_gid_to_sid(m, gid, &sid);
585 return pdb_ads_getgrsid(m, map, sid);
588 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
594 filter = talloc_asprintf(talloc_tos(),
595 "(&(samaccountname=%s)(objectclass=group))",
597 if (filter == NULL) {
598 return NT_STATUS_NO_MEMORY;
601 status = pdb_ads_getgrfilter(m, map, filter);
606 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
607 TALLOC_CTX *mem_ctx, const char *name,
610 TALLOC_CTX *frame = talloc_stackframe();
611 struct pdb_ads_state *state = talloc_get_type_abort(
612 m->private_data, struct pdb_ads_state);
613 const char *attrs[1] = { "objectSid" };
615 struct tldap_mod *mods = NULL;
616 struct tldap_message **alias;
622 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
626 return NT_STATUS_NO_MEMORY;
629 ok &= tldap_make_mod_fmt(
630 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
632 ok &= tldap_make_mod_fmt(
633 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
634 ok &= tldap_make_mod_fmt(
635 NULL, talloc_tos(), &num_mods, &mods, "groupType",
636 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
640 return NT_STATUS_NO_MEMORY;
643 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
644 if (rc != TLDAP_SUCCESS) {
645 DEBUG(10, ("ldap_add failed %s\n",
646 tldap_errstr(debug_ctx(), state->ld, rc)));
648 return NT_STATUS_LDAP(rc);
651 rc = tldap_search_fmt(
652 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
653 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
654 "(&(objectclass=group)(samaccountname=%s))", name);
655 if (rc != TLDAP_SUCCESS) {
656 DEBUG(10, ("Could not find just created alias %s: %s\n",
657 name, tldap_errstr(debug_ctx(), state->ld, rc)));
659 return NT_STATUS_LDAP(rc);
662 if (talloc_array_length(alias) != 1) {
663 DEBUG(10, ("Got %d alias, expected one\n",
664 (int)talloc_array_length(alias)));
666 return NT_STATUS_LDAP(rc);
669 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
670 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
673 return NT_STATUS_INTERNAL_DB_CORRUPTION;
676 sid_peek_rid(&sid, rid);
681 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
682 TALLOC_CTX *mem_ctx, uint32 rid)
684 return NT_STATUS_NOT_IMPLEMENTED;
687 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
690 return NT_STATUS_NOT_IMPLEMENTED;
693 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
696 return NT_STATUS_NOT_IMPLEMENTED;
699 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
702 return NT_STATUS_NOT_IMPLEMENTED;
705 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
707 enum lsa_SidType sid_name_use,
709 size_t *p_num_entries,
712 return NT_STATUS_NOT_IMPLEMENTED;
715 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
717 const DOM_SID *group,
719 size_t *pnum_members)
721 struct pdb_ads_state *state = talloc_get_type_abort(
722 m->private_data, struct pdb_ads_state);
723 const char *attrs[1] = { "member" };
725 struct tldap_message **msg;
726 int i, rc, num_members;
730 sidstr = sid_binstring(talloc_tos(), group);
731 NT_STATUS_HAVE_NO_MEMORY(sidstr);
733 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
734 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
735 "(objectsid=%s)", sidstr);
737 if (rc != TLDAP_SUCCESS) {
738 DEBUG(10, ("ldap_search failed %s\n",
739 tldap_errstr(debug_ctx(), state->ld, rc)));
740 return NT_STATUS_LDAP(rc);
742 switch talloc_array_length(msg) {
744 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
749 return NT_STATUS_INTERNAL_DB_CORRUPTION;
753 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
754 return NT_STATUS_INTERNAL_DB_CORRUPTION;
757 members = talloc_array(mem_ctx, uint32_t, num_members);
758 if (members == NULL) {
759 return NT_STATUS_NO_MEMORY;
762 for (i=0; i<num_members; i++) {
764 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &sid)
765 || !sid_peek_rid(&sid, &members[i])) {
766 TALLOC_FREE(members);
767 return NT_STATUS_INTERNAL_DB_CORRUPTION;
772 *pnum_members = num_members;
776 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
781 size_t *p_num_groups)
783 struct pdb_ads_state *state = talloc_get_type_abort(
784 m->private_data, struct pdb_ads_state);
785 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
787 const char *attrs[1] = { "objectSid" };
788 struct tldap_message **groups;
791 struct dom_sid *group_sids;
794 rc = tldap_search_fmt(
795 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
796 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
797 "(&(member=%s)(grouptype=%d)(objectclass=group))",
798 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
799 if (rc != TLDAP_SUCCESS) {
800 DEBUG(10, ("ldap_search failed %s\n",
801 tldap_errstr(debug_ctx(), state->ld, rc)));
802 return NT_STATUS_LDAP(rc);
805 count = talloc_array_length(groups);
807 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
808 if (group_sids == NULL) {
809 return NT_STATUS_NO_MEMORY;
811 gids = talloc_array(mem_ctx, gid_t, count);
813 TALLOC_FREE(group_sids);
814 return NT_STATUS_NO_MEMORY;
818 for (i=0; i<count; i++) {
819 if (!tldap_pull_binsid(groups[i], "objectSid",
820 &group_sids[num_groups])) {
823 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
826 if (num_groups == count) {
831 *pp_sids = group_sids;
833 *p_num_groups = num_groups;
837 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
841 return NT_STATUS_NOT_IMPLEMENTED;
844 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
846 uint32 group_rid, uint32 member_rid)
848 return NT_STATUS_NOT_IMPLEMENTED;
851 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
853 uint32 group_rid, uint32 member_rid)
855 return NT_STATUS_NOT_IMPLEMENTED;
858 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
859 const char *name, uint32 *rid)
861 TALLOC_CTX *frame = talloc_stackframe();
862 struct pdb_ads_state *state = talloc_get_type_abort(
863 m->private_data, struct pdb_ads_state);
864 const char *attrs[1] = { "objectSid" };
866 struct tldap_mod *mods = NULL;
867 struct tldap_message **alias;
873 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
877 return NT_STATUS_NO_MEMORY;
880 ok &= tldap_make_mod_fmt(
881 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
883 ok &= tldap_make_mod_fmt(
884 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
885 ok &= tldap_make_mod_fmt(
886 NULL, talloc_tos(), &num_mods, &mods, "groupType",
887 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
891 return NT_STATUS_NO_MEMORY;
894 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
895 if (rc != TLDAP_SUCCESS) {
896 DEBUG(10, ("ldap_add failed %s\n",
897 tldap_errstr(debug_ctx(), state->ld, rc)));
899 return NT_STATUS_LDAP(rc);
902 rc = tldap_search_fmt(
903 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
904 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
905 "(&(objectclass=group)(samaccountname=%s))", name);
906 if (rc != TLDAP_SUCCESS) {
907 DEBUG(10, ("Could not find just created alias %s: %s\n",
908 name, tldap_errstr(debug_ctx(), state->ld, rc)));
910 return NT_STATUS_LDAP(rc);
913 if (talloc_array_length(alias) != 1) {
914 DEBUG(10, ("Got %d alias, expected one\n",
915 (int)talloc_array_length(alias)));
917 return NT_STATUS_LDAP(rc);
920 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
921 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
924 return NT_STATUS_INTERNAL_DB_CORRUPTION;
927 sid_peek_rid(&sid, rid);
932 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
935 struct pdb_ads_state *state = talloc_get_type_abort(
936 m->private_data, struct pdb_ads_state);
937 struct tldap_message **alias;
941 sidstr = sid_binstring(talloc_tos(), sid);
942 if (sidstr == NULL) {
943 return NT_STATUS_NO_MEMORY;
946 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
947 NULL, 0, 0, talloc_tos(), &alias,
948 "(&(objectSid=%s)(objectclass=group)"
949 "(|(grouptype=%d)(grouptype=%d)))",
950 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
951 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
953 if (rc != TLDAP_SUCCESS) {
954 DEBUG(10, ("ldap_search failed: %s\n",
955 tldap_errstr(debug_ctx(), state->ld, rc)));
957 return NT_STATUS_LDAP(rc);
959 if (talloc_array_length(alias) != 1) {
960 DEBUG(10, ("Expected 1 alias, got %d\n",
961 (int)talloc_array_length(alias)));
962 return NT_STATUS_INTERNAL_DB_CORRUPTION;
964 if (!tldap_entry_dn(alias[0], &dn)) {
965 DEBUG(10, ("Could not get DN for alias %s\n",
966 sid_string_dbg(sid)));
967 return NT_STATUS_INTERNAL_ERROR;
970 rc = tldap_delete(state->ld, dn, NULL, NULL);
971 if (rc != TLDAP_SUCCESS) {
972 DEBUG(10, ("ldap_delete failed: %s\n",
973 tldap_errstr(debug_ctx(), state->ld, rc)));
975 return NT_STATUS_LDAP(rc);
981 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
983 struct acct_info *info)
985 return NT_STATUS_NOT_IMPLEMENTED;
988 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
990 struct acct_info *info)
992 return NT_STATUS_NOT_IMPLEMENTED;
995 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
996 const struct dom_sid *sid,
997 TALLOC_CTX *mem_ctx, char **pdn)
999 struct tldap_message **msg;
1003 sidstr = sid_binstring(talloc_tos(), sid);
1004 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1006 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1007 NULL, 0, 0, talloc_tos(), &msg,
1008 "(objectsid=%s)", sidstr);
1009 TALLOC_FREE(sidstr);
1010 if (rc != TLDAP_SUCCESS) {
1011 DEBUG(10, ("ldap_search failed %s\n",
1012 tldap_errstr(debug_ctx(), state->ld, rc)));
1013 return NT_STATUS_LDAP(rc);
1016 switch talloc_array_length(msg) {
1018 return NT_STATUS_NOT_FOUND;
1022 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1025 if (!tldap_entry_dn(msg[0], &dn)) {
1026 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1029 dn = talloc_strdup(mem_ctx, dn);
1031 return NT_STATUS_NO_MEMORY;
1036 return NT_STATUS_OK;
1039 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1040 const DOM_SID *alias,
1041 const DOM_SID *member,
1044 struct pdb_ads_state *state = talloc_get_type_abort(
1045 m->private_data, struct pdb_ads_state);
1046 TALLOC_CTX *frame = talloc_stackframe();
1047 struct tldap_mod *mods;
1049 char *aliasdn, *memberdn;
1052 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1053 if (!NT_STATUS_IS_OK(status)) {
1054 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1055 sid_string_dbg(alias), nt_errstr(status)));
1057 return NT_STATUS_NO_SUCH_ALIAS;
1059 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1060 if (!NT_STATUS_IS_OK(status)) {
1061 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1062 sid_string_dbg(member), nt_errstr(status)));
1069 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1070 "member", memberdn)) {
1072 return NT_STATUS_NO_MEMORY;
1075 rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
1077 if (rc != TLDAP_SUCCESS) {
1078 DEBUG(10, ("ldap_modify failed: %s\n",
1079 tldap_errstr(debug_ctx(), state->ld, rc)));
1080 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1081 return NT_STATUS_MEMBER_IN_ALIAS;
1083 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1084 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1086 return NT_STATUS_LDAP(rc);
1089 return NT_STATUS_OK;
1092 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1093 const DOM_SID *alias,
1094 const DOM_SID *member)
1096 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1099 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1100 const DOM_SID *alias,
1101 const DOM_SID *member)
1103 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1106 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1107 struct dom_sid *psid)
1109 const char *attrs[1] = { "objectSid" };
1110 struct tldap_message **msg;
1116 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1117 dnblob->data, dnblob->length, &dn, &len,
1121 rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1122 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1123 &msg, "(objectclass=*)");
1125 if (talloc_array_length(msg) != 1) {
1126 DEBUG(10, ("Got %d objects, expected one\n",
1127 (int)talloc_array_length(msg)));
1132 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1137 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1138 const DOM_SID *alias,
1139 TALLOC_CTX *mem_ctx,
1141 size_t *pnum_members)
1143 struct pdb_ads_state *state = talloc_get_type_abort(
1144 m->private_data, struct pdb_ads_state);
1145 const char *attrs[1] = { "member" };
1147 struct tldap_message **msg;
1148 int i, rc, num_members;
1150 struct dom_sid *members;
1152 sidstr = sid_binstring(talloc_tos(), alias);
1153 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1155 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1156 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1157 "(objectsid=%s)", sidstr);
1158 TALLOC_FREE(sidstr);
1159 if (rc != TLDAP_SUCCESS) {
1160 DEBUG(10, ("ldap_search failed %s\n",
1161 tldap_errstr(debug_ctx(), state->ld, rc)));
1162 return NT_STATUS_LDAP(rc);
1164 switch talloc_array_length(msg) {
1166 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1171 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1175 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1176 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1179 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1180 if (members == NULL) {
1181 return NT_STATUS_NO_MEMORY;
1184 for (i=0; i<num_members; i++) {
1185 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1186 TALLOC_FREE(members);
1187 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1191 *pmembers = members;
1192 *pnum_members = num_members;
1193 return NT_STATUS_OK;
1196 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1197 TALLOC_CTX *mem_ctx,
1198 const DOM_SID *domain_sid,
1199 const DOM_SID *members,
1201 uint32 **pp_alias_rids,
1202 size_t *p_num_alias_rids)
1204 return NT_STATUS_NOT_IMPLEMENTED;
1207 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1208 const DOM_SID *domain_sid,
1211 const char **pp_names,
1212 enum lsa_SidType *attrs)
1214 return NT_STATUS_NOT_IMPLEMENTED;
1217 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1218 const DOM_SID *domain_sid,
1220 const char **pp_names,
1222 enum lsa_SidType *attrs)
1224 return NT_STATUS_NOT_IMPLEMENTED;
1227 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1228 int policy_index, uint32 *value)
1230 return account_policy_get(policy_index, value)
1231 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1234 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1235 int policy_index, uint32 value)
1237 return account_policy_set(policy_index, value)
1238 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1241 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1244 return NT_STATUS_NOT_IMPLEMENTED;
1247 struct pdb_ads_search_state {
1248 uint32_t acct_flags;
1249 struct samr_displayentry *entries;
1250 uint32_t num_entries;
1255 static bool pdb_ads_next_entry(struct pdb_search *search,
1256 struct samr_displayentry *entry)
1258 struct pdb_ads_search_state *state = talloc_get_type_abort(
1259 search->private_data, struct pdb_ads_search_state);
1261 if (state->current == state->num_entries) {
1265 entry->idx = state->entries[state->current].idx;
1266 entry->rid = state->entries[state->current].rid;
1267 entry->acct_flags = state->entries[state->current].acct_flags;
1269 entry->account_name = talloc_strdup(
1270 search, state->entries[state->current].account_name);
1271 entry->fullname = talloc_strdup(
1272 search, state->entries[state->current].fullname);
1273 entry->description = talloc_strdup(
1274 search, state->entries[state->current].description);
1276 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1277 || (entry->description == NULL)) {
1278 DEBUG(0, ("talloc_strdup failed\n"));
1282 state->current += 1;
1286 static void pdb_ads_search_end(struct pdb_search *search)
1288 struct pdb_ads_search_state *state = talloc_get_type_abort(
1289 search->private_data, struct pdb_ads_search_state);
1293 static bool pdb_ads_search_filter(struct pdb_methods *m,
1294 struct pdb_search *search,
1296 struct pdb_ads_search_state **pstate)
1298 struct pdb_ads_state *state = talloc_get_type_abort(
1299 m->private_data, struct pdb_ads_state);
1300 struct pdb_ads_search_state *sstate;
1301 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1302 "userAccountControl", "description" };
1303 struct tldap_message **users;
1304 int i, rc, num_users;
1306 sstate = talloc_zero(search, struct pdb_ads_search_state);
1307 if (sstate == NULL) {
1311 rc = tldap_search_fmt(
1312 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1313 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1315 if (rc != TLDAP_SUCCESS) {
1316 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1317 tldap_errstr(debug_ctx(), state->ld, rc)));
1321 num_users = talloc_array_length(users);
1323 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1325 if (sstate->entries == NULL) {
1326 DEBUG(10, ("talloc failed\n"));
1330 sstate->num_entries = 0;
1332 for (i=0; i<num_users; i++) {
1333 struct samr_displayentry *e;
1336 e = &sstate->entries[sstate->num_entries];
1338 e->idx = sstate->num_entries;
1339 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1340 DEBUG(10, ("Could not pull sid\n"));
1343 sid_peek_rid(&sid, &e->rid);
1344 e->acct_flags = ACB_NORMAL;
1345 e->account_name = tldap_talloc_single_attribute(
1346 users[i], "samAccountName", sstate->entries);
1347 if (e->account_name == NULL) {
1350 e->fullname = tldap_talloc_single_attribute(
1351 users[i], "displayName", sstate->entries);
1352 if (e->fullname == NULL) {
1355 e->description = tldap_talloc_single_attribute(
1356 users[i], "description", sstate->entries);
1357 if (e->description == NULL) {
1358 e->description = "";
1361 sstate->num_entries += 1;
1362 if (sstate->num_entries >= num_users) {
1367 search->private_data = sstate;
1368 search->next_entry = pdb_ads_next_entry;
1369 search->search_end = pdb_ads_search_end;
1374 static bool pdb_ads_search_users(struct pdb_methods *m,
1375 struct pdb_search *search,
1378 struct pdb_ads_search_state *sstate;
1381 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1385 sstate->acct_flags = acct_flags;
1389 static bool pdb_ads_search_groups(struct pdb_methods *m,
1390 struct pdb_search *search)
1392 struct pdb_ads_search_state *sstate;
1396 filter = talloc_asprintf(talloc_tos(),
1397 "(&(grouptype=%d)(objectclass=group))",
1398 GTYPE_SECURITY_GLOBAL_GROUP);
1399 if (filter == NULL) {
1402 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1403 TALLOC_FREE(filter);
1407 sstate->acct_flags = 0;
1411 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1412 struct pdb_search *search,
1415 struct pdb_ads_search_state *sstate;
1419 filter = talloc_asprintf(
1420 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1421 sid_check_is_builtin(sid)
1422 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1423 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1425 if (filter == NULL) {
1428 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1429 TALLOC_FREE(filter);
1433 sstate->acct_flags = 0;
1437 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1443 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1446 struct pdb_ads_state *state = talloc_get_type_abort(
1447 m->private_data, struct pdb_ads_state);
1448 sid_compose(sid, &state->domainsid, uid);
1452 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1455 struct pdb_ads_state *state = talloc_get_type_abort(
1456 m->private_data, struct pdb_ads_state);
1457 sid_compose(sid, &state->domainsid, gid);
1461 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1462 union unid_t *id, enum lsa_SidType *type)
1464 struct pdb_ads_state *state = talloc_get_type_abort(
1465 m->private_data, struct pdb_ads_state);
1466 struct tldap_message **msg;
1472 * This is a big, big hack: Just hard-code the rid as uid/gid.
1475 sid_peek_rid(sid, &rid);
1477 sidstr = sid_binstring(talloc_tos(), sid);
1478 if (sidstr == NULL) {
1482 rc = tldap_search_fmt(
1483 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1484 NULL, 0, 0, talloc_tos(), &msg,
1485 "(&(objectsid=%s)(objectclass=user))", sidstr);
1486 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1488 *type = SID_NAME_USER;
1489 TALLOC_FREE(sidstr);
1493 rc = tldap_search_fmt(
1494 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1495 NULL, 0, 0, talloc_tos(), &msg,
1496 "(&(objectsid=%s)(objectclass=group))", sidstr);
1497 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1499 *type = SID_NAME_DOM_GRP;
1500 TALLOC_FREE(sidstr);
1504 TALLOC_FREE(sidstr);
1508 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1513 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1518 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1519 const char *domain, char** pwd,
1521 time_t *pass_last_set_time)
1526 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1527 const char* domain, const char* pwd,
1533 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1539 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1540 TALLOC_CTX *mem_ctx,
1541 uint32 *num_domains,
1542 struct trustdom_info ***domains)
1544 return NT_STATUS_NOT_IMPLEMENTED;
1547 static void pdb_ads_init_methods(struct pdb_methods *m)
1550 m->getsampwnam = pdb_ads_getsampwnam;
1551 m->getsampwsid = pdb_ads_getsampwsid;
1552 m->create_user = pdb_ads_create_user;
1553 m->delete_user = pdb_ads_delete_user;
1554 m->add_sam_account = pdb_ads_add_sam_account;
1555 m->update_sam_account = pdb_ads_update_sam_account;
1556 m->delete_sam_account = pdb_ads_delete_sam_account;
1557 m->rename_sam_account = pdb_ads_rename_sam_account;
1558 m->update_login_attempts = pdb_ads_update_login_attempts;
1559 m->getgrsid = pdb_ads_getgrsid;
1560 m->getgrgid = pdb_ads_getgrgid;
1561 m->getgrnam = pdb_ads_getgrnam;
1562 m->create_dom_group = pdb_ads_create_dom_group;
1563 m->delete_dom_group = pdb_ads_delete_dom_group;
1564 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1565 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1566 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1567 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1568 m->enum_group_members = pdb_ads_enum_group_members;
1569 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1570 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1571 m->add_groupmem = pdb_ads_add_groupmem;
1572 m->del_groupmem = pdb_ads_del_groupmem;
1573 m->create_alias = pdb_ads_create_alias;
1574 m->delete_alias = pdb_ads_delete_alias;
1575 m->get_aliasinfo = pdb_ads_get_aliasinfo;
1576 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1577 m->add_aliasmem = pdb_ads_add_aliasmem;
1578 m->del_aliasmem = pdb_ads_del_aliasmem;
1579 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1580 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1581 m->lookup_rids = pdb_ads_lookup_rids;
1582 m->lookup_names = pdb_ads_lookup_names;
1583 m->get_account_policy = pdb_ads_get_account_policy;
1584 m->set_account_policy = pdb_ads_set_account_policy;
1585 m->get_seq_num = pdb_ads_get_seq_num;
1586 m->search_users = pdb_ads_search_users;
1587 m->search_groups = pdb_ads_search_groups;
1588 m->search_aliases = pdb_ads_search_aliases;
1589 m->uid_to_rid = pdb_ads_uid_to_rid;
1590 m->uid_to_sid = pdb_ads_uid_to_sid;
1591 m->gid_to_sid = pdb_ads_gid_to_sid;
1592 m->sid_to_id = pdb_ads_sid_to_id;
1593 m->rid_algorithm = pdb_ads_rid_algorithm;
1594 m->new_rid = pdb_ads_new_rid;
1595 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1596 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1597 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1598 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1601 static void free_private_data(void **vp)
1603 struct pdb_ads_state *state = talloc_get_type_abort(
1604 *vp, struct pdb_ads_state);
1606 TALLOC_FREE(state->ld);
1610 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1611 const char *location)
1613 const char *rootdse_attrs[2] = {
1614 "defaultNamingContext", "configurationNamingContext" };
1615 const char *domain_attrs[1] = { "objectSid" };
1616 const char *ncname_attrs[1] = { "netbiosname" };
1617 struct tldap_message **rootdse, **domain, **ncname;
1618 TALLOC_CTX *frame = talloc_stackframe();
1619 struct sockaddr_un sunaddr;
1624 ZERO_STRUCT(sunaddr);
1625 sunaddr.sun_family = AF_UNIX;
1626 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1628 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1630 if (!NT_STATUS_IS_OK(status)) {
1631 DEBUG(10, ("Could not connect to %s: %s\n", location,
1632 nt_errstr(status)));
1636 state->ld = tldap_context_create(state, fd);
1637 if (state->ld == NULL) {
1639 status = NT_STATUS_NO_MEMORY;
1643 rc = tldap_search_fmt(
1644 state->ld, "", TLDAP_SCOPE_BASE,
1645 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1646 talloc_tos(), &rootdse, "(objectclass=*)");
1647 if (rc != TLDAP_SUCCESS) {
1648 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1649 tldap_errstr(debug_ctx(), state->ld, rc)));
1650 status = NT_STATUS_LDAP(rc);
1653 if (talloc_array_length(rootdse) != 1) {
1654 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1658 state->domaindn = tldap_talloc_single_attribute(
1659 rootdse[0], "defaultNamingContext", state);
1660 if (state->domaindn == NULL) {
1661 DEBUG(10, ("Could not get defaultNamingContext\n"));
1662 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1665 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1667 state->configdn = tldap_talloc_single_attribute(
1668 rootdse[0], "configurationNamingContext", state);
1669 if (state->domaindn == NULL) {
1670 DEBUG(10, ("Could not get configurationNamingContext\n"));
1671 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1674 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1677 * Figure out our domain's SID
1679 rc = tldap_search_fmt(
1680 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1681 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1682 talloc_tos(), &domain, "(objectclass=*)");
1683 if (rc != TLDAP_SUCCESS) {
1684 DEBUG(10, ("Could not retrieve domain: %s\n",
1685 tldap_errstr(debug_ctx(), state->ld, rc)));
1686 status = NT_STATUS_LDAP(rc);
1690 num_domains = talloc_array_length(domain);
1691 if (num_domains != 1) {
1692 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1693 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1696 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1697 DEBUG(10, ("Could not retrieve domain SID\n"));
1698 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1701 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1704 * Figure out our domain's short name
1706 rc = tldap_search_fmt(
1707 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1708 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1709 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1710 if (rc != TLDAP_SUCCESS) {
1711 DEBUG(10, ("Could not retrieve ncname: %s\n",
1712 tldap_errstr(debug_ctx(), state->ld, rc)));
1713 status = NT_STATUS_LDAP(rc);
1716 if (talloc_array_length(ncname) != 1) {
1717 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1721 state->netbiosname = tldap_talloc_single_attribute(
1722 ncname[0], "netbiosname", state);
1723 if (state->netbiosname == NULL) {
1724 DEBUG(10, ("Could not get netbiosname\n"));
1725 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1728 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1730 if (!strequal(lp_workgroup(), state->netbiosname)) {
1731 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1732 state->netbiosname, lp_workgroup()));
1733 status = NT_STATUS_NO_SUCH_DOMAIN;
1737 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1739 status = NT_STATUS_OK;
1745 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1746 const char *location)
1748 struct pdb_methods *m;
1749 struct pdb_ads_state *state;
1753 m = talloc(talloc_autofree_context(), struct pdb_methods);
1755 return NT_STATUS_NO_MEMORY;
1757 state = talloc(m, struct pdb_ads_state);
1758 if (state == NULL) {
1761 m->private_data = state;
1762 m->free_private_data = free_private_data;
1763 pdb_ads_init_methods(m);
1765 if (location == NULL) {
1766 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1770 if (location == NULL) {
1774 status = pdb_ads_connect(state, location);
1775 if (!NT_STATUS_IS_OK(status)) {
1776 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1781 return NT_STATUS_OK;
1783 status = NT_STATUS_NO_MEMORY;
1789 NTSTATUS pdb_ads_init(void);
1790 NTSTATUS pdb_ads_init(void)
1792 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",