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_set_aliasinfo(struct pdb_methods *m,
1112 struct acct_info *info)
1114 return NT_STATUS_NOT_IMPLEMENTED;
1117 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1118 const struct dom_sid *sid,
1119 TALLOC_CTX *mem_ctx, char **pdn)
1121 struct tldap_message **msg;
1125 sidstr = sid_binstring(talloc_tos(), sid);
1126 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1128 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1129 NULL, 0, 0, talloc_tos(), &msg,
1130 "(objectsid=%s)", sidstr);
1131 TALLOC_FREE(sidstr);
1132 if (rc != TLDAP_SUCCESS) {
1133 DEBUG(10, ("ldap_search failed %s\n",
1134 tldap_errstr(debug_ctx(), state->ld, rc)));
1135 return NT_STATUS_LDAP(rc);
1138 switch talloc_array_length(msg) {
1140 return NT_STATUS_NOT_FOUND;
1144 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1147 if (!tldap_entry_dn(msg[0], &dn)) {
1148 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1151 dn = talloc_strdup(mem_ctx, dn);
1153 return NT_STATUS_NO_MEMORY;
1158 return NT_STATUS_OK;
1161 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1162 const DOM_SID *alias,
1163 const DOM_SID *member,
1166 struct pdb_ads_state *state = talloc_get_type_abort(
1167 m->private_data, struct pdb_ads_state);
1168 TALLOC_CTX *frame = talloc_stackframe();
1169 struct tldap_mod *mods;
1171 char *aliasdn, *memberdn;
1174 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1175 if (!NT_STATUS_IS_OK(status)) {
1176 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1177 sid_string_dbg(alias), nt_errstr(status)));
1179 return NT_STATUS_NO_SUCH_ALIAS;
1181 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1182 if (!NT_STATUS_IS_OK(status)) {
1183 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1184 sid_string_dbg(member), nt_errstr(status)));
1191 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1192 "member", memberdn)) {
1194 return NT_STATUS_NO_MEMORY;
1197 rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
1199 if (rc != TLDAP_SUCCESS) {
1200 DEBUG(10, ("ldap_modify failed: %s\n",
1201 tldap_errstr(debug_ctx(), state->ld, rc)));
1202 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1203 return NT_STATUS_MEMBER_IN_ALIAS;
1205 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1206 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1208 return NT_STATUS_LDAP(rc);
1211 return NT_STATUS_OK;
1214 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1215 const DOM_SID *alias,
1216 const DOM_SID *member)
1218 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1221 static NTSTATUS pdb_ads_del_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_DELETE);
1228 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1229 struct dom_sid *psid)
1231 const char *attrs[1] = { "objectSid" };
1232 struct tldap_message **msg;
1238 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1239 dnblob->data, dnblob->length, &dn, &len,
1243 rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1244 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1245 &msg, "(objectclass=*)");
1247 if (talloc_array_length(msg) != 1) {
1248 DEBUG(10, ("Got %d objects, expected one\n",
1249 (int)talloc_array_length(msg)));
1254 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1259 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1260 const DOM_SID *alias,
1261 TALLOC_CTX *mem_ctx,
1263 size_t *pnum_members)
1265 struct pdb_ads_state *state = talloc_get_type_abort(
1266 m->private_data, struct pdb_ads_state);
1267 const char *attrs[1] = { "member" };
1269 struct tldap_message **msg;
1270 int i, rc, num_members;
1272 struct dom_sid *members;
1274 sidstr = sid_binstring(talloc_tos(), alias);
1275 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1277 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1278 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1279 "(objectsid=%s)", sidstr);
1280 TALLOC_FREE(sidstr);
1281 if (rc != TLDAP_SUCCESS) {
1282 DEBUG(10, ("ldap_search failed %s\n",
1283 tldap_errstr(debug_ctx(), state->ld, rc)));
1284 return NT_STATUS_LDAP(rc);
1286 switch talloc_array_length(msg) {
1288 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1293 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1297 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1298 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1301 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1302 if (members == NULL) {
1303 return NT_STATUS_NO_MEMORY;
1306 for (i=0; i<num_members; i++) {
1307 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1308 TALLOC_FREE(members);
1309 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1313 *pmembers = members;
1314 *pnum_members = num_members;
1315 return NT_STATUS_OK;
1318 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1319 TALLOC_CTX *mem_ctx,
1320 const DOM_SID *domain_sid,
1321 const DOM_SID *members,
1323 uint32 **pp_alias_rids,
1324 size_t *p_num_alias_rids)
1326 return NT_STATUS_NOT_IMPLEMENTED;
1329 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1330 const DOM_SID *domain_sid,
1334 enum lsa_SidType *lsa_attrs)
1336 struct pdb_ads_state *state = talloc_get_type_abort(
1337 m->private_data, struct pdb_ads_state);
1338 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1341 if (num_rids == 0) {
1342 return NT_STATUS_NONE_MAPPED;
1347 for (i=0; i<num_rids; i++) {
1349 struct tldap_message **msg;
1354 lsa_attrs[i] = SID_NAME_UNKNOWN;
1356 sid_compose(&sid, domain_sid, rids[i]);
1358 sidstr = sid_binstring(talloc_tos(), &sid);
1359 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1361 rc = tldap_search_fmt(state->ld, state->domaindn,
1362 TLDAP_SCOPE_SUB, attrs,
1363 ARRAY_SIZE(attrs), 0, talloc_tos(),
1364 &msg, "(objectsid=%s)", sidstr);
1365 TALLOC_FREE(sidstr);
1366 if (rc != TLDAP_SUCCESS) {
1367 DEBUG(10, ("ldap_search failed %s\n",
1368 tldap_errstr(debug_ctx(), state->ld, rc)));
1372 switch talloc_array_length(msg) {
1374 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1379 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1382 names[i] = tldap_talloc_single_attribute(
1383 msg[0], "samAccountName", talloc_tos());
1384 if (names[i] == NULL) {
1385 DEBUG(10, ("no samAccountName\n"));
1388 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1389 DEBUG(10, ("no samAccountType"));
1392 lsa_attrs[i] = ads_atype_map(attr);
1396 if (num_mapped == 0) {
1397 return NT_STATUS_NONE_MAPPED;
1399 if (num_mapped < num_rids) {
1400 return STATUS_SOME_UNMAPPED;
1402 return NT_STATUS_OK;
1405 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1406 const DOM_SID *domain_sid,
1408 const char **pp_names,
1410 enum lsa_SidType *attrs)
1412 return NT_STATUS_NOT_IMPLEMENTED;
1415 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1416 int policy_index, uint32 *value)
1418 return account_policy_get(policy_index, value)
1419 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1422 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1423 int policy_index, uint32 value)
1425 return account_policy_set(policy_index, value)
1426 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1429 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1432 return NT_STATUS_NOT_IMPLEMENTED;
1435 struct pdb_ads_search_state {
1436 uint32_t acct_flags;
1437 struct samr_displayentry *entries;
1438 uint32_t num_entries;
1443 static bool pdb_ads_next_entry(struct pdb_search *search,
1444 struct samr_displayentry *entry)
1446 struct pdb_ads_search_state *state = talloc_get_type_abort(
1447 search->private_data, struct pdb_ads_search_state);
1449 if (state->current == state->num_entries) {
1453 entry->idx = state->entries[state->current].idx;
1454 entry->rid = state->entries[state->current].rid;
1455 entry->acct_flags = state->entries[state->current].acct_flags;
1457 entry->account_name = talloc_strdup(
1458 search, state->entries[state->current].account_name);
1459 entry->fullname = talloc_strdup(
1460 search, state->entries[state->current].fullname);
1461 entry->description = talloc_strdup(
1462 search, state->entries[state->current].description);
1464 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1465 || (entry->description == NULL)) {
1466 DEBUG(0, ("talloc_strdup failed\n"));
1470 state->current += 1;
1474 static void pdb_ads_search_end(struct pdb_search *search)
1476 struct pdb_ads_search_state *state = talloc_get_type_abort(
1477 search->private_data, struct pdb_ads_search_state);
1481 static bool pdb_ads_search_filter(struct pdb_methods *m,
1482 struct pdb_search *search,
1484 struct pdb_ads_search_state **pstate)
1486 struct pdb_ads_state *state = talloc_get_type_abort(
1487 m->private_data, struct pdb_ads_state);
1488 struct pdb_ads_search_state *sstate;
1489 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1490 "userAccountControl", "description" };
1491 struct tldap_message **users;
1492 int i, rc, num_users;
1494 sstate = talloc_zero(search, struct pdb_ads_search_state);
1495 if (sstate == NULL) {
1499 rc = tldap_search_fmt(
1500 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1501 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1503 if (rc != TLDAP_SUCCESS) {
1504 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1505 tldap_errstr(debug_ctx(), state->ld, rc)));
1509 num_users = talloc_array_length(users);
1511 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1513 if (sstate->entries == NULL) {
1514 DEBUG(10, ("talloc failed\n"));
1518 sstate->num_entries = 0;
1520 for (i=0; i<num_users; i++) {
1521 struct samr_displayentry *e;
1524 e = &sstate->entries[sstate->num_entries];
1526 e->idx = sstate->num_entries;
1527 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1528 DEBUG(10, ("Could not pull sid\n"));
1531 sid_peek_rid(&sid, &e->rid);
1532 e->acct_flags = ACB_NORMAL;
1533 e->account_name = tldap_talloc_single_attribute(
1534 users[i], "samAccountName", sstate->entries);
1535 if (e->account_name == NULL) {
1538 e->fullname = tldap_talloc_single_attribute(
1539 users[i], "displayName", sstate->entries);
1540 if (e->fullname == NULL) {
1543 e->description = tldap_talloc_single_attribute(
1544 users[i], "description", sstate->entries);
1545 if (e->description == NULL) {
1546 e->description = "";
1549 sstate->num_entries += 1;
1550 if (sstate->num_entries >= num_users) {
1555 search->private_data = sstate;
1556 search->next_entry = pdb_ads_next_entry;
1557 search->search_end = pdb_ads_search_end;
1562 static bool pdb_ads_search_users(struct pdb_methods *m,
1563 struct pdb_search *search,
1566 struct pdb_ads_search_state *sstate;
1569 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1573 sstate->acct_flags = acct_flags;
1577 static bool pdb_ads_search_groups(struct pdb_methods *m,
1578 struct pdb_search *search)
1580 struct pdb_ads_search_state *sstate;
1584 filter = talloc_asprintf(talloc_tos(),
1585 "(&(grouptype=%d)(objectclass=group))",
1586 GTYPE_SECURITY_GLOBAL_GROUP);
1587 if (filter == NULL) {
1590 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1591 TALLOC_FREE(filter);
1595 sstate->acct_flags = 0;
1599 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1600 struct pdb_search *search,
1603 struct pdb_ads_search_state *sstate;
1607 filter = talloc_asprintf(
1608 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1609 sid_check_is_builtin(sid)
1610 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1611 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1613 if (filter == NULL) {
1616 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1617 TALLOC_FREE(filter);
1621 sstate->acct_flags = 0;
1625 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1631 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1634 struct pdb_ads_state *state = talloc_get_type_abort(
1635 m->private_data, struct pdb_ads_state);
1636 sid_compose(sid, &state->domainsid, uid);
1640 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1643 struct pdb_ads_state *state = talloc_get_type_abort(
1644 m->private_data, struct pdb_ads_state);
1645 sid_compose(sid, &state->domainsid, gid);
1649 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1650 union unid_t *id, enum lsa_SidType *type)
1652 struct pdb_ads_state *state = talloc_get_type_abort(
1653 m->private_data, struct pdb_ads_state);
1654 struct tldap_message **msg;
1660 * This is a big, big hack: Just hard-code the rid as uid/gid.
1663 sid_peek_rid(sid, &rid);
1665 sidstr = sid_binstring(talloc_tos(), sid);
1666 if (sidstr == NULL) {
1670 rc = tldap_search_fmt(
1671 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1672 NULL, 0, 0, talloc_tos(), &msg,
1673 "(&(objectsid=%s)(objectclass=user))", sidstr);
1674 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1676 *type = SID_NAME_USER;
1677 TALLOC_FREE(sidstr);
1681 rc = tldap_search_fmt(
1682 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1683 NULL, 0, 0, talloc_tos(), &msg,
1684 "(&(objectsid=%s)(objectclass=group))", sidstr);
1685 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1687 *type = SID_NAME_DOM_GRP;
1688 TALLOC_FREE(sidstr);
1692 TALLOC_FREE(sidstr);
1696 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1701 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1706 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1707 const char *domain, char** pwd,
1709 time_t *pass_last_set_time)
1714 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1715 const char* domain, const char* pwd,
1721 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1727 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1728 TALLOC_CTX *mem_ctx,
1729 uint32 *num_domains,
1730 struct trustdom_info ***domains)
1732 return NT_STATUS_NOT_IMPLEMENTED;
1735 static void pdb_ads_init_methods(struct pdb_methods *m)
1738 m->getsampwnam = pdb_ads_getsampwnam;
1739 m->getsampwsid = pdb_ads_getsampwsid;
1740 m->create_user = pdb_ads_create_user;
1741 m->delete_user = pdb_ads_delete_user;
1742 m->add_sam_account = pdb_ads_add_sam_account;
1743 m->update_sam_account = pdb_ads_update_sam_account;
1744 m->delete_sam_account = pdb_ads_delete_sam_account;
1745 m->rename_sam_account = pdb_ads_rename_sam_account;
1746 m->update_login_attempts = pdb_ads_update_login_attempts;
1747 m->getgrsid = pdb_ads_getgrsid;
1748 m->getgrgid = pdb_ads_getgrgid;
1749 m->getgrnam = pdb_ads_getgrnam;
1750 m->create_dom_group = pdb_ads_create_dom_group;
1751 m->delete_dom_group = pdb_ads_delete_dom_group;
1752 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1753 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1754 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1755 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1756 m->enum_group_members = pdb_ads_enum_group_members;
1757 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1758 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1759 m->add_groupmem = pdb_ads_add_groupmem;
1760 m->del_groupmem = pdb_ads_del_groupmem;
1761 m->create_alias = pdb_ads_create_alias;
1762 m->delete_alias = pdb_ads_delete_alias;
1763 m->get_aliasinfo = pdb_default_get_aliasinfo;
1764 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1765 m->add_aliasmem = pdb_ads_add_aliasmem;
1766 m->del_aliasmem = pdb_ads_del_aliasmem;
1767 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1768 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1769 m->lookup_rids = pdb_ads_lookup_rids;
1770 m->lookup_names = pdb_ads_lookup_names;
1771 m->get_account_policy = pdb_ads_get_account_policy;
1772 m->set_account_policy = pdb_ads_set_account_policy;
1773 m->get_seq_num = pdb_ads_get_seq_num;
1774 m->search_users = pdb_ads_search_users;
1775 m->search_groups = pdb_ads_search_groups;
1776 m->search_aliases = pdb_ads_search_aliases;
1777 m->uid_to_rid = pdb_ads_uid_to_rid;
1778 m->uid_to_sid = pdb_ads_uid_to_sid;
1779 m->gid_to_sid = pdb_ads_gid_to_sid;
1780 m->sid_to_id = pdb_ads_sid_to_id;
1781 m->rid_algorithm = pdb_ads_rid_algorithm;
1782 m->new_rid = pdb_ads_new_rid;
1783 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1784 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1785 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1786 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1789 static void free_private_data(void **vp)
1791 struct pdb_ads_state *state = talloc_get_type_abort(
1792 *vp, struct pdb_ads_state);
1794 TALLOC_FREE(state->ld);
1798 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1799 const char *location)
1801 const char *rootdse_attrs[2] = {
1802 "defaultNamingContext", "configurationNamingContext" };
1803 const char *domain_attrs[1] = { "objectSid" };
1804 const char *ncname_attrs[1] = { "netbiosname" };
1805 struct tldap_message **rootdse, **domain, **ncname;
1806 TALLOC_CTX *frame = talloc_stackframe();
1807 struct sockaddr_un sunaddr;
1812 ZERO_STRUCT(sunaddr);
1813 sunaddr.sun_family = AF_UNIX;
1814 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1816 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1818 if (!NT_STATUS_IS_OK(status)) {
1819 DEBUG(10, ("Could not connect to %s: %s\n", location,
1820 nt_errstr(status)));
1824 state->ld = tldap_context_create(state, fd);
1825 if (state->ld == NULL) {
1827 status = NT_STATUS_NO_MEMORY;
1831 rc = tldap_search_fmt(
1832 state->ld, "", TLDAP_SCOPE_BASE,
1833 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1834 talloc_tos(), &rootdse, "(objectclass=*)");
1835 if (rc != TLDAP_SUCCESS) {
1836 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1837 tldap_errstr(debug_ctx(), state->ld, rc)));
1838 status = NT_STATUS_LDAP(rc);
1841 if (talloc_array_length(rootdse) != 1) {
1842 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1846 state->domaindn = tldap_talloc_single_attribute(
1847 rootdse[0], "defaultNamingContext", state);
1848 if (state->domaindn == NULL) {
1849 DEBUG(10, ("Could not get defaultNamingContext\n"));
1850 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1853 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1855 state->configdn = tldap_talloc_single_attribute(
1856 rootdse[0], "configurationNamingContext", state);
1857 if (state->domaindn == NULL) {
1858 DEBUG(10, ("Could not get configurationNamingContext\n"));
1859 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1862 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1865 * Figure out our domain's SID
1867 rc = tldap_search_fmt(
1868 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1869 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1870 talloc_tos(), &domain, "(objectclass=*)");
1871 if (rc != TLDAP_SUCCESS) {
1872 DEBUG(10, ("Could not retrieve domain: %s\n",
1873 tldap_errstr(debug_ctx(), state->ld, rc)));
1874 status = NT_STATUS_LDAP(rc);
1878 num_domains = talloc_array_length(domain);
1879 if (num_domains != 1) {
1880 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1881 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1884 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1885 DEBUG(10, ("Could not retrieve domain SID\n"));
1886 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1889 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1892 * Figure out our domain's short name
1894 rc = tldap_search_fmt(
1895 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1896 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1897 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1898 if (rc != TLDAP_SUCCESS) {
1899 DEBUG(10, ("Could not retrieve ncname: %s\n",
1900 tldap_errstr(debug_ctx(), state->ld, rc)));
1901 status = NT_STATUS_LDAP(rc);
1904 if (talloc_array_length(ncname) != 1) {
1905 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1909 state->netbiosname = tldap_talloc_single_attribute(
1910 ncname[0], "netbiosname", state);
1911 if (state->netbiosname == NULL) {
1912 DEBUG(10, ("Could not get netbiosname\n"));
1913 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1916 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1918 if (!strequal(lp_workgroup(), state->netbiosname)) {
1919 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1920 state->netbiosname, lp_workgroup()));
1921 status = NT_STATUS_NO_SUCH_DOMAIN;
1925 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1927 status = NT_STATUS_OK;
1933 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1934 const char *location)
1936 struct pdb_methods *m;
1937 struct pdb_ads_state *state;
1941 m = talloc(talloc_autofree_context(), struct pdb_methods);
1943 return NT_STATUS_NO_MEMORY;
1945 state = talloc(m, struct pdb_ads_state);
1946 if (state == NULL) {
1949 m->private_data = state;
1950 m->free_private_data = free_private_data;
1951 pdb_ads_init_methods(m);
1953 if (location == NULL) {
1954 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1958 if (location == NULL) {
1962 status = pdb_ads_connect(state, location);
1963 if (!NT_STATUS_IS_OK(status)) {
1964 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1969 return NT_STATUS_OK;
1971 status = NT_STATUS_NO_MEMORY;
1977 NTSTATUS pdb_ads_init(void);
1978 NTSTATUS pdb_ads_init(void)
1980 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",