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 struct pdb_ads_state *state = talloc_get_type_abort(
1115 m->private_data, struct pdb_ads_state);
1116 const char *attrs[3] = { "objectSid", "description",
1118 struct tldap_message **msg;
1121 struct tldap_mod *mods;
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 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1130 &msg, "(&(objectSid=%s)(objectclass=group)"
1131 "(|(grouptype=%d)(grouptype=%d)))",
1132 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1133 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1134 TALLOC_FREE(sidstr);
1135 if (rc != TLDAP_SUCCESS) {
1136 DEBUG(10, ("ldap_search failed %s\n",
1137 tldap_errstr(debug_ctx(), state->ld, rc)));
1138 return NT_STATUS_LDAP(rc);
1140 switch talloc_array_length(msg) {
1142 return NT_STATUS_NO_SUCH_ALIAS;
1146 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1149 if (!tldap_entry_dn(msg[0], &dn)) {
1151 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1158 ok &= tldap_make_mod_fmt(
1159 msg[0], msg, &num_mods, &mods, "description",
1160 "%s", info->acct_desc);
1161 ok &= tldap_make_mod_fmt(
1162 msg[0], msg, &num_mods, &mods, "samAccountName",
1163 "%s", info->acct_name);
1166 return NT_STATUS_NO_MEMORY;
1168 if (num_mods == 0) {
1171 return NT_STATUS_OK;
1174 rc = tldap_modify(state->ld, dn, num_mods, mods, NULL, NULL);
1176 if (rc != TLDAP_SUCCESS) {
1177 DEBUG(10, ("ldap_modify failed: %s\n",
1178 tldap_errstr(debug_ctx(), state->ld, rc)));
1179 return NT_STATUS_LDAP(rc);
1181 return NT_STATUS_OK;
1184 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1185 const struct dom_sid *sid,
1186 TALLOC_CTX *mem_ctx, char **pdn)
1188 struct tldap_message **msg;
1192 sidstr = sid_binstring(talloc_tos(), sid);
1193 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1195 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1196 NULL, 0, 0, talloc_tos(), &msg,
1197 "(objectsid=%s)", sidstr);
1198 TALLOC_FREE(sidstr);
1199 if (rc != TLDAP_SUCCESS) {
1200 DEBUG(10, ("ldap_search failed %s\n",
1201 tldap_errstr(debug_ctx(), state->ld, rc)));
1202 return NT_STATUS_LDAP(rc);
1205 switch talloc_array_length(msg) {
1207 return NT_STATUS_NOT_FOUND;
1211 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1214 if (!tldap_entry_dn(msg[0], &dn)) {
1215 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1218 dn = talloc_strdup(mem_ctx, dn);
1220 return NT_STATUS_NO_MEMORY;
1225 return NT_STATUS_OK;
1228 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1229 const DOM_SID *alias,
1230 const DOM_SID *member,
1233 struct pdb_ads_state *state = talloc_get_type_abort(
1234 m->private_data, struct pdb_ads_state);
1235 TALLOC_CTX *frame = talloc_stackframe();
1236 struct tldap_mod *mods;
1238 char *aliasdn, *memberdn;
1241 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1242 if (!NT_STATUS_IS_OK(status)) {
1243 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1244 sid_string_dbg(alias), nt_errstr(status)));
1246 return NT_STATUS_NO_SUCH_ALIAS;
1248 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1249 if (!NT_STATUS_IS_OK(status)) {
1250 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1251 sid_string_dbg(member), nt_errstr(status)));
1258 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1259 "member", memberdn)) {
1261 return NT_STATUS_NO_MEMORY;
1264 rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
1266 if (rc != TLDAP_SUCCESS) {
1267 DEBUG(10, ("ldap_modify failed: %s\n",
1268 tldap_errstr(debug_ctx(), state->ld, rc)));
1269 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1270 return NT_STATUS_MEMBER_IN_ALIAS;
1272 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1273 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1275 return NT_STATUS_LDAP(rc);
1278 return NT_STATUS_OK;
1281 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1282 const DOM_SID *alias,
1283 const DOM_SID *member)
1285 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1288 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1289 const DOM_SID *alias,
1290 const DOM_SID *member)
1292 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1295 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1296 struct dom_sid *psid)
1298 const char *attrs[1] = { "objectSid" };
1299 struct tldap_message **msg;
1305 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1306 dnblob->data, dnblob->length, &dn, &len,
1310 rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1311 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1312 &msg, "(objectclass=*)");
1314 if (talloc_array_length(msg) != 1) {
1315 DEBUG(10, ("Got %d objects, expected one\n",
1316 (int)talloc_array_length(msg)));
1321 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1326 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1327 const DOM_SID *alias,
1328 TALLOC_CTX *mem_ctx,
1330 size_t *pnum_members)
1332 struct pdb_ads_state *state = talloc_get_type_abort(
1333 m->private_data, struct pdb_ads_state);
1334 const char *attrs[1] = { "member" };
1336 struct tldap_message **msg;
1337 int i, rc, num_members;
1339 struct dom_sid *members;
1341 sidstr = sid_binstring(talloc_tos(), alias);
1342 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1344 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1345 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1346 "(objectsid=%s)", sidstr);
1347 TALLOC_FREE(sidstr);
1348 if (rc != TLDAP_SUCCESS) {
1349 DEBUG(10, ("ldap_search failed %s\n",
1350 tldap_errstr(debug_ctx(), state->ld, rc)));
1351 return NT_STATUS_LDAP(rc);
1353 switch talloc_array_length(msg) {
1355 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1360 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1364 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1365 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1368 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1369 if (members == NULL) {
1370 return NT_STATUS_NO_MEMORY;
1373 for (i=0; i<num_members; i++) {
1374 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1375 TALLOC_FREE(members);
1376 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1380 *pmembers = members;
1381 *pnum_members = num_members;
1382 return NT_STATUS_OK;
1385 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1386 TALLOC_CTX *mem_ctx,
1387 const DOM_SID *domain_sid,
1388 const DOM_SID *members,
1390 uint32 **pp_alias_rids,
1391 size_t *p_num_alias_rids)
1393 return NT_STATUS_NOT_IMPLEMENTED;
1396 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1397 const DOM_SID *domain_sid,
1401 enum lsa_SidType *lsa_attrs)
1403 struct pdb_ads_state *state = talloc_get_type_abort(
1404 m->private_data, struct pdb_ads_state);
1405 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1408 if (num_rids == 0) {
1409 return NT_STATUS_NONE_MAPPED;
1414 for (i=0; i<num_rids; i++) {
1416 struct tldap_message **msg;
1421 lsa_attrs[i] = SID_NAME_UNKNOWN;
1423 sid_compose(&sid, domain_sid, rids[i]);
1425 sidstr = sid_binstring(talloc_tos(), &sid);
1426 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1428 rc = tldap_search_fmt(state->ld, state->domaindn,
1429 TLDAP_SCOPE_SUB, attrs,
1430 ARRAY_SIZE(attrs), 0, talloc_tos(),
1431 &msg, "(objectsid=%s)", sidstr);
1432 TALLOC_FREE(sidstr);
1433 if (rc != TLDAP_SUCCESS) {
1434 DEBUG(10, ("ldap_search failed %s\n",
1435 tldap_errstr(debug_ctx(), state->ld, rc)));
1439 switch talloc_array_length(msg) {
1441 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1446 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1449 names[i] = tldap_talloc_single_attribute(
1450 msg[0], "samAccountName", talloc_tos());
1451 if (names[i] == NULL) {
1452 DEBUG(10, ("no samAccountName\n"));
1455 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1456 DEBUG(10, ("no samAccountType"));
1459 lsa_attrs[i] = ads_atype_map(attr);
1463 if (num_mapped == 0) {
1464 return NT_STATUS_NONE_MAPPED;
1466 if (num_mapped < num_rids) {
1467 return STATUS_SOME_UNMAPPED;
1469 return NT_STATUS_OK;
1472 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1473 const DOM_SID *domain_sid,
1475 const char **pp_names,
1477 enum lsa_SidType *attrs)
1479 return NT_STATUS_NOT_IMPLEMENTED;
1482 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1483 int policy_index, uint32 *value)
1485 return account_policy_get(policy_index, value)
1486 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1489 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1490 int policy_index, uint32 value)
1492 return account_policy_set(policy_index, value)
1493 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1496 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1499 return NT_STATUS_NOT_IMPLEMENTED;
1502 struct pdb_ads_search_state {
1503 uint32_t acct_flags;
1504 struct samr_displayentry *entries;
1505 uint32_t num_entries;
1510 static bool pdb_ads_next_entry(struct pdb_search *search,
1511 struct samr_displayentry *entry)
1513 struct pdb_ads_search_state *state = talloc_get_type_abort(
1514 search->private_data, struct pdb_ads_search_state);
1516 if (state->current == state->num_entries) {
1520 entry->idx = state->entries[state->current].idx;
1521 entry->rid = state->entries[state->current].rid;
1522 entry->acct_flags = state->entries[state->current].acct_flags;
1524 entry->account_name = talloc_strdup(
1525 search, state->entries[state->current].account_name);
1526 entry->fullname = talloc_strdup(
1527 search, state->entries[state->current].fullname);
1528 entry->description = talloc_strdup(
1529 search, state->entries[state->current].description);
1531 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1532 || (entry->description == NULL)) {
1533 DEBUG(0, ("talloc_strdup failed\n"));
1537 state->current += 1;
1541 static void pdb_ads_search_end(struct pdb_search *search)
1543 struct pdb_ads_search_state *state = talloc_get_type_abort(
1544 search->private_data, struct pdb_ads_search_state);
1548 static bool pdb_ads_search_filter(struct pdb_methods *m,
1549 struct pdb_search *search,
1551 struct pdb_ads_search_state **pstate)
1553 struct pdb_ads_state *state = talloc_get_type_abort(
1554 m->private_data, struct pdb_ads_state);
1555 struct pdb_ads_search_state *sstate;
1556 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1557 "userAccountControl", "description" };
1558 struct tldap_message **users;
1559 int i, rc, num_users;
1561 sstate = talloc_zero(search, struct pdb_ads_search_state);
1562 if (sstate == NULL) {
1566 rc = tldap_search_fmt(
1567 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1568 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1570 if (rc != TLDAP_SUCCESS) {
1571 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1572 tldap_errstr(debug_ctx(), state->ld, rc)));
1576 num_users = talloc_array_length(users);
1578 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1580 if (sstate->entries == NULL) {
1581 DEBUG(10, ("talloc failed\n"));
1585 sstate->num_entries = 0;
1587 for (i=0; i<num_users; i++) {
1588 struct samr_displayentry *e;
1591 e = &sstate->entries[sstate->num_entries];
1593 e->idx = sstate->num_entries;
1594 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1595 DEBUG(10, ("Could not pull sid\n"));
1598 sid_peek_rid(&sid, &e->rid);
1599 e->acct_flags = ACB_NORMAL;
1600 e->account_name = tldap_talloc_single_attribute(
1601 users[i], "samAccountName", sstate->entries);
1602 if (e->account_name == NULL) {
1605 e->fullname = tldap_talloc_single_attribute(
1606 users[i], "displayName", sstate->entries);
1607 if (e->fullname == NULL) {
1610 e->description = tldap_talloc_single_attribute(
1611 users[i], "description", sstate->entries);
1612 if (e->description == NULL) {
1613 e->description = "";
1616 sstate->num_entries += 1;
1617 if (sstate->num_entries >= num_users) {
1622 search->private_data = sstate;
1623 search->next_entry = pdb_ads_next_entry;
1624 search->search_end = pdb_ads_search_end;
1629 static bool pdb_ads_search_users(struct pdb_methods *m,
1630 struct pdb_search *search,
1633 struct pdb_ads_search_state *sstate;
1636 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1640 sstate->acct_flags = acct_flags;
1644 static bool pdb_ads_search_groups(struct pdb_methods *m,
1645 struct pdb_search *search)
1647 struct pdb_ads_search_state *sstate;
1651 filter = talloc_asprintf(talloc_tos(),
1652 "(&(grouptype=%d)(objectclass=group))",
1653 GTYPE_SECURITY_GLOBAL_GROUP);
1654 if (filter == NULL) {
1657 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1658 TALLOC_FREE(filter);
1662 sstate->acct_flags = 0;
1666 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1667 struct pdb_search *search,
1670 struct pdb_ads_search_state *sstate;
1674 filter = talloc_asprintf(
1675 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1676 sid_check_is_builtin(sid)
1677 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1678 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1680 if (filter == NULL) {
1683 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1684 TALLOC_FREE(filter);
1688 sstate->acct_flags = 0;
1692 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1698 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1701 struct pdb_ads_state *state = talloc_get_type_abort(
1702 m->private_data, struct pdb_ads_state);
1703 sid_compose(sid, &state->domainsid, uid);
1707 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1710 struct pdb_ads_state *state = talloc_get_type_abort(
1711 m->private_data, struct pdb_ads_state);
1712 sid_compose(sid, &state->domainsid, gid);
1716 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1717 union unid_t *id, enum lsa_SidType *type)
1719 struct pdb_ads_state *state = talloc_get_type_abort(
1720 m->private_data, struct pdb_ads_state);
1721 struct tldap_message **msg;
1727 * This is a big, big hack: Just hard-code the rid as uid/gid.
1730 sid_peek_rid(sid, &rid);
1732 sidstr = sid_binstring(talloc_tos(), sid);
1733 if (sidstr == NULL) {
1737 rc = tldap_search_fmt(
1738 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1739 NULL, 0, 0, talloc_tos(), &msg,
1740 "(&(objectsid=%s)(objectclass=user))", sidstr);
1741 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1743 *type = SID_NAME_USER;
1744 TALLOC_FREE(sidstr);
1748 rc = tldap_search_fmt(
1749 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1750 NULL, 0, 0, talloc_tos(), &msg,
1751 "(&(objectsid=%s)(objectclass=group))", sidstr);
1752 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1754 *type = SID_NAME_DOM_GRP;
1755 TALLOC_FREE(sidstr);
1759 TALLOC_FREE(sidstr);
1763 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1768 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1773 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1774 const char *domain, char** pwd,
1776 time_t *pass_last_set_time)
1781 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1782 const char* domain, const char* pwd,
1788 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1794 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1795 TALLOC_CTX *mem_ctx,
1796 uint32 *num_domains,
1797 struct trustdom_info ***domains)
1799 return NT_STATUS_NOT_IMPLEMENTED;
1802 static void pdb_ads_init_methods(struct pdb_methods *m)
1805 m->getsampwnam = pdb_ads_getsampwnam;
1806 m->getsampwsid = pdb_ads_getsampwsid;
1807 m->create_user = pdb_ads_create_user;
1808 m->delete_user = pdb_ads_delete_user;
1809 m->add_sam_account = pdb_ads_add_sam_account;
1810 m->update_sam_account = pdb_ads_update_sam_account;
1811 m->delete_sam_account = pdb_ads_delete_sam_account;
1812 m->rename_sam_account = pdb_ads_rename_sam_account;
1813 m->update_login_attempts = pdb_ads_update_login_attempts;
1814 m->getgrsid = pdb_ads_getgrsid;
1815 m->getgrgid = pdb_ads_getgrgid;
1816 m->getgrnam = pdb_ads_getgrnam;
1817 m->create_dom_group = pdb_ads_create_dom_group;
1818 m->delete_dom_group = pdb_ads_delete_dom_group;
1819 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1820 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1821 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1822 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1823 m->enum_group_members = pdb_ads_enum_group_members;
1824 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1825 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1826 m->add_groupmem = pdb_ads_add_groupmem;
1827 m->del_groupmem = pdb_ads_del_groupmem;
1828 m->create_alias = pdb_ads_create_alias;
1829 m->delete_alias = pdb_ads_delete_alias;
1830 m->get_aliasinfo = pdb_default_get_aliasinfo;
1831 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1832 m->add_aliasmem = pdb_ads_add_aliasmem;
1833 m->del_aliasmem = pdb_ads_del_aliasmem;
1834 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1835 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1836 m->lookup_rids = pdb_ads_lookup_rids;
1837 m->lookup_names = pdb_ads_lookup_names;
1838 m->get_account_policy = pdb_ads_get_account_policy;
1839 m->set_account_policy = pdb_ads_set_account_policy;
1840 m->get_seq_num = pdb_ads_get_seq_num;
1841 m->search_users = pdb_ads_search_users;
1842 m->search_groups = pdb_ads_search_groups;
1843 m->search_aliases = pdb_ads_search_aliases;
1844 m->uid_to_rid = pdb_ads_uid_to_rid;
1845 m->uid_to_sid = pdb_ads_uid_to_sid;
1846 m->gid_to_sid = pdb_ads_gid_to_sid;
1847 m->sid_to_id = pdb_ads_sid_to_id;
1848 m->rid_algorithm = pdb_ads_rid_algorithm;
1849 m->new_rid = pdb_ads_new_rid;
1850 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1851 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1852 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1853 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1856 static void free_private_data(void **vp)
1858 struct pdb_ads_state *state = talloc_get_type_abort(
1859 *vp, struct pdb_ads_state);
1861 TALLOC_FREE(state->ld);
1865 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1866 const char *location)
1868 const char *rootdse_attrs[2] = {
1869 "defaultNamingContext", "configurationNamingContext" };
1870 const char *domain_attrs[1] = { "objectSid" };
1871 const char *ncname_attrs[1] = { "netbiosname" };
1872 struct tldap_message **rootdse, **domain, **ncname;
1873 TALLOC_CTX *frame = talloc_stackframe();
1874 struct sockaddr_un sunaddr;
1879 ZERO_STRUCT(sunaddr);
1880 sunaddr.sun_family = AF_UNIX;
1881 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1883 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1885 if (!NT_STATUS_IS_OK(status)) {
1886 DEBUG(10, ("Could not connect to %s: %s\n", location,
1887 nt_errstr(status)));
1891 state->ld = tldap_context_create(state, fd);
1892 if (state->ld == NULL) {
1894 status = NT_STATUS_NO_MEMORY;
1898 rc = tldap_search_fmt(
1899 state->ld, "", TLDAP_SCOPE_BASE,
1900 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1901 talloc_tos(), &rootdse, "(objectclass=*)");
1902 if (rc != TLDAP_SUCCESS) {
1903 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1904 tldap_errstr(debug_ctx(), state->ld, rc)));
1905 status = NT_STATUS_LDAP(rc);
1908 if (talloc_array_length(rootdse) != 1) {
1909 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1913 state->domaindn = tldap_talloc_single_attribute(
1914 rootdse[0], "defaultNamingContext", state);
1915 if (state->domaindn == NULL) {
1916 DEBUG(10, ("Could not get defaultNamingContext\n"));
1917 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1920 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1922 state->configdn = tldap_talloc_single_attribute(
1923 rootdse[0], "configurationNamingContext", state);
1924 if (state->domaindn == NULL) {
1925 DEBUG(10, ("Could not get configurationNamingContext\n"));
1926 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1929 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1932 * Figure out our domain's SID
1934 rc = tldap_search_fmt(
1935 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1936 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1937 talloc_tos(), &domain, "(objectclass=*)");
1938 if (rc != TLDAP_SUCCESS) {
1939 DEBUG(10, ("Could not retrieve domain: %s\n",
1940 tldap_errstr(debug_ctx(), state->ld, rc)));
1941 status = NT_STATUS_LDAP(rc);
1945 num_domains = talloc_array_length(domain);
1946 if (num_domains != 1) {
1947 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1948 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1951 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1952 DEBUG(10, ("Could not retrieve domain SID\n"));
1953 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1956 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1959 * Figure out our domain's short name
1961 rc = tldap_search_fmt(
1962 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1963 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1964 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1965 if (rc != TLDAP_SUCCESS) {
1966 DEBUG(10, ("Could not retrieve ncname: %s\n",
1967 tldap_errstr(debug_ctx(), state->ld, rc)));
1968 status = NT_STATUS_LDAP(rc);
1971 if (talloc_array_length(ncname) != 1) {
1972 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1976 state->netbiosname = tldap_talloc_single_attribute(
1977 ncname[0], "netbiosname", state);
1978 if (state->netbiosname == NULL) {
1979 DEBUG(10, ("Could not get netbiosname\n"));
1980 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1983 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1985 if (!strequal(lp_workgroup(), state->netbiosname)) {
1986 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1987 state->netbiosname, lp_workgroup()));
1988 status = NT_STATUS_NO_SUCH_DOMAIN;
1992 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1994 status = NT_STATUS_OK;
2000 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2001 const char *location)
2003 struct pdb_methods *m;
2004 struct pdb_ads_state *state;
2008 m = talloc(talloc_autofree_context(), struct pdb_methods);
2010 return NT_STATUS_NO_MEMORY;
2012 state = talloc(m, struct pdb_ads_state);
2013 if (state == NULL) {
2016 m->private_data = state;
2017 m->free_private_data = free_private_data;
2018 pdb_ads_init_methods(m);
2020 if (location == NULL) {
2021 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2025 if (location == NULL) {
2029 status = pdb_ads_connect(state, location);
2030 if (!NT_STATUS_IS_OK(status)) {
2031 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2036 return NT_STATUS_OK;
2038 status = NT_STATUS_NO_MEMORY;
2044 NTSTATUS pdb_ads_init(void);
2045 NTSTATUS pdb_ads_init(void)
2047 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",