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 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 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 return NT_STATUS_NOT_IMPLEMENTED;
611 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
612 TALLOC_CTX *mem_ctx, uint32 rid)
614 return NT_STATUS_NOT_IMPLEMENTED;
617 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
620 return NT_STATUS_NOT_IMPLEMENTED;
623 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
626 return NT_STATUS_NOT_IMPLEMENTED;
629 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
632 return NT_STATUS_NOT_IMPLEMENTED;
635 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
637 enum lsa_SidType sid_name_use,
639 size_t *p_num_entries,
642 return NT_STATUS_NOT_IMPLEMENTED;
645 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
647 const DOM_SID *group,
648 uint32 **pp_member_rids,
649 size_t *p_num_members)
651 return NT_STATUS_NOT_IMPLEMENTED;
654 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
659 size_t *p_num_groups)
661 struct pdb_ads_state *state = talloc_get_type_abort(
662 m->private_data, struct pdb_ads_state);
663 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
665 const char *attrs[1] = { "objectSid" };
666 struct tldap_message **groups;
669 struct dom_sid *group_sids;
672 rc = tldap_search_fmt(
673 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
674 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
675 "(&(member=%s)(grouptype=%d)(objectclass=group))",
676 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
677 if (rc != TLDAP_SUCCESS) {
678 DEBUG(10, ("ldap_search failed %s\n",
679 tldap_errstr(debug_ctx(), state->ld, rc)));
680 return NT_STATUS_LDAP(rc);
683 count = talloc_array_length(groups);
685 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
686 if (group_sids == NULL) {
687 return NT_STATUS_NO_MEMORY;
689 gids = talloc_array(mem_ctx, gid_t, count);
691 TALLOC_FREE(group_sids);
692 return NT_STATUS_NO_MEMORY;
696 for (i=0; i<count; i++) {
697 if (!tldap_pull_binsid(groups[i], "objectSid",
698 &group_sids[num_groups])) {
701 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
704 if (num_groups == count) {
709 *pp_sids = group_sids;
711 *p_num_groups = num_groups;
715 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
719 return NT_STATUS_NOT_IMPLEMENTED;
722 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
724 uint32 group_rid, uint32 member_rid)
726 return NT_STATUS_NOT_IMPLEMENTED;
729 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
731 uint32 group_rid, uint32 member_rid)
733 return NT_STATUS_NOT_IMPLEMENTED;
736 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
737 const char *name, uint32 *rid)
739 TALLOC_CTX *frame = talloc_stackframe();
740 struct pdb_ads_state *state = talloc_get_type_abort(
741 m->private_data, struct pdb_ads_state);
742 const char *attrs[1] = { "objectSid" };
744 struct tldap_mod *mods = NULL;
745 struct tldap_message **alias;
751 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
755 return NT_STATUS_NO_MEMORY;
758 ok &= tldap_make_mod_fmt(
759 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
761 ok &= tldap_make_mod_fmt(
762 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
763 ok &= tldap_make_mod_fmt(
764 NULL, talloc_tos(), &num_mods, &mods, "groupType",
765 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
769 return NT_STATUS_NO_MEMORY;
772 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
773 if (rc != TLDAP_SUCCESS) {
774 DEBUG(10, ("ldap_add failed %s\n",
775 tldap_errstr(debug_ctx(), state->ld, rc)));
777 return NT_STATUS_LDAP(rc);
780 rc = tldap_search_fmt(
781 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
782 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
783 "(&(objectclass=group)(samaccountname=%s))", name);
784 if (rc != TLDAP_SUCCESS) {
785 DEBUG(10, ("Could not find just created alias %s: %s\n",
786 name, tldap_errstr(debug_ctx(), state->ld, rc)));
788 return NT_STATUS_LDAP(rc);
791 if (talloc_array_length(alias) != 1) {
792 DEBUG(10, ("Got %d alias, expected one\n",
793 (int)talloc_array_length(alias)));
795 return NT_STATUS_LDAP(rc);
798 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
799 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
802 return NT_STATUS_INTERNAL_DB_CORRUPTION;
805 sid_peek_rid(&sid, rid);
810 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
813 return NT_STATUS_NOT_IMPLEMENTED;
816 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
818 struct acct_info *info)
820 return NT_STATUS_NOT_IMPLEMENTED;
823 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
825 struct acct_info *info)
827 return NT_STATUS_NOT_IMPLEMENTED;
830 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
831 const DOM_SID *alias,
832 const DOM_SID *member)
834 return NT_STATUS_NOT_IMPLEMENTED;
837 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
838 const DOM_SID *alias,
839 const DOM_SID *member)
841 return NT_STATUS_NOT_IMPLEMENTED;
844 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
845 const DOM_SID *alias, DOM_SID **members,
846 size_t *p_num_members)
848 return NT_STATUS_NOT_IMPLEMENTED;
851 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
853 const DOM_SID *domain_sid,
854 const DOM_SID *members,
856 uint32 **pp_alias_rids,
857 size_t *p_num_alias_rids)
859 return NT_STATUS_NOT_IMPLEMENTED;
862 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
863 const DOM_SID *domain_sid,
866 const char **pp_names,
867 enum lsa_SidType *attrs)
869 return NT_STATUS_NOT_IMPLEMENTED;
872 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
873 const DOM_SID *domain_sid,
875 const char **pp_names,
877 enum lsa_SidType *attrs)
879 return NT_STATUS_NOT_IMPLEMENTED;
882 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
883 int policy_index, uint32 *value)
885 return account_policy_get(policy_index, value)
886 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
889 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
890 int policy_index, uint32 value)
892 return account_policy_set(policy_index, value)
893 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
896 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
899 return NT_STATUS_NOT_IMPLEMENTED;
902 struct pdb_ads_search_state {
904 struct samr_displayentry *entries;
905 uint32_t num_entries;
910 static bool pdb_ads_next_entry(struct pdb_search *search,
911 struct samr_displayentry *entry)
913 struct pdb_ads_search_state *state = talloc_get_type_abort(
914 search->private_data, struct pdb_ads_search_state);
916 if (state->current == state->num_entries) {
920 entry->idx = state->entries[state->current].idx;
921 entry->rid = state->entries[state->current].rid;
922 entry->acct_flags = state->entries[state->current].acct_flags;
924 entry->account_name = talloc_strdup(
925 search, state->entries[state->current].account_name);
926 entry->fullname = talloc_strdup(
927 search, state->entries[state->current].fullname);
928 entry->description = talloc_strdup(
929 search, state->entries[state->current].description);
931 if ((entry->account_name == NULL) || (entry->fullname == NULL)
932 || (entry->description == NULL)) {
933 DEBUG(0, ("talloc_strdup failed\n"));
941 static void pdb_ads_search_end(struct pdb_search *search)
943 struct pdb_ads_search_state *state = talloc_get_type_abort(
944 search->private_data, struct pdb_ads_search_state);
948 static bool pdb_ads_search_filter(struct pdb_methods *m,
949 struct pdb_search *search,
951 struct pdb_ads_search_state **pstate)
953 struct pdb_ads_state *state = talloc_get_type_abort(
954 m->private_data, struct pdb_ads_state);
955 struct pdb_ads_search_state *sstate;
956 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
957 "userAccountControl", "description" };
958 struct tldap_message **users;
959 int i, rc, num_users;
961 sstate = talloc_zero(search, struct pdb_ads_search_state);
962 if (sstate == NULL) {
966 rc = tldap_search_fmt(
967 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
968 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
970 if (rc != TLDAP_SUCCESS) {
971 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
972 tldap_errstr(debug_ctx(), state->ld, rc)));
976 num_users = talloc_array_length(users);
978 sstate->entries = talloc_array(sstate, struct samr_displayentry,
980 if (sstate->entries == NULL) {
981 DEBUG(10, ("talloc failed\n"));
985 sstate->num_entries = 0;
987 for (i=0; i<num_users; i++) {
988 struct samr_displayentry *e;
991 e = &sstate->entries[sstate->num_entries];
993 e->idx = sstate->num_entries;
994 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
995 DEBUG(10, ("Could not pull sid\n"));
998 sid_peek_rid(&sid, &e->rid);
999 e->acct_flags = ACB_NORMAL;
1000 e->account_name = tldap_talloc_single_attribute(
1001 users[i], "samAccountName", sstate->entries);
1002 if (e->account_name == NULL) {
1005 e->fullname = tldap_talloc_single_attribute(
1006 users[i], "displayName", sstate->entries);
1007 if (e->fullname == NULL) {
1010 e->description = tldap_talloc_single_attribute(
1011 users[i], "description", sstate->entries);
1012 if (e->description == NULL) {
1013 e->description = "";
1016 sstate->num_entries += 1;
1017 if (sstate->num_entries >= num_users) {
1022 search->private_data = sstate;
1023 search->next_entry = pdb_ads_next_entry;
1024 search->search_end = pdb_ads_search_end;
1029 static bool pdb_ads_search_users(struct pdb_methods *m,
1030 struct pdb_search *search,
1033 struct pdb_ads_search_state *sstate;
1036 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1040 sstate->acct_flags = acct_flags;
1044 static bool pdb_ads_search_groups(struct pdb_methods *m,
1045 struct pdb_search *search)
1047 struct pdb_ads_search_state *sstate;
1051 filter = talloc_asprintf(talloc_tos(),
1052 "(&(grouptype=%d)(objectclass=group))",
1053 GTYPE_SECURITY_GLOBAL_GROUP);
1054 if (filter == NULL) {
1057 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1058 TALLOC_FREE(filter);
1062 sstate->acct_flags = 0;
1066 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1067 struct pdb_search *search,
1070 struct pdb_ads_search_state *sstate;
1074 filter = talloc_asprintf(
1075 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1076 sid_check_is_builtin(sid)
1077 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1078 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1080 if (filter == NULL) {
1083 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1084 TALLOC_FREE(filter);
1088 sstate->acct_flags = 0;
1092 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1098 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1101 struct pdb_ads_state *state = talloc_get_type_abort(
1102 m->private_data, struct pdb_ads_state);
1103 sid_compose(sid, &state->domainsid, uid);
1107 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1110 struct pdb_ads_state *state = talloc_get_type_abort(
1111 m->private_data, struct pdb_ads_state);
1112 sid_compose(sid, &state->domainsid, gid);
1116 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1117 union unid_t *id, enum lsa_SidType *type)
1119 struct pdb_ads_state *state = talloc_get_type_abort(
1120 m->private_data, struct pdb_ads_state);
1121 struct tldap_message **msg;
1127 * This is a big, big hack: Just hard-code the rid as uid/gid.
1130 sid_peek_rid(sid, &rid);
1132 sidstr = sid_binstring(talloc_tos(), sid);
1133 if (sidstr == NULL) {
1137 rc = tldap_search_fmt(
1138 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1139 NULL, 0, 0, talloc_tos(), &msg,
1140 "(&(objectsid=%s)(objectclass=user))", sidstr);
1141 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1143 *type = SID_NAME_USER;
1144 TALLOC_FREE(sidstr);
1148 rc = tldap_search_fmt(
1149 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1150 NULL, 0, 0, talloc_tos(), &msg,
1151 "(&(objectsid=%s)(objectclass=group))", sidstr);
1152 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1154 *type = SID_NAME_DOM_GRP;
1155 TALLOC_FREE(sidstr);
1159 TALLOC_FREE(sidstr);
1163 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1168 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1173 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1174 const char *domain, char** pwd,
1176 time_t *pass_last_set_time)
1181 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1182 const char* domain, const char* pwd,
1188 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1194 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1195 TALLOC_CTX *mem_ctx,
1196 uint32 *num_domains,
1197 struct trustdom_info ***domains)
1199 return NT_STATUS_NOT_IMPLEMENTED;
1202 static void pdb_ads_init_methods(struct pdb_methods *m)
1205 m->getsampwnam = pdb_ads_getsampwnam;
1206 m->getsampwsid = pdb_ads_getsampwsid;
1207 m->create_user = pdb_ads_create_user;
1208 m->delete_user = pdb_ads_delete_user;
1209 m->add_sam_account = pdb_ads_add_sam_account;
1210 m->update_sam_account = pdb_ads_update_sam_account;
1211 m->delete_sam_account = pdb_ads_delete_sam_account;
1212 m->rename_sam_account = pdb_ads_rename_sam_account;
1213 m->update_login_attempts = pdb_ads_update_login_attempts;
1214 m->getgrsid = pdb_ads_getgrsid;
1215 m->getgrgid = pdb_ads_getgrgid;
1216 m->getgrnam = pdb_ads_getgrnam;
1217 m->create_dom_group = pdb_ads_create_dom_group;
1218 m->delete_dom_group = pdb_ads_delete_dom_group;
1219 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1220 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1221 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1222 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1223 m->enum_group_members = pdb_ads_enum_group_members;
1224 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1225 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1226 m->add_groupmem = pdb_ads_add_groupmem;
1227 m->del_groupmem = pdb_ads_del_groupmem;
1228 m->create_alias = pdb_ads_create_alias;
1229 m->delete_alias = pdb_ads_delete_alias;
1230 m->get_aliasinfo = pdb_ads_get_aliasinfo;
1231 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1232 m->add_aliasmem = pdb_ads_add_aliasmem;
1233 m->del_aliasmem = pdb_ads_del_aliasmem;
1234 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1235 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1236 m->lookup_rids = pdb_ads_lookup_rids;
1237 m->lookup_names = pdb_ads_lookup_names;
1238 m->get_account_policy = pdb_ads_get_account_policy;
1239 m->set_account_policy = pdb_ads_set_account_policy;
1240 m->get_seq_num = pdb_ads_get_seq_num;
1241 m->search_users = pdb_ads_search_users;
1242 m->search_groups = pdb_ads_search_groups;
1243 m->search_aliases = pdb_ads_search_aliases;
1244 m->uid_to_rid = pdb_ads_uid_to_rid;
1245 m->uid_to_sid = pdb_ads_uid_to_sid;
1246 m->gid_to_sid = pdb_ads_gid_to_sid;
1247 m->sid_to_id = pdb_ads_sid_to_id;
1248 m->rid_algorithm = pdb_ads_rid_algorithm;
1249 m->new_rid = pdb_ads_new_rid;
1250 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1251 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1252 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1253 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1256 static void free_private_data(void **vp)
1258 struct pdb_ads_state *state = talloc_get_type_abort(
1259 *vp, struct pdb_ads_state);
1261 TALLOC_FREE(state->ld);
1265 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1266 const char *location)
1268 const char *rootdse_attrs[2] = {
1269 "defaultNamingContext", "configurationNamingContext" };
1270 const char *domain_attrs[1] = { "objectSid" };
1271 const char *ncname_attrs[1] = { "netbiosname" };
1272 struct tldap_message **rootdse, **domain, **ncname;
1273 TALLOC_CTX *frame = talloc_stackframe();
1274 struct sockaddr_un sunaddr;
1279 ZERO_STRUCT(sunaddr);
1280 sunaddr.sun_family = AF_UNIX;
1281 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1283 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1285 if (!NT_STATUS_IS_OK(status)) {
1286 DEBUG(10, ("Could not connect to %s: %s\n", location,
1287 nt_errstr(status)));
1291 state->ld = tldap_context_create(state, fd);
1292 if (state->ld == NULL) {
1294 status = NT_STATUS_NO_MEMORY;
1298 rc = tldap_search_fmt(
1299 state->ld, "", TLDAP_SCOPE_BASE,
1300 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1301 talloc_tos(), &rootdse, "(objectclass=*)");
1302 if (rc != TLDAP_SUCCESS) {
1303 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1304 tldap_errstr(debug_ctx(), state->ld, rc)));
1305 status = NT_STATUS_LDAP(rc);
1308 if (talloc_array_length(rootdse) != 1) {
1309 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1313 state->domaindn = tldap_talloc_single_attribute(
1314 rootdse[0], "defaultNamingContext", state);
1315 if (state->domaindn == NULL) {
1316 DEBUG(10, ("Could not get defaultNamingContext\n"));
1317 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1320 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1322 state->configdn = tldap_talloc_single_attribute(
1323 rootdse[0], "configurationNamingContext", state);
1324 if (state->domaindn == NULL) {
1325 DEBUG(10, ("Could not get configurationNamingContext\n"));
1326 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1329 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1332 * Figure out our domain's SID
1334 rc = tldap_search_fmt(
1335 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1336 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1337 talloc_tos(), &domain, "(objectclass=*)");
1338 if (rc != TLDAP_SUCCESS) {
1339 DEBUG(10, ("Could not retrieve domain: %s\n",
1340 tldap_errstr(debug_ctx(), state->ld, rc)));
1341 status = NT_STATUS_LDAP(rc);
1345 num_domains = talloc_array_length(domain);
1346 if (num_domains != 1) {
1347 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1348 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1351 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1352 DEBUG(10, ("Could not retrieve domain SID\n"));
1353 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1356 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1359 * Figure out our domain's short name
1361 rc = tldap_search_fmt(
1362 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1363 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1364 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1365 if (rc != TLDAP_SUCCESS) {
1366 DEBUG(10, ("Could not retrieve ncname: %s\n",
1367 tldap_errstr(debug_ctx(), state->ld, rc)));
1368 status = NT_STATUS_LDAP(rc);
1371 if (talloc_array_length(ncname) != 1) {
1372 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1376 state->netbiosname = tldap_talloc_single_attribute(
1377 ncname[0], "netbiosname", state);
1378 if (state->netbiosname == NULL) {
1379 DEBUG(10, ("Could not get netbiosname\n"));
1380 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1383 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1385 if (!strequal(lp_workgroup(), state->netbiosname)) {
1386 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1387 state->netbiosname, lp_workgroup()));
1388 status = NT_STATUS_NO_SUCH_DOMAIN;
1392 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1394 status = NT_STATUS_OK;
1400 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1401 const char *location)
1403 struct pdb_methods *m;
1404 struct pdb_ads_state *state;
1408 m = talloc(talloc_autofree_context(), struct pdb_methods);
1410 return NT_STATUS_NO_MEMORY;
1412 state = talloc(m, struct pdb_ads_state);
1413 if (state == NULL) {
1416 m->private_data = state;
1417 m->free_private_data = free_private_data;
1418 pdb_ads_init_methods(m);
1420 if (location == NULL) {
1421 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1425 if (location == NULL) {
1429 status = pdb_ads_connect(state, location);
1430 if (!NT_STATUS_IS_OK(status)) {
1431 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1436 return NT_STATUS_OK;
1438 status = NT_STATUS_NO_MEMORY;
1444 NTSTATUS pdb_ads_init(void);
1445 NTSTATUS pdb_ads_init(void)
1447 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",