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,
26 struct pdb_ads_state {
27 struct tldap_context *ld;
28 struct dom_sid domainsid;
34 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
39 if (!tldap_pull_uint64(msg, attr, &tmp)) {
42 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
46 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
49 sid_peek_rid(sid, &rid);
53 struct pdb_ads_samu_private {
55 struct tldap_message *ldapmsg;
58 static struct samu *pdb_ads_init_guest(TALLOC_CTX *mem_ctx,
59 struct pdb_methods *m)
61 struct pdb_ads_state *state = talloc_get_type_abort(
62 m->private_data, struct pdb_ads_state);
63 struct dom_sid guest_sid;
67 sid_compose(&guest_sid, &state->domainsid, DOMAIN_USER_RID_GUEST);
69 guest = samu_new(mem_ctx);
74 status = pdb_ads_getsampwsid(m, guest, &guest_sid);
75 if (!NT_STATUS_IS_OK(status)) {
76 DEBUG(10, ("Could not init guest account: %s\n",
84 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
85 struct pdb_methods *m, struct samu *sam)
87 struct pdb_ads_samu_private *result;
90 result = (struct pdb_ads_samu_private *)
91 pdb_get_backend_private_data(sam, m);
94 return talloc_get_type_abort(
95 result, struct pdb_ads_samu_private);
99 * This is now a weirdness of the passdb API. For the guest user we
100 * are not asked first.
102 sid_peek_rid(pdb_get_user_sid(sam), &rid);
104 if (rid == DOMAIN_USER_RID_GUEST) {
105 struct samu *guest = pdb_ads_init_guest(talloc_tos(), m);
110 result = talloc_get_type_abort(
111 pdb_get_backend_private_data(guest, m),
112 struct pdb_ads_samu_private);
113 pdb_set_backend_private_data(
114 sam, talloc_move(sam, &result), NULL, m, PDB_SET);
116 return talloc_get_type_abort(
117 pdb_get_backend_private_data(sam, m),
118 struct pdb_ads_samu_private);
124 static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m,
126 struct tldap_message *entry)
128 struct pdb_ads_state *state = talloc_get_type_abort(
129 m->private_data, struct pdb_ads_state);
130 TALLOC_CTX *frame = talloc_stackframe();
131 struct pdb_ads_samu_private *priv;
132 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
139 priv = talloc(sam, struct pdb_ads_samu_private);
141 return NT_STATUS_NO_MEMORY;
143 if (!tldap_entry_dn(entry, &priv->dn)) {
145 return NT_STATUS_INTERNAL_DB_CORRUPTION;
148 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
150 DEBUG(10, ("no samAccountName\n"));
153 pdb_set_username(sam, str, PDB_SET);
156 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
157 pdb_set_logon_time(sam, tmp_time, PDB_SET);
159 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
160 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
162 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
163 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
165 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
166 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
169 str = tldap_talloc_single_attribute(entry, "samAccoutName",
172 pdb_set_username(sam, str, PDB_SET);
175 str = tldap_talloc_single_attribute(entry, "displayName",
178 pdb_set_fullname(sam, str, PDB_SET);
181 str = tldap_talloc_single_attribute(entry, "homeDirectory",
184 pdb_set_homedir(sam, str, PDB_SET);
187 str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
189 pdb_set_dir_drive(sam, str, PDB_SET);
192 str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
194 pdb_set_logon_script(sam, str, PDB_SET);
197 str = tldap_talloc_single_attribute(entry, "profilePath",
200 pdb_set_profile_path(sam, str, PDB_SET);
203 str = tldap_talloc_single_attribute(entry, "profilePath",
206 pdb_set_profile_path(sam, str, PDB_SET);
209 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
210 DEBUG(10, ("Could not pull SID\n"));
213 pdb_set_user_sid(sam, &sid, PDB_SET);
215 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
216 DEBUG(10, ("Could not pull userAccountControl\n"));
219 pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET);
221 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
222 if (blob.length != NT_HASH_LEN) {
223 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
224 (int)blob.length, NT_HASH_LEN));
227 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
230 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
231 if (blob.length != LM_HASH_LEN) {
232 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
233 (int)blob.length, LM_HASH_LEN));
236 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
239 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
240 sid_compose(&sid, &state->domainsid, n);
241 pdb_set_group_sid(sam, &sid, PDB_SET);
245 priv->ldapmsg = talloc_move(priv, &entry);
246 pdb_set_backend_private_data(sam, priv, NULL, m, PDB_SET);
248 status = NT_STATUS_OK;
254 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
255 struct tldap_message *existing,
257 int *pnum_mods, struct tldap_mod **pmods,
262 /* TODO: All fields :-) */
264 ret &= tldap_make_mod_fmt(
265 existing, mem_ctx, pnum_mods, pmods, "displayName",
266 pdb_get_fullname(sam));
268 ret &= tldap_make_mod_blob(
269 existing, mem_ctx, pnum_mods, pmods, "unicodePwd",
270 data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN));
272 ret &= tldap_make_mod_blob(
273 existing, mem_ctx, pnum_mods, pmods, "dBCSPwd",
274 data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN));
279 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
280 struct pdb_ads_state *state,
281 struct samu *sam_acct,
284 const char * attrs[] = {
285 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
286 "sAMAccountName", "displayName", "homeDirectory",
287 "homeDrive", "scriptPath", "profilePath", "description",
288 "userWorkstations", "comment", "userParameters", "objectSid",
289 "primaryGroupID", "userAccountControl", "logonHours",
290 "badPwdCount", "logonCount", "countryCode", "codePage",
291 "unicodePwd", "dBCSPwd" };
292 struct tldap_message **users;
295 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
296 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
298 if (rc != TLDAP_SUCCESS) {
299 DEBUG(10, ("ldap_search failed %s\n",
300 tldap_errstr(debug_ctx(), state->ld, rc)));
301 return NT_STATUS_LDAP(rc);
304 count = talloc_array_length(users);
306 DEBUG(10, ("Expected 1 user, got %d\n", count));
307 return NT_STATUS_INTERNAL_DB_CORRUPTION;
310 return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]);
313 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
314 struct samu *sam_acct,
315 const char *username)
317 struct pdb_ads_state *state = talloc_get_type_abort(
318 m->private_data, struct pdb_ads_state);
321 filter = talloc_asprintf(
322 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
324 NT_STATUS_HAVE_NO_MEMORY(filter);
326 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
329 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
330 struct samu *sam_acct,
333 struct pdb_ads_state *state = talloc_get_type_abort(
334 m->private_data, struct pdb_ads_state);
335 char *sidstr, *filter;
337 sidstr = sid_binstring(talloc_tos(), sid);
338 NT_STATUS_HAVE_NO_MEMORY(sidstr);
340 filter = talloc_asprintf(
341 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
343 NT_STATUS_HAVE_NO_MEMORY(filter);
345 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
348 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
350 const char *name, uint32 acct_flags,
353 struct pdb_ads_state *state = talloc_get_type_abort(
354 m->private_data, struct pdb_ads_state);
355 const char *attrs[1] = { "objectSid" };
356 struct tldap_mod *mods = NULL;
358 struct tldap_message **user;
364 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
367 return NT_STATUS_NO_MEMORY;
370 /* TODO: Create machines etc */
373 ok &= tldap_make_mod_fmt(
374 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
375 ok &= tldap_make_mod_fmt(
376 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
379 return NT_STATUS_NO_MEMORY;
382 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
383 if (rc != TLDAP_SUCCESS) {
384 DEBUG(10, ("ldap_add failed %s\n",
385 tldap_errstr(debug_ctx(), state->ld, rc)));
387 return NT_STATUS_LDAP(rc);
390 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
391 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &user,
392 "(&(objectclass=user)(samaccountname=%s))",
394 if (rc != TLDAP_SUCCESS) {
395 DEBUG(10, ("Could not find just created user %s: %s\n",
396 name, tldap_errstr(debug_ctx(), state->ld, rc)));
398 return NT_STATUS_LDAP(rc);
401 if (talloc_array_length(user) != 1) {
402 DEBUG(10, ("Got %d users, expected one\n",
403 (int)talloc_array_length(user)));
405 return NT_STATUS_LDAP(rc);
408 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
409 DEBUG(10, ("Could not fetch objectSid from user %s\n",
412 return NT_STATUS_INTERNAL_DB_CORRUPTION;
415 sid_peek_rid(&sid, rid);
420 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
424 struct pdb_ads_state *state = talloc_get_type_abort(
425 m->private_data, struct pdb_ads_state);
426 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
429 rc = tldap_delete(state->ld, priv->dn, NULL, NULL);
430 if (rc != TLDAP_SUCCESS) {
431 DEBUG(10, ("ldap_delete for %s failed: %s\n", priv->dn,
432 tldap_errstr(debug_ctx(), state->ld, rc)));
433 return NT_STATUS_LDAP(rc);
438 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
439 struct samu *sampass)
441 return NT_STATUS_NOT_IMPLEMENTED;
444 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
447 struct pdb_ads_state *state = talloc_get_type_abort(
448 m->private_data, struct pdb_ads_state);
449 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
450 struct tldap_mod *mods = NULL;
451 int rc, num_mods = 0;
453 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
454 &num_mods, &mods, sam)) {
455 return NT_STATUS_NO_MEMORY;
458 rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, NULL);
459 if (rc != TLDAP_SUCCESS) {
460 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
461 tldap_errstr(debug_ctx(), state->ld, rc)));
462 return NT_STATUS_LDAP(rc);
470 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
471 struct samu *username)
473 return NT_STATUS_NOT_IMPLEMENTED;
476 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
477 struct samu *oldname,
480 return NT_STATUS_NOT_IMPLEMENTED;
483 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
484 struct samu *sam_acct,
487 return NT_STATUS_NOT_IMPLEMENTED;
490 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
493 return NT_STATUS_NOT_IMPLEMENTED;
496 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
499 return NT_STATUS_NOT_IMPLEMENTED;
502 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
505 return NT_STATUS_NOT_IMPLEMENTED;
508 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
509 TALLOC_CTX *mem_ctx, const char *name,
512 return NT_STATUS_NOT_IMPLEMENTED;
515 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
516 TALLOC_CTX *mem_ctx, uint32 rid)
518 return NT_STATUS_NOT_IMPLEMENTED;
521 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
524 return NT_STATUS_NOT_IMPLEMENTED;
527 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
530 return NT_STATUS_NOT_IMPLEMENTED;
533 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
536 return NT_STATUS_NOT_IMPLEMENTED;
539 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
541 enum lsa_SidType sid_name_use,
543 size_t *p_num_entries,
546 return NT_STATUS_NOT_IMPLEMENTED;
549 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
551 const DOM_SID *group,
552 uint32 **pp_member_rids,
553 size_t *p_num_members)
555 return NT_STATUS_NOT_IMPLEMENTED;
558 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
563 size_t *p_num_groups)
565 struct pdb_ads_state *state = talloc_get_type_abort(
566 m->private_data, struct pdb_ads_state);
567 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
569 const char *attrs[1] = { "objectSid" };
570 struct tldap_message **groups;
573 struct dom_sid *group_sids;
576 rc = tldap_search_fmt(
577 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
578 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
579 "(&(member=%s)(grouptype=%d)(objectclass=group))",
580 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
581 if (rc != TLDAP_SUCCESS) {
582 DEBUG(10, ("ldap_search failed %s\n",
583 tldap_errstr(debug_ctx(), state->ld, rc)));
584 return NT_STATUS_LDAP(rc);
587 count = talloc_array_length(groups);
589 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
590 if (group_sids == NULL) {
591 return NT_STATUS_NO_MEMORY;
593 gids = talloc_array(mem_ctx, gid_t, count);
595 TALLOC_FREE(group_sids);
596 return NT_STATUS_NO_MEMORY;
600 for (i=0; i<count; i++) {
601 if (!tldap_pull_binsid(groups[i], "objectSid",
602 &group_sids[num_groups])) {
605 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
608 if (num_groups == count) {
613 *pp_sids = group_sids;
615 *p_num_groups = num_groups;
619 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
623 return NT_STATUS_NOT_IMPLEMENTED;
626 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
628 uint32 group_rid, uint32 member_rid)
630 return NT_STATUS_NOT_IMPLEMENTED;
633 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
635 uint32 group_rid, uint32 member_rid)
637 return NT_STATUS_NOT_IMPLEMENTED;
640 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
641 const char *name, uint32 *rid)
643 TALLOC_CTX *frame = talloc_stackframe();
644 struct pdb_ads_state *state = talloc_get_type_abort(
645 m->private_data, struct pdb_ads_state);
646 const char *attrs[1] = { "objectSid" };
648 struct tldap_mod *mods = NULL;
649 struct tldap_message **alias;
655 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
659 return NT_STATUS_NO_MEMORY;
662 ok &= tldap_make_mod_fmt(
663 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
665 ok &= tldap_make_mod_fmt(
666 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
667 ok &= tldap_make_mod_fmt(
668 NULL, talloc_tos(), &num_mods, &mods, "groupType",
669 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
673 return NT_STATUS_NO_MEMORY;
676 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
677 if (rc != TLDAP_SUCCESS) {
678 DEBUG(10, ("ldap_add failed %s\n",
679 tldap_errstr(debug_ctx(), state->ld, rc)));
681 return NT_STATUS_LDAP(rc);
684 rc = tldap_search_fmt(
685 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
686 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
687 "(&(objectclass=group)(samaccountname=%s))", name);
688 if (rc != TLDAP_SUCCESS) {
689 DEBUG(10, ("Could not find just created alias %s: %s\n",
690 name, tldap_errstr(debug_ctx(), state->ld, rc)));
692 return NT_STATUS_LDAP(rc);
695 if (talloc_array_length(alias) != 1) {
696 DEBUG(10, ("Got %d alias, expected one\n",
697 (int)talloc_array_length(alias)));
699 return NT_STATUS_LDAP(rc);
702 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
703 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
706 return NT_STATUS_INTERNAL_DB_CORRUPTION;
709 sid_peek_rid(&sid, rid);
714 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
717 return NT_STATUS_NOT_IMPLEMENTED;
720 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
722 struct acct_info *info)
724 return NT_STATUS_NOT_IMPLEMENTED;
727 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
729 struct acct_info *info)
731 return NT_STATUS_NOT_IMPLEMENTED;
734 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
735 const DOM_SID *alias,
736 const DOM_SID *member)
738 return NT_STATUS_NOT_IMPLEMENTED;
741 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
742 const DOM_SID *alias,
743 const DOM_SID *member)
745 return NT_STATUS_NOT_IMPLEMENTED;
748 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
749 const DOM_SID *alias, DOM_SID **members,
750 size_t *p_num_members)
752 return NT_STATUS_NOT_IMPLEMENTED;
755 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
757 const DOM_SID *domain_sid,
758 const DOM_SID *members,
760 uint32 **pp_alias_rids,
761 size_t *p_num_alias_rids)
763 return NT_STATUS_NOT_IMPLEMENTED;
766 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
767 const DOM_SID *domain_sid,
770 const char **pp_names,
771 enum lsa_SidType *attrs)
773 return NT_STATUS_NOT_IMPLEMENTED;
776 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
777 const DOM_SID *domain_sid,
779 const char **pp_names,
781 enum lsa_SidType *attrs)
783 return NT_STATUS_NOT_IMPLEMENTED;
786 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
787 int policy_index, uint32 *value)
789 return account_policy_get(policy_index, value)
790 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
793 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
794 int policy_index, uint32 value)
796 return account_policy_set(policy_index, value)
797 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
800 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
803 return NT_STATUS_NOT_IMPLEMENTED;
806 struct pdb_ads_search_state {
808 struct samr_displayentry *entries;
809 uint32_t num_entries;
814 static bool pdb_ads_next_entry(struct pdb_search *search,
815 struct samr_displayentry *entry)
817 struct pdb_ads_search_state *state = talloc_get_type_abort(
818 search->private_data, struct pdb_ads_search_state);
820 if (state->current == state->num_entries) {
824 entry->idx = state->entries[state->current].idx;
825 entry->rid = state->entries[state->current].rid;
826 entry->acct_flags = state->entries[state->current].acct_flags;
828 entry->account_name = talloc_strdup(
829 search, state->entries[state->current].account_name);
830 entry->fullname = talloc_strdup(
831 search, state->entries[state->current].fullname);
832 entry->description = talloc_strdup(
833 search, state->entries[state->current].description);
835 if ((entry->account_name == NULL) || (entry->fullname == NULL)
836 || (entry->description == NULL)) {
837 DEBUG(0, ("talloc_strdup failed\n"));
845 static void pdb_ads_search_end(struct pdb_search *search)
847 struct pdb_ads_search_state *state = talloc_get_type_abort(
848 search->private_data, struct pdb_ads_search_state);
852 static bool pdb_ads_search_users(struct pdb_methods *m,
853 struct pdb_search *search,
856 struct pdb_ads_state *state = talloc_get_type_abort(
857 m->private_data, struct pdb_ads_state);
858 struct pdb_ads_search_state *sstate;
859 const char * attrs[] = { "objectSid", "sAMAccountName",
860 "userAccountControl" };
861 struct tldap_message **users;
862 int i, rc, num_users;
864 sstate = talloc_zero(search, struct pdb_ads_search_state);
865 if (sstate == NULL) {
868 sstate->acct_flags = acct_flags;
870 rc = tldap_search_fmt(
871 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
872 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
873 "(objectclass=user)");
874 if (rc != TLDAP_SUCCESS) {
875 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
876 tldap_errstr(debug_ctx(), state->ld, rc)));
880 num_users = talloc_array_length(users);
882 sstate->entries = talloc_array(sstate, struct samr_displayentry,
884 if (sstate->entries == NULL) {
885 DEBUG(10, ("talloc failed\n"));
889 sstate->num_entries = 0;
891 for (i=0; i<num_users; i++) {
892 struct samr_displayentry *e;
895 e = &sstate->entries[sstate->num_entries];
897 e->idx = sstate->num_entries;
898 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
899 DEBUG(10, ("Could not pull sid\n"));
902 sid_peek_rid(&sid, &e->rid);
903 e->acct_flags = ACB_NORMAL;
904 e->account_name = "Name";
905 e->fullname = "Full Name";
906 e->description = "Beschreibung";
908 sstate->num_entries += 1;
909 if (sstate->num_entries >= num_users) {
914 search->private_data = sstate;
915 search->next_entry = pdb_ads_next_entry;
916 search->search_end = pdb_ads_search_end;
920 static bool pdb_ads_search_groups(struct pdb_methods *m,
921 struct pdb_search *search)
926 static bool pdb_ads_search_aliases(struct pdb_methods *m,
927 struct pdb_search *search,
933 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
939 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
945 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
951 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
952 union unid_t *id, enum lsa_SidType *type)
954 struct pdb_ads_state *state = talloc_get_type_abort(
955 m->private_data, struct pdb_ads_state);
956 struct tldap_message **msg;
962 * This is a big, big hack: Just hard-code the rid as uid/gid.
965 sid_peek_rid(sid, &rid);
967 sidstr = sid_binstring(talloc_tos(), sid);
968 if (sidstr == NULL) {
972 rc = tldap_search_fmt(
973 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
974 NULL, 0, 0, talloc_tos(), &msg,
975 "(&(objectsid=%s)(objectclass=user))", sidstr);
976 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
978 *type = SID_NAME_USER;
983 rc = tldap_search_fmt(
984 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
985 NULL, 0, 0, talloc_tos(), &msg,
986 "(&(objectsid=%s)(objectclass=group))", sidstr);
987 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
989 *type = SID_NAME_DOM_GRP;
998 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1003 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1008 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1009 const char *domain, char** pwd,
1011 time_t *pass_last_set_time)
1016 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1017 const char* domain, const char* pwd,
1023 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1029 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1030 TALLOC_CTX *mem_ctx,
1031 uint32 *num_domains,
1032 struct trustdom_info ***domains)
1034 return NT_STATUS_NOT_IMPLEMENTED;
1037 static void pdb_ads_init_methods(struct pdb_methods *m)
1040 m->getsampwnam = pdb_ads_getsampwnam;
1041 m->getsampwsid = pdb_ads_getsampwsid;
1042 m->create_user = pdb_ads_create_user;
1043 m->delete_user = pdb_ads_delete_user;
1044 m->add_sam_account = pdb_ads_add_sam_account;
1045 m->update_sam_account = pdb_ads_update_sam_account;
1046 m->delete_sam_account = pdb_ads_delete_sam_account;
1047 m->rename_sam_account = pdb_ads_rename_sam_account;
1048 m->update_login_attempts = pdb_ads_update_login_attempts;
1049 m->getgrsid = pdb_ads_getgrsid;
1050 m->getgrgid = pdb_ads_getgrgid;
1051 m->getgrnam = pdb_ads_getgrnam;
1052 m->create_dom_group = pdb_ads_create_dom_group;
1053 m->delete_dom_group = pdb_ads_delete_dom_group;
1054 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1055 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1056 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1057 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1058 m->enum_group_members = pdb_ads_enum_group_members;
1059 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1060 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1061 m->add_groupmem = pdb_ads_add_groupmem;
1062 m->del_groupmem = pdb_ads_del_groupmem;
1063 m->create_alias = pdb_ads_create_alias;
1064 m->delete_alias = pdb_ads_delete_alias;
1065 m->get_aliasinfo = pdb_ads_get_aliasinfo;
1066 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1067 m->add_aliasmem = pdb_ads_add_aliasmem;
1068 m->del_aliasmem = pdb_ads_del_aliasmem;
1069 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1070 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1071 m->lookup_rids = pdb_ads_lookup_rids;
1072 m->lookup_names = pdb_ads_lookup_names;
1073 m->get_account_policy = pdb_ads_get_account_policy;
1074 m->set_account_policy = pdb_ads_set_account_policy;
1075 m->get_seq_num = pdb_ads_get_seq_num;
1076 m->search_users = pdb_ads_search_users;
1077 m->search_groups = pdb_ads_search_groups;
1078 m->search_aliases = pdb_ads_search_aliases;
1079 m->uid_to_rid = pdb_ads_uid_to_rid;
1080 m->uid_to_sid = pdb_ads_uid_to_sid;
1081 m->gid_to_sid = pdb_ads_gid_to_sid;
1082 m->sid_to_id = pdb_ads_sid_to_id;
1083 m->rid_algorithm = pdb_ads_rid_algorithm;
1084 m->new_rid = pdb_ads_new_rid;
1085 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1086 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1087 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1088 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1091 static void free_private_data(void **vp)
1093 struct pdb_ads_state *state = talloc_get_type_abort(
1094 *vp, struct pdb_ads_state);
1096 TALLOC_FREE(state->ld);
1100 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1101 const char *location)
1103 const char *rootdse_attrs[2] = {
1104 "defaultNamingContext", "configurationNamingContext" };
1105 const char *domain_attrs[1] = { "objectSid" };
1106 const char *ncname_attrs[1] = { "netbiosname" };
1107 struct tldap_message **rootdse, **domain, **ncname;
1108 TALLOC_CTX *frame = talloc_stackframe();
1109 struct sockaddr_un sunaddr;
1114 ZERO_STRUCT(sunaddr);
1115 sunaddr.sun_family = AF_UNIX;
1116 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1118 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1120 if (!NT_STATUS_IS_OK(status)) {
1121 DEBUG(10, ("Could not connect to %s: %s\n", location,
1122 nt_errstr(status)));
1126 state->ld = tldap_context_create(state, fd);
1127 if (state->ld == NULL) {
1129 status = NT_STATUS_NO_MEMORY;
1133 rc = tldap_search_fmt(
1134 state->ld, "", TLDAP_SCOPE_BASE,
1135 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1136 talloc_tos(), &rootdse, "(objectclass=*)");
1137 if (rc != TLDAP_SUCCESS) {
1138 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1139 tldap_errstr(debug_ctx(), state->ld, rc)));
1140 status = NT_STATUS_LDAP(rc);
1143 if (talloc_array_length(rootdse) != 1) {
1144 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1148 state->domaindn = tldap_talloc_single_attribute(
1149 rootdse[0], "defaultNamingContext", state);
1150 if (state->domaindn == NULL) {
1151 DEBUG(10, ("Could not get defaultNamingContext\n"));
1152 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1155 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1157 state->configdn = tldap_talloc_single_attribute(
1158 rootdse[0], "configurationNamingContext", state);
1159 if (state->domaindn == NULL) {
1160 DEBUG(10, ("Could not get configurationNamingContext\n"));
1161 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1164 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1167 * Figure out our domain's SID
1169 rc = tldap_search_fmt(
1170 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1171 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1172 talloc_tos(), &domain, "(objectclass=*)");
1173 if (rc != TLDAP_SUCCESS) {
1174 DEBUG(10, ("Could not retrieve domain: %s\n",
1175 tldap_errstr(debug_ctx(), state->ld, rc)));
1176 status = NT_STATUS_LDAP(rc);
1180 num_domains = talloc_array_length(domain);
1181 if (num_domains != 1) {
1182 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1183 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1186 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1187 DEBUG(10, ("Could not retrieve domain SID\n"));
1188 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1191 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1194 * Figure out our domain's short name
1196 rc = tldap_search_fmt(
1197 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1198 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1199 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1200 if (rc != TLDAP_SUCCESS) {
1201 DEBUG(10, ("Could not retrieve ncname: %s\n",
1202 tldap_errstr(debug_ctx(), state->ld, rc)));
1203 status = NT_STATUS_LDAP(rc);
1206 if (talloc_array_length(ncname) != 1) {
1207 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1211 state->netbiosname = tldap_talloc_single_attribute(
1212 ncname[0], "netbiosname", state);
1213 if (state->netbiosname == NULL) {
1214 DEBUG(10, ("Could not get netbiosname\n"));
1215 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1218 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1220 if (!strequal(lp_workgroup(), state->netbiosname)) {
1221 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1222 state->netbiosname, lp_workgroup()));
1223 status = NT_STATUS_NO_SUCH_DOMAIN;
1227 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1229 status = NT_STATUS_OK;
1235 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1236 const char *location)
1238 struct pdb_methods *m;
1239 struct pdb_ads_state *state;
1243 m = talloc(talloc_autofree_context(), struct pdb_methods);
1245 return NT_STATUS_NO_MEMORY;
1247 state = talloc(m, struct pdb_ads_state);
1248 if (state == NULL) {
1251 m->private_data = state;
1252 m->free_private_data = free_private_data;
1253 pdb_ads_init_methods(m);
1255 if (location == NULL) {
1256 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1260 if (location == NULL) {
1264 status = pdb_ads_connect(state, location);
1265 if (!NT_STATUS_IS_OK(status)) {
1266 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1271 return NT_STATUS_OK;
1273 status = NT_STATUS_NO_MEMORY;
1279 NTSTATUS pdb_ads_init(void);
1280 NTSTATUS pdb_ads_init(void)
1282 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",