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 struct pdb_ads_state {
23 struct tldap_context *ld;
24 struct dom_sid domainsid;
30 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
31 struct samu *sam_acct,
33 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
35 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
36 struct dom_sid *psid);
37 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
38 const struct dom_sid *sid,
39 TALLOC_CTX *mem_ctx, char **pdn);
41 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
46 if (!tldap_pull_uint64(msg, attr, &tmp)) {
49 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
53 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
56 sid_peek_rid(sid, &rid);
60 struct pdb_ads_samu_private {
62 struct tldap_message *ldapmsg;
65 static struct samu *pdb_ads_init_guest(TALLOC_CTX *mem_ctx,
66 struct pdb_methods *m)
68 struct pdb_ads_state *state = talloc_get_type_abort(
69 m->private_data, struct pdb_ads_state);
70 struct dom_sid guest_sid;
74 sid_compose(&guest_sid, &state->domainsid, DOMAIN_USER_RID_GUEST);
76 guest = samu_new(mem_ctx);
81 status = pdb_ads_getsampwsid(m, guest, &guest_sid);
82 if (!NT_STATUS_IS_OK(status)) {
83 DEBUG(10, ("Could not init guest account: %s\n",
91 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
92 struct pdb_methods *m, struct samu *sam)
94 struct pdb_ads_samu_private *result;
97 result = (struct pdb_ads_samu_private *)
98 pdb_get_backend_private_data(sam, m);
100 if (result != NULL) {
101 return talloc_get_type_abort(
102 result, struct pdb_ads_samu_private);
106 * This is now a weirdness of the passdb API. For the guest user we
107 * are not asked first.
109 sid_peek_rid(pdb_get_user_sid(sam), &rid);
111 if (rid == DOMAIN_USER_RID_GUEST) {
112 struct samu *guest = pdb_ads_init_guest(talloc_tos(), m);
117 result = talloc_get_type_abort(
118 pdb_get_backend_private_data(guest, m),
119 struct pdb_ads_samu_private);
120 pdb_set_backend_private_data(
121 sam, talloc_move(sam, &result), NULL, m, PDB_SET);
123 return talloc_get_type_abort(
124 pdb_get_backend_private_data(sam, m),
125 struct pdb_ads_samu_private);
131 static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m,
133 struct tldap_message *entry)
135 struct pdb_ads_state *state = talloc_get_type_abort(
136 m->private_data, struct pdb_ads_state);
137 TALLOC_CTX *frame = talloc_stackframe();
138 struct pdb_ads_samu_private *priv;
139 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
146 priv = talloc(sam, struct pdb_ads_samu_private);
148 return NT_STATUS_NO_MEMORY;
150 if (!tldap_entry_dn(entry, &priv->dn)) {
152 return NT_STATUS_INTERNAL_DB_CORRUPTION;
155 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
157 DEBUG(10, ("no samAccountName\n"));
160 pdb_set_username(sam, str, PDB_SET);
162 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
163 pdb_set_logon_time(sam, tmp_time, PDB_SET);
165 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
166 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
168 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
169 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
171 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
172 pdb_set_pass_last_set_time(sam, tmp_time, 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 "%s", 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));
276 ret &= tldap_make_mod_fmt(
277 existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
278 "%d", ads_acb2uf(pdb_get_acct_ctrl(sam)));
280 ret &= tldap_make_mod_fmt(
281 existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
282 "%s", pdb_get_homedir(sam));
284 ret &= tldap_make_mod_fmt(
285 existing, mem_ctx, pnum_mods, pmods, "homeDrive",
286 "%s", pdb_get_dir_drive(sam));
288 ret &= tldap_make_mod_fmt(
289 existing, mem_ctx, pnum_mods, pmods, "scriptPath",
290 "%s", pdb_get_logon_script(sam));
292 ret &= tldap_make_mod_fmt(
293 existing, mem_ctx, pnum_mods, pmods, "profilePath",
294 "%s", pdb_get_profile_path(sam));
299 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
300 struct pdb_ads_state *state,
301 struct samu *sam_acct,
304 const char * attrs[] = {
305 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
306 "sAMAccountName", "displayName", "homeDirectory",
307 "homeDrive", "scriptPath", "profilePath", "description",
308 "userWorkstations", "comment", "userParameters", "objectSid",
309 "primaryGroupID", "userAccountControl", "logonHours",
310 "badPwdCount", "logonCount", "countryCode", "codePage",
311 "unicodePwd", "dBCSPwd" };
312 struct tldap_message **users;
315 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
316 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
317 &users, "%s", filter);
318 if (rc != TLDAP_SUCCESS) {
319 DEBUG(10, ("ldap_search failed %s\n",
320 tldap_errstr(debug_ctx(), state->ld, rc)));
321 return NT_STATUS_LDAP(rc);
324 count = talloc_array_length(users);
326 DEBUG(10, ("Expected 1 user, got %d\n", count));
327 return NT_STATUS_INTERNAL_DB_CORRUPTION;
330 return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]);
333 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
334 struct samu *sam_acct,
335 const char *username)
337 struct pdb_ads_state *state = talloc_get_type_abort(
338 m->private_data, struct pdb_ads_state);
341 filter = talloc_asprintf(
342 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
344 NT_STATUS_HAVE_NO_MEMORY(filter);
346 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
349 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
350 struct samu *sam_acct,
353 struct pdb_ads_state *state = talloc_get_type_abort(
354 m->private_data, struct pdb_ads_state);
355 char *sidstr, *filter;
357 sidstr = sid_binstring(talloc_tos(), sid);
358 NT_STATUS_HAVE_NO_MEMORY(sidstr);
360 filter = talloc_asprintf(
361 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
363 NT_STATUS_HAVE_NO_MEMORY(filter);
365 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
368 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
370 const char *name, uint32 acct_flags,
373 struct pdb_ads_state *state = talloc_get_type_abort(
374 m->private_data, struct pdb_ads_state);
375 const char *attrs[1] = { "objectSid" };
376 struct tldap_mod *mods = NULL;
378 struct tldap_message **user;
384 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
387 return NT_STATUS_NO_MEMORY;
390 /* TODO: Create machines etc */
393 ok &= tldap_make_mod_fmt(
394 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
395 ok &= tldap_make_mod_fmt(
396 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
399 return NT_STATUS_NO_MEMORY;
402 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
403 if (rc != TLDAP_SUCCESS) {
404 DEBUG(10, ("ldap_add failed %s\n",
405 tldap_errstr(debug_ctx(), state->ld, rc)));
407 return NT_STATUS_LDAP(rc);
410 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
411 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &user,
412 "(&(objectclass=user)(samaccountname=%s))",
414 if (rc != TLDAP_SUCCESS) {
415 DEBUG(10, ("Could not find just created user %s: %s\n",
416 name, tldap_errstr(debug_ctx(), state->ld, rc)));
418 return NT_STATUS_LDAP(rc);
421 if (talloc_array_length(user) != 1) {
422 DEBUG(10, ("Got %d users, expected one\n",
423 (int)talloc_array_length(user)));
425 return NT_STATUS_LDAP(rc);
428 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
429 DEBUG(10, ("Could not fetch objectSid from user %s\n",
432 return NT_STATUS_INTERNAL_DB_CORRUPTION;
435 sid_peek_rid(&sid, rid);
440 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
444 struct pdb_ads_state *state = talloc_get_type_abort(
445 m->private_data, struct pdb_ads_state);
450 status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
452 if (!NT_STATUS_IS_OK(status)) {
456 rc = tldap_delete(state->ld, dn, NULL, NULL);
458 if (rc != TLDAP_SUCCESS) {
459 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
460 tldap_errstr(debug_ctx(), state->ld, rc)));
461 return NT_STATUS_LDAP(rc);
466 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
467 struct samu *sampass)
469 return NT_STATUS_NOT_IMPLEMENTED;
472 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
475 struct pdb_ads_state *state = talloc_get_type_abort(
476 m->private_data, struct pdb_ads_state);
477 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
478 struct tldap_mod *mods = NULL;
479 int rc, num_mods = 0;
481 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
482 &num_mods, &mods, sam)) {
483 return NT_STATUS_NO_MEMORY;
487 /* Nothing to do, just return success */
491 rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, NULL);
492 if (rc != TLDAP_SUCCESS) {
493 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
494 tldap_errstr(debug_ctx(), state->ld, rc)));
495 return NT_STATUS_LDAP(rc);
503 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
504 struct samu *username)
506 return NT_STATUS_NOT_IMPLEMENTED;
509 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
510 struct samu *oldname,
513 return NT_STATUS_NOT_IMPLEMENTED;
516 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
517 struct samu *sam_acct,
520 return NT_STATUS_NOT_IMPLEMENTED;
523 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
526 struct pdb_ads_state *state = talloc_get_type_abort(
527 m->private_data, struct pdb_ads_state);
528 const char *attrs[4] = { "objectSid", "description", "samAccountName",
531 struct tldap_message **group;
535 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
536 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
537 &group, "%s", filter);
538 if (rc != TLDAP_SUCCESS) {
539 DEBUG(10, ("ldap_search failed %s\n",
540 tldap_errstr(debug_ctx(), state->ld, rc)));
541 return NT_STATUS_LDAP(rc);
543 if (talloc_array_length(group) != 1) {
544 DEBUG(10, ("Expected 1 user, got %d\n",
545 (int)talloc_array_length(group)));
546 return NT_STATUS_INTERNAL_DB_CORRUPTION;
549 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
550 return NT_STATUS_INTERNAL_DB_CORRUPTION;
552 map->gid = pdb_ads_sid2gid(&map->sid);
554 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
555 return NT_STATUS_INTERNAL_DB_CORRUPTION;
558 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
559 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
560 map->sid_name_use = SID_NAME_ALIAS;
562 case GTYPE_SECURITY_GLOBAL_GROUP:
563 map->sid_name_use = SID_NAME_DOM_GRP;
566 return NT_STATUS_INTERNAL_DB_CORRUPTION;
569 str = tldap_talloc_single_attribute(group[0], "samAccountName",
572 return NT_STATUS_INTERNAL_DB_CORRUPTION;
574 fstrcpy(map->nt_name, str);
577 str = tldap_talloc_single_attribute(group[0], "description",
580 fstrcpy(map->comment, str);
583 map->comment[0] = '\0';
590 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
596 filter = talloc_asprintf(talloc_tos(),
597 "(&(objectsid=%s)(objectclass=group))",
598 sid_string_talloc(talloc_tos(), &sid));
599 if (filter == NULL) {
600 return NT_STATUS_NO_MEMORY;
603 status = pdb_ads_getgrfilter(m, map, filter);
608 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
612 pdb_ads_gid_to_sid(m, gid, &sid);
613 return pdb_ads_getgrsid(m, map, sid);
616 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
622 filter = talloc_asprintf(talloc_tos(),
623 "(&(samaccountname=%s)(objectclass=group))",
625 if (filter == NULL) {
626 return NT_STATUS_NO_MEMORY;
629 status = pdb_ads_getgrfilter(m, map, filter);
634 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
635 TALLOC_CTX *mem_ctx, const char *name,
638 TALLOC_CTX *frame = talloc_stackframe();
639 struct pdb_ads_state *state = talloc_get_type_abort(
640 m->private_data, struct pdb_ads_state);
641 const char *attrs[1] = { "objectSid" };
643 struct tldap_mod *mods = NULL;
644 struct tldap_message **alias;
650 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
654 return NT_STATUS_NO_MEMORY;
657 ok &= tldap_make_mod_fmt(
658 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
660 ok &= tldap_make_mod_fmt(
661 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
662 ok &= tldap_make_mod_fmt(
663 NULL, talloc_tos(), &num_mods, &mods, "groupType",
664 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
668 return NT_STATUS_NO_MEMORY;
671 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
672 if (rc != TLDAP_SUCCESS) {
673 DEBUG(10, ("ldap_add failed %s\n",
674 tldap_errstr(debug_ctx(), state->ld, rc)));
676 return NT_STATUS_LDAP(rc);
679 rc = tldap_search_fmt(
680 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
681 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
682 "(&(objectclass=group)(samaccountname=%s))", name);
683 if (rc != TLDAP_SUCCESS) {
684 DEBUG(10, ("Could not find just created alias %s: %s\n",
685 name, tldap_errstr(debug_ctx(), state->ld, rc)));
687 return NT_STATUS_LDAP(rc);
690 if (talloc_array_length(alias) != 1) {
691 DEBUG(10, ("Got %d alias, expected one\n",
692 (int)talloc_array_length(alias)));
694 return NT_STATUS_LDAP(rc);
697 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
698 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
701 return NT_STATUS_INTERNAL_DB_CORRUPTION;
704 sid_peek_rid(&sid, rid);
709 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
710 TALLOC_CTX *mem_ctx, uint32 rid)
712 struct pdb_ads_state *state = talloc_get_type_abort(
713 m->private_data, struct pdb_ads_state);
716 struct tldap_message **msg;
720 sid_compose(&sid, &state->domainsid, rid);
722 sidstr = sid_binstring(talloc_tos(), &sid);
723 NT_STATUS_HAVE_NO_MEMORY(sidstr);
725 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
726 NULL, 0, 0, talloc_tos(), &msg,
727 ("(&(objectSid=%s)(objectClass=group))"),
730 if (rc != TLDAP_SUCCESS) {
731 DEBUG(10, ("ldap_search failed %s\n",
732 tldap_errstr(debug_ctx(), state->ld, rc)));
733 return NT_STATUS_LDAP(rc);
736 switch talloc_array_length(msg) {
738 return NT_STATUS_NO_SUCH_GROUP;
742 return NT_STATUS_INTERNAL_DB_CORRUPTION;
745 if (!tldap_entry_dn(msg[0], &dn)) {
746 return NT_STATUS_INTERNAL_DB_CORRUPTION;
749 rc = tldap_delete(state->ld, dn, NULL, NULL);
750 if (rc != TLDAP_SUCCESS) {
751 DEBUG(10, ("ldap_delete failed: %s\n",
752 tldap_errstr(debug_ctx(), state->ld, rc)));
754 return NT_STATUS_LDAP(rc);
761 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
764 return NT_STATUS_NOT_IMPLEMENTED;
767 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
770 return NT_STATUS_NOT_IMPLEMENTED;
773 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
776 return NT_STATUS_NOT_IMPLEMENTED;
779 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
781 enum lsa_SidType sid_name_use,
783 size_t *p_num_entries,
786 return NT_STATUS_NOT_IMPLEMENTED;
789 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
791 const DOM_SID *group,
793 size_t *pnum_members)
795 struct pdb_ads_state *state = talloc_get_type_abort(
796 m->private_data, struct pdb_ads_state);
797 const char *attrs[1] = { "member" };
799 struct tldap_message **msg;
800 int i, rc, num_members;
804 sidstr = sid_binstring(talloc_tos(), group);
805 NT_STATUS_HAVE_NO_MEMORY(sidstr);
807 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
808 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
809 "(objectsid=%s)", sidstr);
811 if (rc != TLDAP_SUCCESS) {
812 DEBUG(10, ("ldap_search failed %s\n",
813 tldap_errstr(debug_ctx(), state->ld, rc)));
814 return NT_STATUS_LDAP(rc);
816 switch talloc_array_length(msg) {
818 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
823 return NT_STATUS_INTERNAL_DB_CORRUPTION;
827 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
828 return NT_STATUS_INTERNAL_DB_CORRUPTION;
831 members = talloc_array(mem_ctx, uint32_t, num_members);
832 if (members == NULL) {
833 return NT_STATUS_NO_MEMORY;
836 for (i=0; i<num_members; i++) {
838 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &sid)
839 || !sid_peek_rid(&sid, &members[i])) {
840 TALLOC_FREE(members);
841 return NT_STATUS_INTERNAL_DB_CORRUPTION;
846 *pnum_members = num_members;
850 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
855 size_t *p_num_groups)
857 struct pdb_ads_state *state = talloc_get_type_abort(
858 m->private_data, struct pdb_ads_state);
859 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
861 const char *attrs[1] = { "objectSid" };
862 struct tldap_message **groups;
865 struct dom_sid *group_sids;
868 rc = tldap_search_fmt(
869 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
870 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
871 "(&(member=%s)(grouptype=%d)(objectclass=group))",
872 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
873 if (rc != TLDAP_SUCCESS) {
874 DEBUG(10, ("ldap_search failed %s\n",
875 tldap_errstr(debug_ctx(), state->ld, rc)));
876 return NT_STATUS_LDAP(rc);
879 count = talloc_array_length(groups);
881 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
882 if (group_sids == NULL) {
883 return NT_STATUS_NO_MEMORY;
885 gids = talloc_array(mem_ctx, gid_t, count);
887 TALLOC_FREE(group_sids);
888 return NT_STATUS_NO_MEMORY;
892 for (i=0; i<count; i++) {
893 if (!tldap_pull_binsid(groups[i], "objectSid",
894 &group_sids[num_groups])) {
897 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
900 if (num_groups == count) {
905 *pp_sids = group_sids;
907 *p_num_groups = num_groups;
911 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
915 return NT_STATUS_NOT_IMPLEMENTED;
918 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
920 uint32 grouprid, uint32 memberrid,
923 struct pdb_ads_state *state = talloc_get_type_abort(
924 m->private_data, struct pdb_ads_state);
925 TALLOC_CTX *frame = talloc_stackframe();
926 struct dom_sid groupsid, membersid;
927 char *groupdn, *memberdn;
928 struct tldap_mod *mods;
932 sid_compose(&groupsid, &state->domainsid, grouprid);
933 sid_compose(&membersid, &state->domainsid, memberrid);
935 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
936 if (!NT_STATUS_IS_OK(status)) {
938 return NT_STATUS_NO_SUCH_GROUP;
940 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
941 if (!NT_STATUS_IS_OK(status)) {
943 return NT_STATUS_NO_SUCH_USER;
948 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
949 "member", memberdn)) {
951 return NT_STATUS_NO_MEMORY;
954 rc = tldap_modify(state->ld, groupdn, 1, mods, NULL, NULL);
956 if (rc != TLDAP_SUCCESS) {
957 DEBUG(10, ("ldap_modify failed: %s\n",
958 tldap_errstr(debug_ctx(), state->ld, rc)));
959 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
960 return NT_STATUS_MEMBER_IN_GROUP;
962 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
963 return NT_STATUS_MEMBER_NOT_IN_GROUP;
965 return NT_STATUS_LDAP(rc);
971 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
973 uint32 group_rid, uint32 member_rid)
975 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
979 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
981 uint32 group_rid, uint32 member_rid)
983 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
987 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
988 const char *name, uint32 *rid)
990 TALLOC_CTX *frame = talloc_stackframe();
991 struct pdb_ads_state *state = talloc_get_type_abort(
992 m->private_data, struct pdb_ads_state);
993 const char *attrs[1] = { "objectSid" };
995 struct tldap_mod *mods = NULL;
996 struct tldap_message **alias;
1002 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1006 return NT_STATUS_NO_MEMORY;
1009 ok &= tldap_make_mod_fmt(
1010 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
1012 ok &= tldap_make_mod_fmt(
1013 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
1014 ok &= tldap_make_mod_fmt(
1015 NULL, talloc_tos(), &num_mods, &mods, "groupType",
1016 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1020 return NT_STATUS_NO_MEMORY;
1023 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
1024 if (rc != TLDAP_SUCCESS) {
1025 DEBUG(10, ("ldap_add failed %s\n",
1026 tldap_errstr(debug_ctx(), state->ld, rc)));
1028 return NT_STATUS_LDAP(rc);
1031 rc = tldap_search_fmt(
1032 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1033 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1034 "(&(objectclass=group)(samaccountname=%s))", name);
1035 if (rc != TLDAP_SUCCESS) {
1036 DEBUG(10, ("Could not find just created alias %s: %s\n",
1037 name, tldap_errstr(debug_ctx(), state->ld, rc)));
1039 return NT_STATUS_LDAP(rc);
1042 if (talloc_array_length(alias) != 1) {
1043 DEBUG(10, ("Got %d alias, expected one\n",
1044 (int)talloc_array_length(alias)));
1046 return NT_STATUS_LDAP(rc);
1049 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1050 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1053 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1056 sid_peek_rid(&sid, rid);
1058 return NT_STATUS_OK;
1061 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1064 struct pdb_ads_state *state = talloc_get_type_abort(
1065 m->private_data, struct pdb_ads_state);
1066 struct tldap_message **alias;
1070 sidstr = sid_binstring(talloc_tos(), sid);
1071 if (sidstr == NULL) {
1072 return NT_STATUS_NO_MEMORY;
1075 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1076 NULL, 0, 0, talloc_tos(), &alias,
1077 "(&(objectSid=%s)(objectclass=group)"
1078 "(|(grouptype=%d)(grouptype=%d)))",
1079 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1080 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1081 TALLOC_FREE(sidstr);
1082 if (rc != TLDAP_SUCCESS) {
1083 DEBUG(10, ("ldap_search failed: %s\n",
1084 tldap_errstr(debug_ctx(), state->ld, rc)));
1086 return NT_STATUS_LDAP(rc);
1088 if (talloc_array_length(alias) != 1) {
1089 DEBUG(10, ("Expected 1 alias, got %d\n",
1090 (int)talloc_array_length(alias)));
1091 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1093 if (!tldap_entry_dn(alias[0], &dn)) {
1094 DEBUG(10, ("Could not get DN for alias %s\n",
1095 sid_string_dbg(sid)));
1096 return NT_STATUS_INTERNAL_ERROR;
1099 rc = tldap_delete(state->ld, dn, NULL, NULL);
1100 if (rc != TLDAP_SUCCESS) {
1101 DEBUG(10, ("ldap_delete failed: %s\n",
1102 tldap_errstr(debug_ctx(), state->ld, rc)));
1104 return NT_STATUS_LDAP(rc);
1107 return NT_STATUS_OK;
1110 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
1112 struct acct_info *info)
1114 return NT_STATUS_NOT_IMPLEMENTED;
1117 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1119 struct acct_info *info)
1121 return NT_STATUS_NOT_IMPLEMENTED;
1124 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1125 const struct dom_sid *sid,
1126 TALLOC_CTX *mem_ctx, char **pdn)
1128 struct tldap_message **msg;
1132 sidstr = sid_binstring(talloc_tos(), sid);
1133 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1135 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1136 NULL, 0, 0, talloc_tos(), &msg,
1137 "(objectsid=%s)", sidstr);
1138 TALLOC_FREE(sidstr);
1139 if (rc != TLDAP_SUCCESS) {
1140 DEBUG(10, ("ldap_search failed %s\n",
1141 tldap_errstr(debug_ctx(), state->ld, rc)));
1142 return NT_STATUS_LDAP(rc);
1145 switch talloc_array_length(msg) {
1147 return NT_STATUS_NOT_FOUND;
1151 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1154 if (!tldap_entry_dn(msg[0], &dn)) {
1155 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1158 dn = talloc_strdup(mem_ctx, dn);
1160 return NT_STATUS_NO_MEMORY;
1165 return NT_STATUS_OK;
1168 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1169 const DOM_SID *alias,
1170 const DOM_SID *member,
1173 struct pdb_ads_state *state = talloc_get_type_abort(
1174 m->private_data, struct pdb_ads_state);
1175 TALLOC_CTX *frame = talloc_stackframe();
1176 struct tldap_mod *mods;
1178 char *aliasdn, *memberdn;
1181 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1182 if (!NT_STATUS_IS_OK(status)) {
1183 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1184 sid_string_dbg(alias), nt_errstr(status)));
1186 return NT_STATUS_NO_SUCH_ALIAS;
1188 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1189 if (!NT_STATUS_IS_OK(status)) {
1190 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1191 sid_string_dbg(member), nt_errstr(status)));
1198 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1199 "member", memberdn)) {
1201 return NT_STATUS_NO_MEMORY;
1204 rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
1206 if (rc != TLDAP_SUCCESS) {
1207 DEBUG(10, ("ldap_modify failed: %s\n",
1208 tldap_errstr(debug_ctx(), state->ld, rc)));
1209 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1210 return NT_STATUS_MEMBER_IN_ALIAS;
1212 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1213 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1215 return NT_STATUS_LDAP(rc);
1218 return NT_STATUS_OK;
1221 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1222 const DOM_SID *alias,
1223 const DOM_SID *member)
1225 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1228 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1229 const DOM_SID *alias,
1230 const DOM_SID *member)
1232 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1235 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1236 struct dom_sid *psid)
1238 const char *attrs[1] = { "objectSid" };
1239 struct tldap_message **msg;
1245 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1246 dnblob->data, dnblob->length, &dn, &len,
1250 rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1251 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1252 &msg, "(objectclass=*)");
1254 if (talloc_array_length(msg) != 1) {
1255 DEBUG(10, ("Got %d objects, expected one\n",
1256 (int)talloc_array_length(msg)));
1261 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1266 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1267 const DOM_SID *alias,
1268 TALLOC_CTX *mem_ctx,
1270 size_t *pnum_members)
1272 struct pdb_ads_state *state = talloc_get_type_abort(
1273 m->private_data, struct pdb_ads_state);
1274 const char *attrs[1] = { "member" };
1276 struct tldap_message **msg;
1277 int i, rc, num_members;
1279 struct dom_sid *members;
1281 sidstr = sid_binstring(talloc_tos(), alias);
1282 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1284 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1285 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1286 "(objectsid=%s)", sidstr);
1287 TALLOC_FREE(sidstr);
1288 if (rc != TLDAP_SUCCESS) {
1289 DEBUG(10, ("ldap_search failed %s\n",
1290 tldap_errstr(debug_ctx(), state->ld, rc)));
1291 return NT_STATUS_LDAP(rc);
1293 switch talloc_array_length(msg) {
1295 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1300 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1304 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1305 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1308 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1309 if (members == NULL) {
1310 return NT_STATUS_NO_MEMORY;
1313 for (i=0; i<num_members; i++) {
1314 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1315 TALLOC_FREE(members);
1316 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1320 *pmembers = members;
1321 *pnum_members = num_members;
1322 return NT_STATUS_OK;
1325 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1326 TALLOC_CTX *mem_ctx,
1327 const DOM_SID *domain_sid,
1328 const DOM_SID *members,
1330 uint32 **pp_alias_rids,
1331 size_t *p_num_alias_rids)
1333 return NT_STATUS_NOT_IMPLEMENTED;
1336 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1337 const DOM_SID *domain_sid,
1341 enum lsa_SidType *lsa_attrs)
1343 struct pdb_ads_state *state = talloc_get_type_abort(
1344 m->private_data, struct pdb_ads_state);
1345 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1348 if (num_rids == 0) {
1349 return NT_STATUS_NONE_MAPPED;
1354 for (i=0; i<num_rids; i++) {
1356 struct tldap_message **msg;
1361 lsa_attrs[i] = SID_NAME_UNKNOWN;
1363 sid_compose(&sid, domain_sid, rids[i]);
1365 sidstr = sid_binstring(talloc_tos(), &sid);
1366 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1368 rc = tldap_search_fmt(state->ld, state->domaindn,
1369 TLDAP_SCOPE_SUB, attrs,
1370 ARRAY_SIZE(attrs), 0, talloc_tos(),
1371 &msg, "(objectsid=%s)", sidstr);
1372 TALLOC_FREE(sidstr);
1373 if (rc != TLDAP_SUCCESS) {
1374 DEBUG(10, ("ldap_search failed %s\n",
1375 tldap_errstr(debug_ctx(), state->ld, rc)));
1379 switch talloc_array_length(msg) {
1381 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1386 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1389 names[i] = tldap_talloc_single_attribute(
1390 msg[0], "samAccountName", talloc_tos());
1391 if (names[i] == NULL) {
1392 DEBUG(10, ("no samAccountName\n"));
1395 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1396 DEBUG(10, ("no samAccountType"));
1399 lsa_attrs[i] = ads_atype_map(attr);
1403 if (num_mapped == 0) {
1404 return NT_STATUS_NONE_MAPPED;
1406 if (num_mapped < num_rids) {
1407 return STATUS_SOME_UNMAPPED;
1409 return NT_STATUS_OK;
1412 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1413 const DOM_SID *domain_sid,
1415 const char **pp_names,
1417 enum lsa_SidType *attrs)
1419 return NT_STATUS_NOT_IMPLEMENTED;
1422 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1423 int policy_index, uint32 *value)
1425 return account_policy_get(policy_index, value)
1426 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1429 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1430 int policy_index, uint32 value)
1432 return account_policy_set(policy_index, value)
1433 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1436 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1439 return NT_STATUS_NOT_IMPLEMENTED;
1442 struct pdb_ads_search_state {
1443 uint32_t acct_flags;
1444 struct samr_displayentry *entries;
1445 uint32_t num_entries;
1450 static bool pdb_ads_next_entry(struct pdb_search *search,
1451 struct samr_displayentry *entry)
1453 struct pdb_ads_search_state *state = talloc_get_type_abort(
1454 search->private_data, struct pdb_ads_search_state);
1456 if (state->current == state->num_entries) {
1460 entry->idx = state->entries[state->current].idx;
1461 entry->rid = state->entries[state->current].rid;
1462 entry->acct_flags = state->entries[state->current].acct_flags;
1464 entry->account_name = talloc_strdup(
1465 search, state->entries[state->current].account_name);
1466 entry->fullname = talloc_strdup(
1467 search, state->entries[state->current].fullname);
1468 entry->description = talloc_strdup(
1469 search, state->entries[state->current].description);
1471 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1472 || (entry->description == NULL)) {
1473 DEBUG(0, ("talloc_strdup failed\n"));
1477 state->current += 1;
1481 static void pdb_ads_search_end(struct pdb_search *search)
1483 struct pdb_ads_search_state *state = talloc_get_type_abort(
1484 search->private_data, struct pdb_ads_search_state);
1488 static bool pdb_ads_search_filter(struct pdb_methods *m,
1489 struct pdb_search *search,
1491 struct pdb_ads_search_state **pstate)
1493 struct pdb_ads_state *state = talloc_get_type_abort(
1494 m->private_data, struct pdb_ads_state);
1495 struct pdb_ads_search_state *sstate;
1496 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1497 "userAccountControl", "description" };
1498 struct tldap_message **users;
1499 int i, rc, num_users;
1501 sstate = talloc_zero(search, struct pdb_ads_search_state);
1502 if (sstate == NULL) {
1506 rc = tldap_search_fmt(
1507 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1508 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1510 if (rc != TLDAP_SUCCESS) {
1511 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1512 tldap_errstr(debug_ctx(), state->ld, rc)));
1516 num_users = talloc_array_length(users);
1518 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1520 if (sstate->entries == NULL) {
1521 DEBUG(10, ("talloc failed\n"));
1525 sstate->num_entries = 0;
1527 for (i=0; i<num_users; i++) {
1528 struct samr_displayentry *e;
1531 e = &sstate->entries[sstate->num_entries];
1533 e->idx = sstate->num_entries;
1534 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1535 DEBUG(10, ("Could not pull sid\n"));
1538 sid_peek_rid(&sid, &e->rid);
1539 e->acct_flags = ACB_NORMAL;
1540 e->account_name = tldap_talloc_single_attribute(
1541 users[i], "samAccountName", sstate->entries);
1542 if (e->account_name == NULL) {
1545 e->fullname = tldap_talloc_single_attribute(
1546 users[i], "displayName", sstate->entries);
1547 if (e->fullname == NULL) {
1550 e->description = tldap_talloc_single_attribute(
1551 users[i], "description", sstate->entries);
1552 if (e->description == NULL) {
1553 e->description = "";
1556 sstate->num_entries += 1;
1557 if (sstate->num_entries >= num_users) {
1562 search->private_data = sstate;
1563 search->next_entry = pdb_ads_next_entry;
1564 search->search_end = pdb_ads_search_end;
1569 static bool pdb_ads_search_users(struct pdb_methods *m,
1570 struct pdb_search *search,
1573 struct pdb_ads_search_state *sstate;
1576 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1580 sstate->acct_flags = acct_flags;
1584 static bool pdb_ads_search_groups(struct pdb_methods *m,
1585 struct pdb_search *search)
1587 struct pdb_ads_search_state *sstate;
1591 filter = talloc_asprintf(talloc_tos(),
1592 "(&(grouptype=%d)(objectclass=group))",
1593 GTYPE_SECURITY_GLOBAL_GROUP);
1594 if (filter == NULL) {
1597 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1598 TALLOC_FREE(filter);
1602 sstate->acct_flags = 0;
1606 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1607 struct pdb_search *search,
1610 struct pdb_ads_search_state *sstate;
1614 filter = talloc_asprintf(
1615 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1616 sid_check_is_builtin(sid)
1617 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1618 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1620 if (filter == NULL) {
1623 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1624 TALLOC_FREE(filter);
1628 sstate->acct_flags = 0;
1632 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1638 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1641 struct pdb_ads_state *state = talloc_get_type_abort(
1642 m->private_data, struct pdb_ads_state);
1643 sid_compose(sid, &state->domainsid, uid);
1647 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1650 struct pdb_ads_state *state = talloc_get_type_abort(
1651 m->private_data, struct pdb_ads_state);
1652 sid_compose(sid, &state->domainsid, gid);
1656 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1657 union unid_t *id, enum lsa_SidType *type)
1659 struct pdb_ads_state *state = talloc_get_type_abort(
1660 m->private_data, struct pdb_ads_state);
1661 struct tldap_message **msg;
1667 * This is a big, big hack: Just hard-code the rid as uid/gid.
1670 sid_peek_rid(sid, &rid);
1672 sidstr = sid_binstring(talloc_tos(), sid);
1673 if (sidstr == NULL) {
1677 rc = tldap_search_fmt(
1678 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1679 NULL, 0, 0, talloc_tos(), &msg,
1680 "(&(objectsid=%s)(objectclass=user))", sidstr);
1681 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1683 *type = SID_NAME_USER;
1684 TALLOC_FREE(sidstr);
1688 rc = tldap_search_fmt(
1689 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1690 NULL, 0, 0, talloc_tos(), &msg,
1691 "(&(objectsid=%s)(objectclass=group))", sidstr);
1692 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1694 *type = SID_NAME_DOM_GRP;
1695 TALLOC_FREE(sidstr);
1699 TALLOC_FREE(sidstr);
1703 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1708 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1713 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1714 const char *domain, char** pwd,
1716 time_t *pass_last_set_time)
1721 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1722 const char* domain, const char* pwd,
1728 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1734 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1735 TALLOC_CTX *mem_ctx,
1736 uint32 *num_domains,
1737 struct trustdom_info ***domains)
1739 return NT_STATUS_NOT_IMPLEMENTED;
1742 static void pdb_ads_init_methods(struct pdb_methods *m)
1745 m->getsampwnam = pdb_ads_getsampwnam;
1746 m->getsampwsid = pdb_ads_getsampwsid;
1747 m->create_user = pdb_ads_create_user;
1748 m->delete_user = pdb_ads_delete_user;
1749 m->add_sam_account = pdb_ads_add_sam_account;
1750 m->update_sam_account = pdb_ads_update_sam_account;
1751 m->delete_sam_account = pdb_ads_delete_sam_account;
1752 m->rename_sam_account = pdb_ads_rename_sam_account;
1753 m->update_login_attempts = pdb_ads_update_login_attempts;
1754 m->getgrsid = pdb_ads_getgrsid;
1755 m->getgrgid = pdb_ads_getgrgid;
1756 m->getgrnam = pdb_ads_getgrnam;
1757 m->create_dom_group = pdb_ads_create_dom_group;
1758 m->delete_dom_group = pdb_ads_delete_dom_group;
1759 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1760 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1761 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1762 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1763 m->enum_group_members = pdb_ads_enum_group_members;
1764 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1765 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1766 m->add_groupmem = pdb_ads_add_groupmem;
1767 m->del_groupmem = pdb_ads_del_groupmem;
1768 m->create_alias = pdb_ads_create_alias;
1769 m->delete_alias = pdb_ads_delete_alias;
1770 m->get_aliasinfo = pdb_ads_get_aliasinfo;
1771 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1772 m->add_aliasmem = pdb_ads_add_aliasmem;
1773 m->del_aliasmem = pdb_ads_del_aliasmem;
1774 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1775 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1776 m->lookup_rids = pdb_ads_lookup_rids;
1777 m->lookup_names = pdb_ads_lookup_names;
1778 m->get_account_policy = pdb_ads_get_account_policy;
1779 m->set_account_policy = pdb_ads_set_account_policy;
1780 m->get_seq_num = pdb_ads_get_seq_num;
1781 m->search_users = pdb_ads_search_users;
1782 m->search_groups = pdb_ads_search_groups;
1783 m->search_aliases = pdb_ads_search_aliases;
1784 m->uid_to_rid = pdb_ads_uid_to_rid;
1785 m->uid_to_sid = pdb_ads_uid_to_sid;
1786 m->gid_to_sid = pdb_ads_gid_to_sid;
1787 m->sid_to_id = pdb_ads_sid_to_id;
1788 m->rid_algorithm = pdb_ads_rid_algorithm;
1789 m->new_rid = pdb_ads_new_rid;
1790 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1791 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1792 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1793 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1796 static void free_private_data(void **vp)
1798 struct pdb_ads_state *state = talloc_get_type_abort(
1799 *vp, struct pdb_ads_state);
1801 TALLOC_FREE(state->ld);
1805 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1806 const char *location)
1808 const char *rootdse_attrs[2] = {
1809 "defaultNamingContext", "configurationNamingContext" };
1810 const char *domain_attrs[1] = { "objectSid" };
1811 const char *ncname_attrs[1] = { "netbiosname" };
1812 struct tldap_message **rootdse, **domain, **ncname;
1813 TALLOC_CTX *frame = talloc_stackframe();
1814 struct sockaddr_un sunaddr;
1819 ZERO_STRUCT(sunaddr);
1820 sunaddr.sun_family = AF_UNIX;
1821 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1823 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1825 if (!NT_STATUS_IS_OK(status)) {
1826 DEBUG(10, ("Could not connect to %s: %s\n", location,
1827 nt_errstr(status)));
1831 state->ld = tldap_context_create(state, fd);
1832 if (state->ld == NULL) {
1834 status = NT_STATUS_NO_MEMORY;
1838 rc = tldap_search_fmt(
1839 state->ld, "", TLDAP_SCOPE_BASE,
1840 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1841 talloc_tos(), &rootdse, "(objectclass=*)");
1842 if (rc != TLDAP_SUCCESS) {
1843 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1844 tldap_errstr(debug_ctx(), state->ld, rc)));
1845 status = NT_STATUS_LDAP(rc);
1848 if (talloc_array_length(rootdse) != 1) {
1849 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1853 state->domaindn = tldap_talloc_single_attribute(
1854 rootdse[0], "defaultNamingContext", state);
1855 if (state->domaindn == NULL) {
1856 DEBUG(10, ("Could not get defaultNamingContext\n"));
1857 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1860 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1862 state->configdn = tldap_talloc_single_attribute(
1863 rootdse[0], "configurationNamingContext", state);
1864 if (state->domaindn == NULL) {
1865 DEBUG(10, ("Could not get configurationNamingContext\n"));
1866 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1869 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1872 * Figure out our domain's SID
1874 rc = tldap_search_fmt(
1875 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1876 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1877 talloc_tos(), &domain, "(objectclass=*)");
1878 if (rc != TLDAP_SUCCESS) {
1879 DEBUG(10, ("Could not retrieve domain: %s\n",
1880 tldap_errstr(debug_ctx(), state->ld, rc)));
1881 status = NT_STATUS_LDAP(rc);
1885 num_domains = talloc_array_length(domain);
1886 if (num_domains != 1) {
1887 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1888 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1891 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1892 DEBUG(10, ("Could not retrieve domain SID\n"));
1893 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1896 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1899 * Figure out our domain's short name
1901 rc = tldap_search_fmt(
1902 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1903 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1904 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1905 if (rc != TLDAP_SUCCESS) {
1906 DEBUG(10, ("Could not retrieve ncname: %s\n",
1907 tldap_errstr(debug_ctx(), state->ld, rc)));
1908 status = NT_STATUS_LDAP(rc);
1911 if (talloc_array_length(ncname) != 1) {
1912 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1916 state->netbiosname = tldap_talloc_single_attribute(
1917 ncname[0], "netbiosname", state);
1918 if (state->netbiosname == NULL) {
1919 DEBUG(10, ("Could not get netbiosname\n"));
1920 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1923 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1925 if (!strequal(lp_workgroup(), state->netbiosname)) {
1926 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1927 state->netbiosname, lp_workgroup()));
1928 status = NT_STATUS_NO_SUCH_DOMAIN;
1932 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1934 status = NT_STATUS_OK;
1940 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1941 const char *location)
1943 struct pdb_methods *m;
1944 struct pdb_ads_state *state;
1948 m = talloc(talloc_autofree_context(), struct pdb_methods);
1950 return NT_STATUS_NO_MEMORY;
1952 state = talloc(m, struct pdb_ads_state);
1953 if (state == NULL) {
1956 m->private_data = state;
1957 m->free_private_data = free_private_data;
1958 pdb_ads_init_methods(m);
1960 if (location == NULL) {
1961 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1965 if (location == NULL) {
1969 status = pdb_ads_connect(state, location);
1970 if (!NT_STATUS_IS_OK(status)) {
1971 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1976 return NT_STATUS_OK;
1978 status = NT_STATUS_NO_MEMORY;
1984 NTSTATUS pdb_ads_init(void);
1985 NTSTATUS pdb_ads_init(void)
1987 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",