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 struct pdb_ads_state *state = talloc_get_type_abort(
685 m->private_data, struct pdb_ads_state);
688 struct tldap_message **msg;
692 sid_compose(&sid, &state->domainsid, rid);
694 sidstr = sid_binstring(talloc_tos(), &sid);
695 NT_STATUS_HAVE_NO_MEMORY(sidstr);
697 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
698 NULL, 0, 0, talloc_tos(), &msg,
699 ("(&(objectSid=%s)(objectClass=group))"),
702 if (rc != TLDAP_SUCCESS) {
703 DEBUG(10, ("ldap_search failed %s\n",
704 tldap_errstr(debug_ctx(), state->ld, rc)));
705 return NT_STATUS_LDAP(rc);
708 switch talloc_array_length(msg) {
710 return NT_STATUS_NO_SUCH_GROUP;
714 return NT_STATUS_INTERNAL_DB_CORRUPTION;
717 if (!tldap_entry_dn(msg[0], &dn)) {
718 return NT_STATUS_INTERNAL_DB_CORRUPTION;
721 rc = tldap_delete(state->ld, dn, NULL, NULL);
722 if (rc != TLDAP_SUCCESS) {
723 DEBUG(10, ("ldap_delete failed: %s\n",
724 tldap_errstr(debug_ctx(), state->ld, rc)));
726 return NT_STATUS_LDAP(rc);
733 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
736 return NT_STATUS_NOT_IMPLEMENTED;
739 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
742 return NT_STATUS_NOT_IMPLEMENTED;
745 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
748 return NT_STATUS_NOT_IMPLEMENTED;
751 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
753 enum lsa_SidType sid_name_use,
755 size_t *p_num_entries,
758 return NT_STATUS_NOT_IMPLEMENTED;
761 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
763 const DOM_SID *group,
765 size_t *pnum_members)
767 struct pdb_ads_state *state = talloc_get_type_abort(
768 m->private_data, struct pdb_ads_state);
769 const char *attrs[1] = { "member" };
771 struct tldap_message **msg;
772 int i, rc, num_members;
776 sidstr = sid_binstring(talloc_tos(), group);
777 NT_STATUS_HAVE_NO_MEMORY(sidstr);
779 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
780 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
781 "(objectsid=%s)", sidstr);
783 if (rc != TLDAP_SUCCESS) {
784 DEBUG(10, ("ldap_search failed %s\n",
785 tldap_errstr(debug_ctx(), state->ld, rc)));
786 return NT_STATUS_LDAP(rc);
788 switch talloc_array_length(msg) {
790 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
795 return NT_STATUS_INTERNAL_DB_CORRUPTION;
799 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
800 return NT_STATUS_INTERNAL_DB_CORRUPTION;
803 members = talloc_array(mem_ctx, uint32_t, num_members);
804 if (members == NULL) {
805 return NT_STATUS_NO_MEMORY;
808 for (i=0; i<num_members; i++) {
810 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &sid)
811 || !sid_peek_rid(&sid, &members[i])) {
812 TALLOC_FREE(members);
813 return NT_STATUS_INTERNAL_DB_CORRUPTION;
818 *pnum_members = num_members;
822 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
827 size_t *p_num_groups)
829 struct pdb_ads_state *state = talloc_get_type_abort(
830 m->private_data, struct pdb_ads_state);
831 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
833 const char *attrs[1] = { "objectSid" };
834 struct tldap_message **groups;
837 struct dom_sid *group_sids;
840 rc = tldap_search_fmt(
841 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
842 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
843 "(&(member=%s)(grouptype=%d)(objectclass=group))",
844 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
845 if (rc != TLDAP_SUCCESS) {
846 DEBUG(10, ("ldap_search failed %s\n",
847 tldap_errstr(debug_ctx(), state->ld, rc)));
848 return NT_STATUS_LDAP(rc);
851 count = talloc_array_length(groups);
853 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
854 if (group_sids == NULL) {
855 return NT_STATUS_NO_MEMORY;
857 gids = talloc_array(mem_ctx, gid_t, count);
859 TALLOC_FREE(group_sids);
860 return NT_STATUS_NO_MEMORY;
864 for (i=0; i<count; i++) {
865 if (!tldap_pull_binsid(groups[i], "objectSid",
866 &group_sids[num_groups])) {
869 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
872 if (num_groups == count) {
877 *pp_sids = group_sids;
879 *p_num_groups = num_groups;
883 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
887 return NT_STATUS_NOT_IMPLEMENTED;
890 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
892 uint32 group_rid, uint32 member_rid)
894 return NT_STATUS_NOT_IMPLEMENTED;
897 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
899 uint32 group_rid, uint32 member_rid)
901 return NT_STATUS_NOT_IMPLEMENTED;
904 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
905 const char *name, uint32 *rid)
907 TALLOC_CTX *frame = talloc_stackframe();
908 struct pdb_ads_state *state = talloc_get_type_abort(
909 m->private_data, struct pdb_ads_state);
910 const char *attrs[1] = { "objectSid" };
912 struct tldap_mod *mods = NULL;
913 struct tldap_message **alias;
919 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
923 return NT_STATUS_NO_MEMORY;
926 ok &= tldap_make_mod_fmt(
927 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
929 ok &= tldap_make_mod_fmt(
930 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
931 ok &= tldap_make_mod_fmt(
932 NULL, talloc_tos(), &num_mods, &mods, "groupType",
933 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
937 return NT_STATUS_NO_MEMORY;
940 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
941 if (rc != TLDAP_SUCCESS) {
942 DEBUG(10, ("ldap_add failed %s\n",
943 tldap_errstr(debug_ctx(), state->ld, rc)));
945 return NT_STATUS_LDAP(rc);
948 rc = tldap_search_fmt(
949 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
950 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
951 "(&(objectclass=group)(samaccountname=%s))", name);
952 if (rc != TLDAP_SUCCESS) {
953 DEBUG(10, ("Could not find just created alias %s: %s\n",
954 name, tldap_errstr(debug_ctx(), state->ld, rc)));
956 return NT_STATUS_LDAP(rc);
959 if (talloc_array_length(alias) != 1) {
960 DEBUG(10, ("Got %d alias, expected one\n",
961 (int)talloc_array_length(alias)));
963 return NT_STATUS_LDAP(rc);
966 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
967 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
970 return NT_STATUS_INTERNAL_DB_CORRUPTION;
973 sid_peek_rid(&sid, rid);
978 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
981 struct pdb_ads_state *state = talloc_get_type_abort(
982 m->private_data, struct pdb_ads_state);
983 struct tldap_message **alias;
987 sidstr = sid_binstring(talloc_tos(), sid);
988 if (sidstr == NULL) {
989 return NT_STATUS_NO_MEMORY;
992 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
993 NULL, 0, 0, talloc_tos(), &alias,
994 "(&(objectSid=%s)(objectclass=group)"
995 "(|(grouptype=%d)(grouptype=%d)))",
996 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
997 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
999 if (rc != TLDAP_SUCCESS) {
1000 DEBUG(10, ("ldap_search failed: %s\n",
1001 tldap_errstr(debug_ctx(), state->ld, rc)));
1003 return NT_STATUS_LDAP(rc);
1005 if (talloc_array_length(alias) != 1) {
1006 DEBUG(10, ("Expected 1 alias, got %d\n",
1007 (int)talloc_array_length(alias)));
1008 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1010 if (!tldap_entry_dn(alias[0], &dn)) {
1011 DEBUG(10, ("Could not get DN for alias %s\n",
1012 sid_string_dbg(sid)));
1013 return NT_STATUS_INTERNAL_ERROR;
1016 rc = tldap_delete(state->ld, dn, NULL, NULL);
1017 if (rc != TLDAP_SUCCESS) {
1018 DEBUG(10, ("ldap_delete failed: %s\n",
1019 tldap_errstr(debug_ctx(), state->ld, rc)));
1021 return NT_STATUS_LDAP(rc);
1024 return NT_STATUS_OK;
1027 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
1029 struct acct_info *info)
1031 return NT_STATUS_NOT_IMPLEMENTED;
1034 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1036 struct acct_info *info)
1038 return NT_STATUS_NOT_IMPLEMENTED;
1041 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1042 const struct dom_sid *sid,
1043 TALLOC_CTX *mem_ctx, char **pdn)
1045 struct tldap_message **msg;
1049 sidstr = sid_binstring(talloc_tos(), sid);
1050 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1052 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1053 NULL, 0, 0, talloc_tos(), &msg,
1054 "(objectsid=%s)", sidstr);
1055 TALLOC_FREE(sidstr);
1056 if (rc != TLDAP_SUCCESS) {
1057 DEBUG(10, ("ldap_search failed %s\n",
1058 tldap_errstr(debug_ctx(), state->ld, rc)));
1059 return NT_STATUS_LDAP(rc);
1062 switch talloc_array_length(msg) {
1064 return NT_STATUS_NOT_FOUND;
1068 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1071 if (!tldap_entry_dn(msg[0], &dn)) {
1072 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1075 dn = talloc_strdup(mem_ctx, dn);
1077 return NT_STATUS_NO_MEMORY;
1082 return NT_STATUS_OK;
1085 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1086 const DOM_SID *alias,
1087 const DOM_SID *member,
1090 struct pdb_ads_state *state = talloc_get_type_abort(
1091 m->private_data, struct pdb_ads_state);
1092 TALLOC_CTX *frame = talloc_stackframe();
1093 struct tldap_mod *mods;
1095 char *aliasdn, *memberdn;
1098 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1099 if (!NT_STATUS_IS_OK(status)) {
1100 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1101 sid_string_dbg(alias), nt_errstr(status)));
1103 return NT_STATUS_NO_SUCH_ALIAS;
1105 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1106 if (!NT_STATUS_IS_OK(status)) {
1107 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1108 sid_string_dbg(member), nt_errstr(status)));
1115 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1116 "member", memberdn)) {
1118 return NT_STATUS_NO_MEMORY;
1121 rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
1123 if (rc != TLDAP_SUCCESS) {
1124 DEBUG(10, ("ldap_modify failed: %s\n",
1125 tldap_errstr(debug_ctx(), state->ld, rc)));
1126 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1127 return NT_STATUS_MEMBER_IN_ALIAS;
1129 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1130 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1132 return NT_STATUS_LDAP(rc);
1135 return NT_STATUS_OK;
1138 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1139 const DOM_SID *alias,
1140 const DOM_SID *member)
1142 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1145 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1146 const DOM_SID *alias,
1147 const DOM_SID *member)
1149 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1152 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1153 struct dom_sid *psid)
1155 const char *attrs[1] = { "objectSid" };
1156 struct tldap_message **msg;
1162 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1163 dnblob->data, dnblob->length, &dn, &len,
1167 rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1168 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1169 &msg, "(objectclass=*)");
1171 if (talloc_array_length(msg) != 1) {
1172 DEBUG(10, ("Got %d objects, expected one\n",
1173 (int)talloc_array_length(msg)));
1178 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1183 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1184 const DOM_SID *alias,
1185 TALLOC_CTX *mem_ctx,
1187 size_t *pnum_members)
1189 struct pdb_ads_state *state = talloc_get_type_abort(
1190 m->private_data, struct pdb_ads_state);
1191 const char *attrs[1] = { "member" };
1193 struct tldap_message **msg;
1194 int i, rc, num_members;
1196 struct dom_sid *members;
1198 sidstr = sid_binstring(talloc_tos(), alias);
1199 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1201 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1202 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1203 "(objectsid=%s)", sidstr);
1204 TALLOC_FREE(sidstr);
1205 if (rc != TLDAP_SUCCESS) {
1206 DEBUG(10, ("ldap_search failed %s\n",
1207 tldap_errstr(debug_ctx(), state->ld, rc)));
1208 return NT_STATUS_LDAP(rc);
1210 switch talloc_array_length(msg) {
1212 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1217 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1221 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1222 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1225 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1226 if (members == NULL) {
1227 return NT_STATUS_NO_MEMORY;
1230 for (i=0; i<num_members; i++) {
1231 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1232 TALLOC_FREE(members);
1233 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1237 *pmembers = members;
1238 *pnum_members = num_members;
1239 return NT_STATUS_OK;
1242 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1243 TALLOC_CTX *mem_ctx,
1244 const DOM_SID *domain_sid,
1245 const DOM_SID *members,
1247 uint32 **pp_alias_rids,
1248 size_t *p_num_alias_rids)
1250 return NT_STATUS_NOT_IMPLEMENTED;
1253 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1254 const DOM_SID *domain_sid,
1257 const char **pp_names,
1258 enum lsa_SidType *attrs)
1260 return NT_STATUS_NOT_IMPLEMENTED;
1263 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1264 const DOM_SID *domain_sid,
1266 const char **pp_names,
1268 enum lsa_SidType *attrs)
1270 return NT_STATUS_NOT_IMPLEMENTED;
1273 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1274 int policy_index, uint32 *value)
1276 return account_policy_get(policy_index, value)
1277 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1280 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1281 int policy_index, uint32 value)
1283 return account_policy_set(policy_index, value)
1284 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1287 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1290 return NT_STATUS_NOT_IMPLEMENTED;
1293 struct pdb_ads_search_state {
1294 uint32_t acct_flags;
1295 struct samr_displayentry *entries;
1296 uint32_t num_entries;
1301 static bool pdb_ads_next_entry(struct pdb_search *search,
1302 struct samr_displayentry *entry)
1304 struct pdb_ads_search_state *state = talloc_get_type_abort(
1305 search->private_data, struct pdb_ads_search_state);
1307 if (state->current == state->num_entries) {
1311 entry->idx = state->entries[state->current].idx;
1312 entry->rid = state->entries[state->current].rid;
1313 entry->acct_flags = state->entries[state->current].acct_flags;
1315 entry->account_name = talloc_strdup(
1316 search, state->entries[state->current].account_name);
1317 entry->fullname = talloc_strdup(
1318 search, state->entries[state->current].fullname);
1319 entry->description = talloc_strdup(
1320 search, state->entries[state->current].description);
1322 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1323 || (entry->description == NULL)) {
1324 DEBUG(0, ("talloc_strdup failed\n"));
1328 state->current += 1;
1332 static void pdb_ads_search_end(struct pdb_search *search)
1334 struct pdb_ads_search_state *state = talloc_get_type_abort(
1335 search->private_data, struct pdb_ads_search_state);
1339 static bool pdb_ads_search_filter(struct pdb_methods *m,
1340 struct pdb_search *search,
1342 struct pdb_ads_search_state **pstate)
1344 struct pdb_ads_state *state = talloc_get_type_abort(
1345 m->private_data, struct pdb_ads_state);
1346 struct pdb_ads_search_state *sstate;
1347 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1348 "userAccountControl", "description" };
1349 struct tldap_message **users;
1350 int i, rc, num_users;
1352 sstate = talloc_zero(search, struct pdb_ads_search_state);
1353 if (sstate == NULL) {
1357 rc = tldap_search_fmt(
1358 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1359 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1361 if (rc != TLDAP_SUCCESS) {
1362 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1363 tldap_errstr(debug_ctx(), state->ld, rc)));
1367 num_users = talloc_array_length(users);
1369 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1371 if (sstate->entries == NULL) {
1372 DEBUG(10, ("talloc failed\n"));
1376 sstate->num_entries = 0;
1378 for (i=0; i<num_users; i++) {
1379 struct samr_displayentry *e;
1382 e = &sstate->entries[sstate->num_entries];
1384 e->idx = sstate->num_entries;
1385 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1386 DEBUG(10, ("Could not pull sid\n"));
1389 sid_peek_rid(&sid, &e->rid);
1390 e->acct_flags = ACB_NORMAL;
1391 e->account_name = tldap_talloc_single_attribute(
1392 users[i], "samAccountName", sstate->entries);
1393 if (e->account_name == NULL) {
1396 e->fullname = tldap_talloc_single_attribute(
1397 users[i], "displayName", sstate->entries);
1398 if (e->fullname == NULL) {
1401 e->description = tldap_talloc_single_attribute(
1402 users[i], "description", sstate->entries);
1403 if (e->description == NULL) {
1404 e->description = "";
1407 sstate->num_entries += 1;
1408 if (sstate->num_entries >= num_users) {
1413 search->private_data = sstate;
1414 search->next_entry = pdb_ads_next_entry;
1415 search->search_end = pdb_ads_search_end;
1420 static bool pdb_ads_search_users(struct pdb_methods *m,
1421 struct pdb_search *search,
1424 struct pdb_ads_search_state *sstate;
1427 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1431 sstate->acct_flags = acct_flags;
1435 static bool pdb_ads_search_groups(struct pdb_methods *m,
1436 struct pdb_search *search)
1438 struct pdb_ads_search_state *sstate;
1442 filter = talloc_asprintf(talloc_tos(),
1443 "(&(grouptype=%d)(objectclass=group))",
1444 GTYPE_SECURITY_GLOBAL_GROUP);
1445 if (filter == NULL) {
1448 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1449 TALLOC_FREE(filter);
1453 sstate->acct_flags = 0;
1457 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1458 struct pdb_search *search,
1461 struct pdb_ads_search_state *sstate;
1465 filter = talloc_asprintf(
1466 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1467 sid_check_is_builtin(sid)
1468 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1469 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1471 if (filter == NULL) {
1474 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1475 TALLOC_FREE(filter);
1479 sstate->acct_flags = 0;
1483 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1489 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1492 struct pdb_ads_state *state = talloc_get_type_abort(
1493 m->private_data, struct pdb_ads_state);
1494 sid_compose(sid, &state->domainsid, uid);
1498 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1501 struct pdb_ads_state *state = talloc_get_type_abort(
1502 m->private_data, struct pdb_ads_state);
1503 sid_compose(sid, &state->domainsid, gid);
1507 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1508 union unid_t *id, enum lsa_SidType *type)
1510 struct pdb_ads_state *state = talloc_get_type_abort(
1511 m->private_data, struct pdb_ads_state);
1512 struct tldap_message **msg;
1518 * This is a big, big hack: Just hard-code the rid as uid/gid.
1521 sid_peek_rid(sid, &rid);
1523 sidstr = sid_binstring(talloc_tos(), sid);
1524 if (sidstr == NULL) {
1528 rc = tldap_search_fmt(
1529 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1530 NULL, 0, 0, talloc_tos(), &msg,
1531 "(&(objectsid=%s)(objectclass=user))", sidstr);
1532 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1534 *type = SID_NAME_USER;
1535 TALLOC_FREE(sidstr);
1539 rc = tldap_search_fmt(
1540 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1541 NULL, 0, 0, talloc_tos(), &msg,
1542 "(&(objectsid=%s)(objectclass=group))", sidstr);
1543 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1545 *type = SID_NAME_DOM_GRP;
1546 TALLOC_FREE(sidstr);
1550 TALLOC_FREE(sidstr);
1554 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1559 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1564 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1565 const char *domain, char** pwd,
1567 time_t *pass_last_set_time)
1572 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1573 const char* domain, const char* pwd,
1579 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1585 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1586 TALLOC_CTX *mem_ctx,
1587 uint32 *num_domains,
1588 struct trustdom_info ***domains)
1590 return NT_STATUS_NOT_IMPLEMENTED;
1593 static void pdb_ads_init_methods(struct pdb_methods *m)
1596 m->getsampwnam = pdb_ads_getsampwnam;
1597 m->getsampwsid = pdb_ads_getsampwsid;
1598 m->create_user = pdb_ads_create_user;
1599 m->delete_user = pdb_ads_delete_user;
1600 m->add_sam_account = pdb_ads_add_sam_account;
1601 m->update_sam_account = pdb_ads_update_sam_account;
1602 m->delete_sam_account = pdb_ads_delete_sam_account;
1603 m->rename_sam_account = pdb_ads_rename_sam_account;
1604 m->update_login_attempts = pdb_ads_update_login_attempts;
1605 m->getgrsid = pdb_ads_getgrsid;
1606 m->getgrgid = pdb_ads_getgrgid;
1607 m->getgrnam = pdb_ads_getgrnam;
1608 m->create_dom_group = pdb_ads_create_dom_group;
1609 m->delete_dom_group = pdb_ads_delete_dom_group;
1610 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1611 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1612 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1613 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1614 m->enum_group_members = pdb_ads_enum_group_members;
1615 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1616 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1617 m->add_groupmem = pdb_ads_add_groupmem;
1618 m->del_groupmem = pdb_ads_del_groupmem;
1619 m->create_alias = pdb_ads_create_alias;
1620 m->delete_alias = pdb_ads_delete_alias;
1621 m->get_aliasinfo = pdb_ads_get_aliasinfo;
1622 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1623 m->add_aliasmem = pdb_ads_add_aliasmem;
1624 m->del_aliasmem = pdb_ads_del_aliasmem;
1625 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1626 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1627 m->lookup_rids = pdb_ads_lookup_rids;
1628 m->lookup_names = pdb_ads_lookup_names;
1629 m->get_account_policy = pdb_ads_get_account_policy;
1630 m->set_account_policy = pdb_ads_set_account_policy;
1631 m->get_seq_num = pdb_ads_get_seq_num;
1632 m->search_users = pdb_ads_search_users;
1633 m->search_groups = pdb_ads_search_groups;
1634 m->search_aliases = pdb_ads_search_aliases;
1635 m->uid_to_rid = pdb_ads_uid_to_rid;
1636 m->uid_to_sid = pdb_ads_uid_to_sid;
1637 m->gid_to_sid = pdb_ads_gid_to_sid;
1638 m->sid_to_id = pdb_ads_sid_to_id;
1639 m->rid_algorithm = pdb_ads_rid_algorithm;
1640 m->new_rid = pdb_ads_new_rid;
1641 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1642 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1643 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1644 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1647 static void free_private_data(void **vp)
1649 struct pdb_ads_state *state = talloc_get_type_abort(
1650 *vp, struct pdb_ads_state);
1652 TALLOC_FREE(state->ld);
1656 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1657 const char *location)
1659 const char *rootdse_attrs[2] = {
1660 "defaultNamingContext", "configurationNamingContext" };
1661 const char *domain_attrs[1] = { "objectSid" };
1662 const char *ncname_attrs[1] = { "netbiosname" };
1663 struct tldap_message **rootdse, **domain, **ncname;
1664 TALLOC_CTX *frame = talloc_stackframe();
1665 struct sockaddr_un sunaddr;
1670 ZERO_STRUCT(sunaddr);
1671 sunaddr.sun_family = AF_UNIX;
1672 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1674 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1676 if (!NT_STATUS_IS_OK(status)) {
1677 DEBUG(10, ("Could not connect to %s: %s\n", location,
1678 nt_errstr(status)));
1682 state->ld = tldap_context_create(state, fd);
1683 if (state->ld == NULL) {
1685 status = NT_STATUS_NO_MEMORY;
1689 rc = tldap_search_fmt(
1690 state->ld, "", TLDAP_SCOPE_BASE,
1691 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1692 talloc_tos(), &rootdse, "(objectclass=*)");
1693 if (rc != TLDAP_SUCCESS) {
1694 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1695 tldap_errstr(debug_ctx(), state->ld, rc)));
1696 status = NT_STATUS_LDAP(rc);
1699 if (talloc_array_length(rootdse) != 1) {
1700 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1704 state->domaindn = tldap_talloc_single_attribute(
1705 rootdse[0], "defaultNamingContext", state);
1706 if (state->domaindn == NULL) {
1707 DEBUG(10, ("Could not get defaultNamingContext\n"));
1708 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1711 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1713 state->configdn = tldap_talloc_single_attribute(
1714 rootdse[0], "configurationNamingContext", state);
1715 if (state->domaindn == NULL) {
1716 DEBUG(10, ("Could not get configurationNamingContext\n"));
1717 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1720 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1723 * Figure out our domain's SID
1725 rc = tldap_search_fmt(
1726 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1727 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1728 talloc_tos(), &domain, "(objectclass=*)");
1729 if (rc != TLDAP_SUCCESS) {
1730 DEBUG(10, ("Could not retrieve domain: %s\n",
1731 tldap_errstr(debug_ctx(), state->ld, rc)));
1732 status = NT_STATUS_LDAP(rc);
1736 num_domains = talloc_array_length(domain);
1737 if (num_domains != 1) {
1738 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1739 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1742 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1743 DEBUG(10, ("Could not retrieve domain SID\n"));
1744 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1747 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1750 * Figure out our domain's short name
1752 rc = tldap_search_fmt(
1753 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1754 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1755 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1756 if (rc != TLDAP_SUCCESS) {
1757 DEBUG(10, ("Could not retrieve ncname: %s\n",
1758 tldap_errstr(debug_ctx(), state->ld, rc)));
1759 status = NT_STATUS_LDAP(rc);
1762 if (talloc_array_length(ncname) != 1) {
1763 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1767 state->netbiosname = tldap_talloc_single_attribute(
1768 ncname[0], "netbiosname", state);
1769 if (state->netbiosname == NULL) {
1770 DEBUG(10, ("Could not get netbiosname\n"));
1771 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1774 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1776 if (!strequal(lp_workgroup(), state->netbiosname)) {
1777 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1778 state->netbiosname, lp_workgroup()));
1779 status = NT_STATUS_NO_SUCH_DOMAIN;
1783 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1785 status = NT_STATUS_OK;
1791 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1792 const char *location)
1794 struct pdb_methods *m;
1795 struct pdb_ads_state *state;
1799 m = talloc(talloc_autofree_context(), struct pdb_methods);
1801 return NT_STATUS_NO_MEMORY;
1803 state = talloc(m, struct pdb_ads_state);
1804 if (state == NULL) {
1807 m->private_data = state;
1808 m->free_private_data = free_private_data;
1809 pdb_ads_init_methods(m);
1811 if (location == NULL) {
1812 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1816 if (location == NULL) {
1820 status = pdb_ads_connect(state, location);
1821 if (!NT_STATUS_IS_OK(status)) {
1822 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1827 return NT_STATUS_OK;
1829 status = NT_STATUS_NO_MEMORY;
1835 NTSTATUS pdb_ads_init(void);
1836 NTSTATUS pdb_ads_init(void)
1838 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",