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,
263 /* TODO: All fields :-) */
265 ret &= tldap_make_mod_fmt(
266 existing, mem_ctx, pnum_mods, pmods, "displayName",
267 "%s", pdb_get_fullname(sam));
269 blob = data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN);
270 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
271 "unicodePwd", 1, &blob);
273 blob = data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN);
274 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
275 "dBCSPwd", 1, &blob);
277 ret &= tldap_make_mod_fmt(
278 existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
279 "%d", ads_acb2uf(pdb_get_acct_ctrl(sam)));
281 ret &= tldap_make_mod_fmt(
282 existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
283 "%s", pdb_get_homedir(sam));
285 ret &= tldap_make_mod_fmt(
286 existing, mem_ctx, pnum_mods, pmods, "homeDrive",
287 "%s", pdb_get_dir_drive(sam));
289 ret &= tldap_make_mod_fmt(
290 existing, mem_ctx, pnum_mods, pmods, "scriptPath",
291 "%s", pdb_get_logon_script(sam));
293 ret &= tldap_make_mod_fmt(
294 existing, mem_ctx, pnum_mods, pmods, "profilePath",
295 "%s", pdb_get_profile_path(sam));
300 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
301 struct pdb_ads_state *state,
302 struct samu *sam_acct,
305 const char * attrs[] = {
306 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
307 "sAMAccountName", "displayName", "homeDirectory",
308 "homeDrive", "scriptPath", "profilePath", "description",
309 "userWorkstations", "comment", "userParameters", "objectSid",
310 "primaryGroupID", "userAccountControl", "logonHours",
311 "badPwdCount", "logonCount", "countryCode", "codePage",
312 "unicodePwd", "dBCSPwd" };
313 struct tldap_message **users;
316 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
317 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
318 &users, "%s", filter);
319 if (rc != TLDAP_SUCCESS) {
320 DEBUG(10, ("ldap_search failed %s\n",
321 tldap_errstr(debug_ctx(), state->ld, rc)));
322 return NT_STATUS_LDAP(rc);
325 count = talloc_array_length(users);
327 DEBUG(10, ("Expected 1 user, got %d\n", count));
328 return NT_STATUS_INTERNAL_DB_CORRUPTION;
331 return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]);
334 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
335 struct samu *sam_acct,
336 const char *username)
338 struct pdb_ads_state *state = talloc_get_type_abort(
339 m->private_data, struct pdb_ads_state);
342 filter = talloc_asprintf(
343 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
345 NT_STATUS_HAVE_NO_MEMORY(filter);
347 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
350 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
351 struct samu *sam_acct,
354 struct pdb_ads_state *state = talloc_get_type_abort(
355 m->private_data, struct pdb_ads_state);
356 char *sidstr, *filter;
358 sidstr = sid_binstring(talloc_tos(), sid);
359 NT_STATUS_HAVE_NO_MEMORY(sidstr);
361 filter = talloc_asprintf(
362 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
364 NT_STATUS_HAVE_NO_MEMORY(filter);
366 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
369 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
371 const char *name, uint32 acct_flags,
374 struct pdb_ads_state *state = talloc_get_type_abort(
375 m->private_data, struct pdb_ads_state);
376 const char *attrs[1] = { "objectSid" };
377 struct tldap_mod *mods = NULL;
379 struct tldap_message **user;
385 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
388 return NT_STATUS_NO_MEMORY;
391 /* TODO: Create machines etc */
394 ok &= tldap_make_mod_fmt(
395 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
396 ok &= tldap_make_mod_fmt(
397 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
400 return NT_STATUS_NO_MEMORY;
403 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, 0, NULL, 0);
404 if (rc != TLDAP_SUCCESS) {
405 DEBUG(10, ("ldap_add failed %s\n",
406 tldap_errstr(debug_ctx(), state->ld, rc)));
408 return NT_STATUS_LDAP(rc);
411 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
412 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &user,
413 "(&(objectclass=user)(samaccountname=%s))",
415 if (rc != TLDAP_SUCCESS) {
416 DEBUG(10, ("Could not find just created user %s: %s\n",
417 name, tldap_errstr(debug_ctx(), state->ld, rc)));
419 return NT_STATUS_LDAP(rc);
422 if (talloc_array_length(user) != 1) {
423 DEBUG(10, ("Got %d users, expected one\n",
424 (int)talloc_array_length(user)));
426 return NT_STATUS_LDAP(rc);
429 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
430 DEBUG(10, ("Could not fetch objectSid from user %s\n",
433 return NT_STATUS_INTERNAL_DB_CORRUPTION;
436 sid_peek_rid(&sid, rid);
441 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
445 struct pdb_ads_state *state = talloc_get_type_abort(
446 m->private_data, struct pdb_ads_state);
451 status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
453 if (!NT_STATUS_IS_OK(status)) {
457 rc = tldap_delete(state->ld, dn, NULL, 0, NULL, 0);
459 if (rc != TLDAP_SUCCESS) {
460 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
461 tldap_errstr(debug_ctx(), state->ld, rc)));
462 return NT_STATUS_LDAP(rc);
467 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
468 struct samu *sampass)
470 return NT_STATUS_NOT_IMPLEMENTED;
473 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
476 struct pdb_ads_state *state = talloc_get_type_abort(
477 m->private_data, struct pdb_ads_state);
478 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
479 struct tldap_mod *mods = NULL;
480 int rc, num_mods = 0;
482 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
483 &num_mods, &mods, sam)) {
484 return NT_STATUS_NO_MEMORY;
488 /* Nothing to do, just return success */
492 rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, 0,
494 if (rc != TLDAP_SUCCESS) {
495 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
496 tldap_errstr(debug_ctx(), state->ld, rc)));
497 return NT_STATUS_LDAP(rc);
505 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
506 struct samu *username)
508 return NT_STATUS_NOT_IMPLEMENTED;
511 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
512 struct samu *oldname,
515 return NT_STATUS_NOT_IMPLEMENTED;
518 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
519 struct samu *sam_acct,
522 return NT_STATUS_NOT_IMPLEMENTED;
525 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
528 struct pdb_ads_state *state = talloc_get_type_abort(
529 m->private_data, struct pdb_ads_state);
530 const char *attrs[4] = { "objectSid", "description", "samAccountName",
533 struct tldap_message **group;
537 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
538 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
539 &group, "%s", filter);
540 if (rc != TLDAP_SUCCESS) {
541 DEBUG(10, ("ldap_search failed %s\n",
542 tldap_errstr(debug_ctx(), state->ld, rc)));
543 return NT_STATUS_LDAP(rc);
545 if (talloc_array_length(group) != 1) {
546 DEBUG(10, ("Expected 1 user, got %d\n",
547 (int)talloc_array_length(group)));
548 return NT_STATUS_INTERNAL_DB_CORRUPTION;
551 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
552 return NT_STATUS_INTERNAL_DB_CORRUPTION;
554 map->gid = pdb_ads_sid2gid(&map->sid);
556 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
557 return NT_STATUS_INTERNAL_DB_CORRUPTION;
560 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
561 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
562 map->sid_name_use = SID_NAME_ALIAS;
564 case GTYPE_SECURITY_GLOBAL_GROUP:
565 map->sid_name_use = SID_NAME_DOM_GRP;
568 return NT_STATUS_INTERNAL_DB_CORRUPTION;
571 str = tldap_talloc_single_attribute(group[0], "samAccountName",
574 return NT_STATUS_INTERNAL_DB_CORRUPTION;
576 fstrcpy(map->nt_name, str);
579 str = tldap_talloc_single_attribute(group[0], "description",
582 fstrcpy(map->comment, str);
585 map->comment[0] = '\0';
592 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
598 filter = talloc_asprintf(talloc_tos(),
599 "(&(objectsid=%s)(objectclass=group))",
600 sid_string_talloc(talloc_tos(), &sid));
601 if (filter == NULL) {
602 return NT_STATUS_NO_MEMORY;
605 status = pdb_ads_getgrfilter(m, map, filter);
610 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
614 pdb_ads_gid_to_sid(m, gid, &sid);
615 return pdb_ads_getgrsid(m, map, sid);
618 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
624 filter = talloc_asprintf(talloc_tos(),
625 "(&(samaccountname=%s)(objectclass=group))",
627 if (filter == NULL) {
628 return NT_STATUS_NO_MEMORY;
631 status = pdb_ads_getgrfilter(m, map, filter);
636 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
637 TALLOC_CTX *mem_ctx, const char *name,
640 TALLOC_CTX *frame = talloc_stackframe();
641 struct pdb_ads_state *state = talloc_get_type_abort(
642 m->private_data, struct pdb_ads_state);
643 const char *attrs[1] = { "objectSid" };
645 struct tldap_mod *mods = NULL;
646 struct tldap_message **alias;
652 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
656 return NT_STATUS_NO_MEMORY;
659 ok &= tldap_make_mod_fmt(
660 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
662 ok &= tldap_make_mod_fmt(
663 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
664 ok &= tldap_make_mod_fmt(
665 NULL, talloc_tos(), &num_mods, &mods, "groupType",
666 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
670 return NT_STATUS_NO_MEMORY;
673 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, 0, NULL, 0);
674 if (rc != TLDAP_SUCCESS) {
675 DEBUG(10, ("ldap_add failed %s\n",
676 tldap_errstr(debug_ctx(), state->ld, rc)));
678 return NT_STATUS_LDAP(rc);
681 rc = tldap_search_fmt(
682 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
683 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
684 "(&(objectclass=group)(samaccountname=%s))", name);
685 if (rc != TLDAP_SUCCESS) {
686 DEBUG(10, ("Could not find just created alias %s: %s\n",
687 name, tldap_errstr(debug_ctx(), state->ld, rc)));
689 return NT_STATUS_LDAP(rc);
692 if (talloc_array_length(alias) != 1) {
693 DEBUG(10, ("Got %d alias, expected one\n",
694 (int)talloc_array_length(alias)));
696 return NT_STATUS_LDAP(rc);
699 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
700 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
703 return NT_STATUS_INTERNAL_DB_CORRUPTION;
706 sid_peek_rid(&sid, rid);
711 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
712 TALLOC_CTX *mem_ctx, uint32 rid)
714 struct pdb_ads_state *state = talloc_get_type_abort(
715 m->private_data, struct pdb_ads_state);
718 struct tldap_message **msg;
722 sid_compose(&sid, &state->domainsid, rid);
724 sidstr = sid_binstring(talloc_tos(), &sid);
725 NT_STATUS_HAVE_NO_MEMORY(sidstr);
727 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
728 NULL, 0, 0, talloc_tos(), &msg,
729 ("(&(objectSid=%s)(objectClass=group))"),
732 if (rc != TLDAP_SUCCESS) {
733 DEBUG(10, ("ldap_search failed %s\n",
734 tldap_errstr(debug_ctx(), state->ld, rc)));
735 return NT_STATUS_LDAP(rc);
738 switch talloc_array_length(msg) {
740 return NT_STATUS_NO_SUCH_GROUP;
744 return NT_STATUS_INTERNAL_DB_CORRUPTION;
747 if (!tldap_entry_dn(msg[0], &dn)) {
748 return NT_STATUS_INTERNAL_DB_CORRUPTION;
751 rc = tldap_delete(state->ld, dn, NULL, 0, NULL, 0);
752 if (rc != TLDAP_SUCCESS) {
753 DEBUG(10, ("ldap_delete failed: %s\n",
754 tldap_errstr(debug_ctx(), state->ld, rc)));
756 return NT_STATUS_LDAP(rc);
763 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
766 return NT_STATUS_NOT_IMPLEMENTED;
769 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
772 return NT_STATUS_NOT_IMPLEMENTED;
775 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
778 return NT_STATUS_NOT_IMPLEMENTED;
781 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
783 enum lsa_SidType sid_name_use,
785 size_t *p_num_entries,
788 return NT_STATUS_NOT_IMPLEMENTED;
791 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
793 const DOM_SID *group,
795 size_t *pnum_members)
797 struct pdb_ads_state *state = talloc_get_type_abort(
798 m->private_data, struct pdb_ads_state);
799 const char *attrs[1] = { "member" };
801 struct tldap_message **msg;
802 int i, rc, num_members;
806 sidstr = sid_binstring(talloc_tos(), group);
807 NT_STATUS_HAVE_NO_MEMORY(sidstr);
809 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
810 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
811 "(objectsid=%s)", sidstr);
813 if (rc != TLDAP_SUCCESS) {
814 DEBUG(10, ("ldap_search failed %s\n",
815 tldap_errstr(debug_ctx(), state->ld, rc)));
816 return NT_STATUS_LDAP(rc);
818 switch talloc_array_length(msg) {
820 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
825 return NT_STATUS_INTERNAL_DB_CORRUPTION;
829 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
830 return NT_STATUS_INTERNAL_DB_CORRUPTION;
833 members = talloc_array(mem_ctx, uint32_t, num_members);
834 if (members == NULL) {
835 return NT_STATUS_NO_MEMORY;
838 for (i=0; i<num_members; i++) {
840 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &sid)
841 || !sid_peek_rid(&sid, &members[i])) {
842 TALLOC_FREE(members);
843 return NT_STATUS_INTERNAL_DB_CORRUPTION;
848 *pnum_members = num_members;
852 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
857 size_t *p_num_groups)
859 struct pdb_ads_state *state = talloc_get_type_abort(
860 m->private_data, struct pdb_ads_state);
861 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
863 const char *attrs[1] = { "objectSid" };
864 struct tldap_message **groups;
867 struct dom_sid *group_sids;
870 rc = tldap_search_fmt(
871 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
872 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
873 "(&(member=%s)(grouptype=%d)(objectclass=group))",
874 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
875 if (rc != TLDAP_SUCCESS) {
876 DEBUG(10, ("ldap_search failed %s\n",
877 tldap_errstr(debug_ctx(), state->ld, rc)));
878 return NT_STATUS_LDAP(rc);
881 count = talloc_array_length(groups);
883 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
884 if (group_sids == NULL) {
885 return NT_STATUS_NO_MEMORY;
887 gids = talloc_array(mem_ctx, gid_t, count);
889 TALLOC_FREE(group_sids);
890 return NT_STATUS_NO_MEMORY;
894 for (i=0; i<count; i++) {
895 if (!tldap_pull_binsid(groups[i], "objectSid",
896 &group_sids[num_groups])) {
899 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
902 if (num_groups == count) {
907 *pp_sids = group_sids;
909 *p_num_groups = num_groups;
913 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
917 return NT_STATUS_NOT_IMPLEMENTED;
920 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
922 uint32 grouprid, uint32 memberrid,
925 struct pdb_ads_state *state = talloc_get_type_abort(
926 m->private_data, struct pdb_ads_state);
927 TALLOC_CTX *frame = talloc_stackframe();
928 struct dom_sid groupsid, membersid;
929 char *groupdn, *memberdn;
930 struct tldap_mod *mods;
934 sid_compose(&groupsid, &state->domainsid, grouprid);
935 sid_compose(&membersid, &state->domainsid, memberrid);
937 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
938 if (!NT_STATUS_IS_OK(status)) {
940 return NT_STATUS_NO_SUCH_GROUP;
942 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
943 if (!NT_STATUS_IS_OK(status)) {
945 return NT_STATUS_NO_SUCH_USER;
950 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
951 "member", memberdn)) {
953 return NT_STATUS_NO_MEMORY;
956 rc = tldap_modify(state->ld, groupdn, 1, mods, NULL, 0, NULL, 0);
958 if (rc != TLDAP_SUCCESS) {
959 DEBUG(10, ("ldap_modify failed: %s\n",
960 tldap_errstr(debug_ctx(), state->ld, rc)));
961 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
962 return NT_STATUS_MEMBER_IN_GROUP;
964 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
965 return NT_STATUS_MEMBER_NOT_IN_GROUP;
967 return NT_STATUS_LDAP(rc);
973 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
975 uint32 group_rid, uint32 member_rid)
977 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
981 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
983 uint32 group_rid, uint32 member_rid)
985 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
989 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
990 const char *name, uint32 *rid)
992 TALLOC_CTX *frame = talloc_stackframe();
993 struct pdb_ads_state *state = talloc_get_type_abort(
994 m->private_data, struct pdb_ads_state);
995 const char *attrs[1] = { "objectSid" };
997 struct tldap_mod *mods = NULL;
998 struct tldap_message **alias;
1004 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1008 return NT_STATUS_NO_MEMORY;
1011 ok &= tldap_make_mod_fmt(
1012 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
1014 ok &= tldap_make_mod_fmt(
1015 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
1016 ok &= tldap_make_mod_fmt(
1017 NULL, talloc_tos(), &num_mods, &mods, "groupType",
1018 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1022 return NT_STATUS_NO_MEMORY;
1025 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1026 if (rc != TLDAP_SUCCESS) {
1027 DEBUG(10, ("ldap_add failed %s\n",
1028 tldap_errstr(debug_ctx(), state->ld, rc)));
1030 return NT_STATUS_LDAP(rc);
1033 rc = tldap_search_fmt(
1034 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1035 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1036 "(&(objectclass=group)(samaccountname=%s))", name);
1037 if (rc != TLDAP_SUCCESS) {
1038 DEBUG(10, ("Could not find just created alias %s: %s\n",
1039 name, tldap_errstr(debug_ctx(), state->ld, rc)));
1041 return NT_STATUS_LDAP(rc);
1044 if (talloc_array_length(alias) != 1) {
1045 DEBUG(10, ("Got %d alias, expected one\n",
1046 (int)talloc_array_length(alias)));
1048 return NT_STATUS_LDAP(rc);
1051 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1052 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1055 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1058 sid_peek_rid(&sid, rid);
1060 return NT_STATUS_OK;
1063 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1066 struct pdb_ads_state *state = talloc_get_type_abort(
1067 m->private_data, struct pdb_ads_state);
1068 struct tldap_message **alias;
1072 sidstr = sid_binstring(talloc_tos(), sid);
1073 if (sidstr == NULL) {
1074 return NT_STATUS_NO_MEMORY;
1077 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1078 NULL, 0, 0, talloc_tos(), &alias,
1079 "(&(objectSid=%s)(objectclass=group)"
1080 "(|(grouptype=%d)(grouptype=%d)))",
1081 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1082 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1083 TALLOC_FREE(sidstr);
1084 if (rc != TLDAP_SUCCESS) {
1085 DEBUG(10, ("ldap_search failed: %s\n",
1086 tldap_errstr(debug_ctx(), state->ld, rc)));
1088 return NT_STATUS_LDAP(rc);
1090 if (talloc_array_length(alias) != 1) {
1091 DEBUG(10, ("Expected 1 alias, got %d\n",
1092 (int)talloc_array_length(alias)));
1093 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1095 if (!tldap_entry_dn(alias[0], &dn)) {
1096 DEBUG(10, ("Could not get DN for alias %s\n",
1097 sid_string_dbg(sid)));
1098 return NT_STATUS_INTERNAL_ERROR;
1101 rc = tldap_delete(state->ld, dn, NULL, 0, NULL, 0);
1102 if (rc != TLDAP_SUCCESS) {
1103 DEBUG(10, ("ldap_delete failed: %s\n",
1104 tldap_errstr(debug_ctx(), state->ld, rc)));
1106 return NT_STATUS_LDAP(rc);
1109 return NT_STATUS_OK;
1112 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1114 struct acct_info *info)
1116 struct pdb_ads_state *state = talloc_get_type_abort(
1117 m->private_data, struct pdb_ads_state);
1118 const char *attrs[3] = { "objectSid", "description",
1120 struct tldap_message **msg;
1123 struct tldap_mod *mods;
1127 sidstr = sid_binstring(talloc_tos(), sid);
1128 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1130 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1131 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1132 &msg, "(&(objectSid=%s)(objectclass=group)"
1133 "(|(grouptype=%d)(grouptype=%d)))",
1134 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1135 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1136 TALLOC_FREE(sidstr);
1137 if (rc != TLDAP_SUCCESS) {
1138 DEBUG(10, ("ldap_search failed %s\n",
1139 tldap_errstr(debug_ctx(), state->ld, rc)));
1140 return NT_STATUS_LDAP(rc);
1142 switch talloc_array_length(msg) {
1144 return NT_STATUS_NO_SUCH_ALIAS;
1148 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1151 if (!tldap_entry_dn(msg[0], &dn)) {
1153 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1160 ok &= tldap_make_mod_fmt(
1161 msg[0], msg, &num_mods, &mods, "description",
1162 "%s", info->acct_desc);
1163 ok &= tldap_make_mod_fmt(
1164 msg[0], msg, &num_mods, &mods, "samAccountName",
1165 "%s", info->acct_name);
1168 return NT_STATUS_NO_MEMORY;
1170 if (num_mods == 0) {
1173 return NT_STATUS_OK;
1176 rc = tldap_modify(state->ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1178 if (rc != TLDAP_SUCCESS) {
1179 DEBUG(10, ("ldap_modify failed: %s\n",
1180 tldap_errstr(debug_ctx(), state->ld, rc)));
1181 return NT_STATUS_LDAP(rc);
1183 return NT_STATUS_OK;
1186 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1187 const struct dom_sid *sid,
1188 TALLOC_CTX *mem_ctx, char **pdn)
1190 struct tldap_message **msg;
1194 sidstr = sid_binstring(talloc_tos(), sid);
1195 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1197 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1198 NULL, 0, 0, talloc_tos(), &msg,
1199 "(objectsid=%s)", sidstr);
1200 TALLOC_FREE(sidstr);
1201 if (rc != TLDAP_SUCCESS) {
1202 DEBUG(10, ("ldap_search failed %s\n",
1203 tldap_errstr(debug_ctx(), state->ld, rc)));
1204 return NT_STATUS_LDAP(rc);
1207 switch talloc_array_length(msg) {
1209 return NT_STATUS_NOT_FOUND;
1213 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1216 if (!tldap_entry_dn(msg[0], &dn)) {
1217 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1220 dn = talloc_strdup(mem_ctx, dn);
1222 return NT_STATUS_NO_MEMORY;
1227 return NT_STATUS_OK;
1230 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1231 const DOM_SID *alias,
1232 const DOM_SID *member,
1235 struct pdb_ads_state *state = talloc_get_type_abort(
1236 m->private_data, struct pdb_ads_state);
1237 TALLOC_CTX *frame = talloc_stackframe();
1238 struct tldap_mod *mods;
1240 char *aliasdn, *memberdn;
1243 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1244 if (!NT_STATUS_IS_OK(status)) {
1245 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1246 sid_string_dbg(alias), nt_errstr(status)));
1248 return NT_STATUS_NO_SUCH_ALIAS;
1250 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1251 if (!NT_STATUS_IS_OK(status)) {
1252 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1253 sid_string_dbg(member), nt_errstr(status)));
1260 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1261 "member", memberdn)) {
1263 return NT_STATUS_NO_MEMORY;
1266 rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, 0, NULL, 0);
1268 if (rc != TLDAP_SUCCESS) {
1269 DEBUG(10, ("ldap_modify failed: %s\n",
1270 tldap_errstr(debug_ctx(), state->ld, rc)));
1271 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1272 return NT_STATUS_MEMBER_IN_ALIAS;
1274 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1275 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1277 return NT_STATUS_LDAP(rc);
1280 return NT_STATUS_OK;
1283 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1284 const DOM_SID *alias,
1285 const DOM_SID *member)
1287 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1290 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1291 const DOM_SID *alias,
1292 const DOM_SID *member)
1294 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1297 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1298 struct dom_sid *psid)
1300 const char *attrs[1] = { "objectSid" };
1301 struct tldap_message **msg;
1307 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1308 dnblob->data, dnblob->length, &dn, &len,
1312 rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1313 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1314 &msg, "(objectclass=*)");
1316 if (talloc_array_length(msg) != 1) {
1317 DEBUG(10, ("Got %d objects, expected one\n",
1318 (int)talloc_array_length(msg)));
1323 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1328 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1329 const DOM_SID *alias,
1330 TALLOC_CTX *mem_ctx,
1332 size_t *pnum_members)
1334 struct pdb_ads_state *state = talloc_get_type_abort(
1335 m->private_data, struct pdb_ads_state);
1336 const char *attrs[1] = { "member" };
1338 struct tldap_message **msg;
1339 int i, rc, num_members;
1341 struct dom_sid *members;
1343 sidstr = sid_binstring(talloc_tos(), alias);
1344 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1346 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1347 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1348 "(objectsid=%s)", sidstr);
1349 TALLOC_FREE(sidstr);
1350 if (rc != TLDAP_SUCCESS) {
1351 DEBUG(10, ("ldap_search failed %s\n",
1352 tldap_errstr(debug_ctx(), state->ld, rc)));
1353 return NT_STATUS_LDAP(rc);
1355 switch talloc_array_length(msg) {
1357 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1362 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1366 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1367 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1370 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1371 if (members == NULL) {
1372 return NT_STATUS_NO_MEMORY;
1375 for (i=0; i<num_members; i++) {
1376 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1377 TALLOC_FREE(members);
1378 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1382 *pmembers = members;
1383 *pnum_members = num_members;
1384 return NT_STATUS_OK;
1387 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1388 TALLOC_CTX *mem_ctx,
1389 const DOM_SID *domain_sid,
1390 const DOM_SID *members,
1392 uint32_t **palias_rids,
1393 size_t *pnum_alias_rids)
1395 struct pdb_ads_state *state = talloc_get_type_abort(
1396 m->private_data, struct pdb_ads_state);
1397 const char *attrs[1] = { "objectSid" };
1398 struct tldap_message **msg;
1399 uint32_t *alias_rids = NULL;
1400 size_t num_alias_rids = 0;
1402 bool got_members = false;
1407 * TODO: Get the filter right so that we only get the aliases from
1408 * either the SAM or BUILTIN
1411 filter = talloc_asprintf(talloc_tos(),
1412 "(&(|(grouptype=%d)(grouptype=%d))"
1413 "(objectclass=group)(|",
1414 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1415 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1416 if (filter == NULL) {
1417 return NT_STATUS_NO_MEMORY;
1420 for (i=0; i<num_members; i++) {
1423 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1424 if (!NT_STATUS_IS_OK(status)) {
1425 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1426 sid_string_dbg(&members[i]),
1427 nt_errstr(status)));
1430 filter = talloc_asprintf_append_buffer(
1431 filter, "(member=%s)", dn);
1433 if (filter == NULL) {
1434 return NT_STATUS_NO_MEMORY;
1443 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1444 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1445 &msg, "%s))", filter);
1446 TALLOC_FREE(filter);
1447 if (rc != TLDAP_SUCCESS) {
1448 DEBUG(10, ("tldap_search failed %s\n",
1449 tldap_errstr(debug_ctx(), state->ld, rc)));
1450 return NT_STATUS_LDAP(rc);
1453 count = talloc_array_length(msg);
1458 alias_rids = talloc_array(mem_ctx, uint32_t, count);
1459 if (alias_rids == NULL) {
1461 return NT_STATUS_NO_MEMORY;
1464 for (i=0; i<count; i++) {
1467 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1468 DEBUG(10, ("Could not pull SID for member %d\n", i));
1471 if (sid_peek_check_rid(domain_sid, &sid,
1472 &alias_rids[num_alias_rids])) {
1473 num_alias_rids += 1;
1478 *palias_rids = alias_rids;
1479 *pnum_alias_rids = 0;
1480 return NT_STATUS_OK;
1483 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1484 const DOM_SID *domain_sid,
1488 enum lsa_SidType *lsa_attrs)
1490 struct pdb_ads_state *state = talloc_get_type_abort(
1491 m->private_data, struct pdb_ads_state);
1492 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1495 if (num_rids == 0) {
1496 return NT_STATUS_NONE_MAPPED;
1501 for (i=0; i<num_rids; i++) {
1503 struct tldap_message **msg;
1508 lsa_attrs[i] = SID_NAME_UNKNOWN;
1510 sid_compose(&sid, domain_sid, rids[i]);
1512 sidstr = sid_binstring(talloc_tos(), &sid);
1513 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1515 rc = tldap_search_fmt(state->ld, state->domaindn,
1516 TLDAP_SCOPE_SUB, attrs,
1517 ARRAY_SIZE(attrs), 0, talloc_tos(),
1518 &msg, "(objectsid=%s)", sidstr);
1519 TALLOC_FREE(sidstr);
1520 if (rc != TLDAP_SUCCESS) {
1521 DEBUG(10, ("ldap_search failed %s\n",
1522 tldap_errstr(debug_ctx(), state->ld, rc)));
1526 switch talloc_array_length(msg) {
1528 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1533 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1536 names[i] = tldap_talloc_single_attribute(
1537 msg[0], "samAccountName", talloc_tos());
1538 if (names[i] == NULL) {
1539 DEBUG(10, ("no samAccountName\n"));
1542 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1543 DEBUG(10, ("no samAccountType"));
1546 lsa_attrs[i] = ads_atype_map(attr);
1550 if (num_mapped == 0) {
1551 return NT_STATUS_NONE_MAPPED;
1553 if (num_mapped < num_rids) {
1554 return STATUS_SOME_UNMAPPED;
1556 return NT_STATUS_OK;
1559 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1560 const DOM_SID *domain_sid,
1562 const char **pp_names,
1564 enum lsa_SidType *attrs)
1566 return NT_STATUS_NOT_IMPLEMENTED;
1569 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1570 int policy_index, uint32 *value)
1572 return account_policy_get(policy_index, value)
1573 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1576 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1577 int policy_index, uint32 value)
1579 return account_policy_set(policy_index, value)
1580 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1583 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1586 return NT_STATUS_NOT_IMPLEMENTED;
1589 struct pdb_ads_search_state {
1590 uint32_t acct_flags;
1591 struct samr_displayentry *entries;
1592 uint32_t num_entries;
1597 static bool pdb_ads_next_entry(struct pdb_search *search,
1598 struct samr_displayentry *entry)
1600 struct pdb_ads_search_state *state = talloc_get_type_abort(
1601 search->private_data, struct pdb_ads_search_state);
1603 if (state->current == state->num_entries) {
1607 entry->idx = state->entries[state->current].idx;
1608 entry->rid = state->entries[state->current].rid;
1609 entry->acct_flags = state->entries[state->current].acct_flags;
1611 entry->account_name = talloc_strdup(
1612 search, state->entries[state->current].account_name);
1613 entry->fullname = talloc_strdup(
1614 search, state->entries[state->current].fullname);
1615 entry->description = talloc_strdup(
1616 search, state->entries[state->current].description);
1618 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1619 || (entry->description == NULL)) {
1620 DEBUG(0, ("talloc_strdup failed\n"));
1624 state->current += 1;
1628 static void pdb_ads_search_end(struct pdb_search *search)
1630 struct pdb_ads_search_state *state = talloc_get_type_abort(
1631 search->private_data, struct pdb_ads_search_state);
1635 static bool pdb_ads_search_filter(struct pdb_methods *m,
1636 struct pdb_search *search,
1638 struct pdb_ads_search_state **pstate)
1640 struct pdb_ads_state *state = talloc_get_type_abort(
1641 m->private_data, struct pdb_ads_state);
1642 struct pdb_ads_search_state *sstate;
1643 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1644 "userAccountControl", "description" };
1645 struct tldap_message **users;
1646 int i, rc, num_users;
1648 sstate = talloc_zero(search, struct pdb_ads_search_state);
1649 if (sstate == NULL) {
1653 rc = tldap_search_fmt(
1654 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1655 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1657 if (rc != TLDAP_SUCCESS) {
1658 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1659 tldap_errstr(debug_ctx(), state->ld, rc)));
1663 num_users = talloc_array_length(users);
1665 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1667 if (sstate->entries == NULL) {
1668 DEBUG(10, ("talloc failed\n"));
1672 sstate->num_entries = 0;
1674 for (i=0; i<num_users; i++) {
1675 struct samr_displayentry *e;
1678 e = &sstate->entries[sstate->num_entries];
1680 e->idx = sstate->num_entries;
1681 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1682 DEBUG(10, ("Could not pull sid\n"));
1685 sid_peek_rid(&sid, &e->rid);
1686 e->acct_flags = ACB_NORMAL;
1687 e->account_name = tldap_talloc_single_attribute(
1688 users[i], "samAccountName", sstate->entries);
1689 if (e->account_name == NULL) {
1692 e->fullname = tldap_talloc_single_attribute(
1693 users[i], "displayName", sstate->entries);
1694 if (e->fullname == NULL) {
1697 e->description = tldap_talloc_single_attribute(
1698 users[i], "description", sstate->entries);
1699 if (e->description == NULL) {
1700 e->description = "";
1703 sstate->num_entries += 1;
1704 if (sstate->num_entries >= num_users) {
1709 search->private_data = sstate;
1710 search->next_entry = pdb_ads_next_entry;
1711 search->search_end = pdb_ads_search_end;
1716 static bool pdb_ads_search_users(struct pdb_methods *m,
1717 struct pdb_search *search,
1720 struct pdb_ads_search_state *sstate;
1723 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1727 sstate->acct_flags = acct_flags;
1731 static bool pdb_ads_search_groups(struct pdb_methods *m,
1732 struct pdb_search *search)
1734 struct pdb_ads_search_state *sstate;
1738 filter = talloc_asprintf(talloc_tos(),
1739 "(&(grouptype=%d)(objectclass=group))",
1740 GTYPE_SECURITY_GLOBAL_GROUP);
1741 if (filter == NULL) {
1744 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1745 TALLOC_FREE(filter);
1749 sstate->acct_flags = 0;
1753 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1754 struct pdb_search *search,
1757 struct pdb_ads_search_state *sstate;
1761 filter = talloc_asprintf(
1762 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1763 sid_check_is_builtin(sid)
1764 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1765 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1767 if (filter == NULL) {
1770 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1771 TALLOC_FREE(filter);
1775 sstate->acct_flags = 0;
1779 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1785 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1788 struct pdb_ads_state *state = talloc_get_type_abort(
1789 m->private_data, struct pdb_ads_state);
1790 sid_compose(sid, &state->domainsid, uid);
1794 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1797 struct pdb_ads_state *state = talloc_get_type_abort(
1798 m->private_data, struct pdb_ads_state);
1799 sid_compose(sid, &state->domainsid, gid);
1803 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1804 union unid_t *id, enum lsa_SidType *type)
1806 struct pdb_ads_state *state = talloc_get_type_abort(
1807 m->private_data, struct pdb_ads_state);
1808 struct tldap_message **msg;
1814 * This is a big, big hack: Just hard-code the rid as uid/gid.
1817 sid_peek_rid(sid, &rid);
1819 sidstr = sid_binstring(talloc_tos(), sid);
1820 if (sidstr == NULL) {
1824 rc = tldap_search_fmt(
1825 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1826 NULL, 0, 0, talloc_tos(), &msg,
1827 "(&(objectsid=%s)(objectclass=user))", sidstr);
1828 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1830 *type = SID_NAME_USER;
1831 TALLOC_FREE(sidstr);
1835 rc = tldap_search_fmt(
1836 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1837 NULL, 0, 0, talloc_tos(), &msg,
1838 "(&(objectsid=%s)(objectclass=group))", sidstr);
1839 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1841 *type = SID_NAME_DOM_GRP;
1842 TALLOC_FREE(sidstr);
1846 TALLOC_FREE(sidstr);
1850 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1855 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1860 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1861 const char *domain, char** pwd,
1863 time_t *pass_last_set_time)
1868 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1869 const char* domain, const char* pwd,
1875 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1881 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1882 TALLOC_CTX *mem_ctx,
1883 uint32 *num_domains,
1884 struct trustdom_info ***domains)
1886 return NT_STATUS_NOT_IMPLEMENTED;
1889 static void pdb_ads_init_methods(struct pdb_methods *m)
1892 m->getsampwnam = pdb_ads_getsampwnam;
1893 m->getsampwsid = pdb_ads_getsampwsid;
1894 m->create_user = pdb_ads_create_user;
1895 m->delete_user = pdb_ads_delete_user;
1896 m->add_sam_account = pdb_ads_add_sam_account;
1897 m->update_sam_account = pdb_ads_update_sam_account;
1898 m->delete_sam_account = pdb_ads_delete_sam_account;
1899 m->rename_sam_account = pdb_ads_rename_sam_account;
1900 m->update_login_attempts = pdb_ads_update_login_attempts;
1901 m->getgrsid = pdb_ads_getgrsid;
1902 m->getgrgid = pdb_ads_getgrgid;
1903 m->getgrnam = pdb_ads_getgrnam;
1904 m->create_dom_group = pdb_ads_create_dom_group;
1905 m->delete_dom_group = pdb_ads_delete_dom_group;
1906 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1907 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1908 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1909 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1910 m->enum_group_members = pdb_ads_enum_group_members;
1911 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1912 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1913 m->add_groupmem = pdb_ads_add_groupmem;
1914 m->del_groupmem = pdb_ads_del_groupmem;
1915 m->create_alias = pdb_ads_create_alias;
1916 m->delete_alias = pdb_ads_delete_alias;
1917 m->get_aliasinfo = pdb_default_get_aliasinfo;
1918 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1919 m->add_aliasmem = pdb_ads_add_aliasmem;
1920 m->del_aliasmem = pdb_ads_del_aliasmem;
1921 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1922 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1923 m->lookup_rids = pdb_ads_lookup_rids;
1924 m->lookup_names = pdb_ads_lookup_names;
1925 m->get_account_policy = pdb_ads_get_account_policy;
1926 m->set_account_policy = pdb_ads_set_account_policy;
1927 m->get_seq_num = pdb_ads_get_seq_num;
1928 m->search_users = pdb_ads_search_users;
1929 m->search_groups = pdb_ads_search_groups;
1930 m->search_aliases = pdb_ads_search_aliases;
1931 m->uid_to_rid = pdb_ads_uid_to_rid;
1932 m->uid_to_sid = pdb_ads_uid_to_sid;
1933 m->gid_to_sid = pdb_ads_gid_to_sid;
1934 m->sid_to_id = pdb_ads_sid_to_id;
1935 m->rid_algorithm = pdb_ads_rid_algorithm;
1936 m->new_rid = pdb_ads_new_rid;
1937 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1938 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1939 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1940 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1943 static void free_private_data(void **vp)
1945 struct pdb_ads_state *state = talloc_get_type_abort(
1946 *vp, struct pdb_ads_state);
1948 TALLOC_FREE(state->ld);
1953 this is used to catch debug messages from events
1955 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
1956 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
1958 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
1959 const char *fmt, va_list ap)
1961 int samba_level = -1;
1964 case TLDAP_DEBUG_FATAL:
1967 case TLDAP_DEBUG_ERROR:
1970 case TLDAP_DEBUG_WARNING:
1973 case TLDAP_DEBUG_TRACE:
1978 if (vasprintf(&s, fmt, ap) == -1) {
1981 DEBUG(samba_level, ("tldap: %s", s));
1985 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1986 const char *location)
1988 const char *rootdse_attrs[2] = {
1989 "defaultNamingContext", "configurationNamingContext" };
1990 const char *domain_attrs[1] = { "objectSid" };
1991 const char *ncname_attrs[1] = { "netbiosname" };
1992 struct tldap_message **rootdse, **domain, **ncname;
1993 TALLOC_CTX *frame = talloc_stackframe();
1994 struct sockaddr_un sunaddr;
1999 ZERO_STRUCT(sunaddr);
2000 sunaddr.sun_family = AF_UNIX;
2001 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
2003 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
2005 if (!NT_STATUS_IS_OK(status)) {
2006 DEBUG(10, ("Could not connect to %s: %s\n", location,
2007 nt_errstr(status)));
2011 state->ld = tldap_context_create(state, fd);
2012 if (state->ld == NULL) {
2014 status = NT_STATUS_NO_MEMORY;
2017 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2019 rc = tldap_search_fmt(
2020 state->ld, "", TLDAP_SCOPE_BASE,
2021 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
2022 talloc_tos(), &rootdse, "(objectclass=*)");
2023 if (rc != TLDAP_SUCCESS) {
2024 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2025 tldap_errstr(debug_ctx(), state->ld, rc)));
2026 status = NT_STATUS_LDAP(rc);
2029 if (talloc_array_length(rootdse) != 1) {
2030 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2034 state->domaindn = tldap_talloc_single_attribute(
2035 rootdse[0], "defaultNamingContext", state);
2036 if (state->domaindn == NULL) {
2037 DEBUG(10, ("Could not get defaultNamingContext\n"));
2038 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2041 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2043 state->configdn = tldap_talloc_single_attribute(
2044 rootdse[0], "configurationNamingContext", state);
2045 if (state->domaindn == NULL) {
2046 DEBUG(10, ("Could not get configurationNamingContext\n"));
2047 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2050 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2053 * Figure out our domain's SID
2055 rc = tldap_search_fmt(
2056 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
2057 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2058 talloc_tos(), &domain, "(objectclass=*)");
2059 if (rc != TLDAP_SUCCESS) {
2060 DEBUG(10, ("Could not retrieve domain: %s\n",
2061 tldap_errstr(debug_ctx(), state->ld, rc)));
2062 status = NT_STATUS_LDAP(rc);
2066 num_domains = talloc_array_length(domain);
2067 if (num_domains != 1) {
2068 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2069 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2072 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2073 DEBUG(10, ("Could not retrieve domain SID\n"));
2074 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2077 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2080 * Figure out our domain's short name
2082 rc = tldap_search_fmt(
2083 state->ld, state->configdn, TLDAP_SCOPE_SUB,
2084 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2085 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2086 if (rc != TLDAP_SUCCESS) {
2087 DEBUG(10, ("Could not retrieve ncname: %s\n",
2088 tldap_errstr(debug_ctx(), state->ld, rc)));
2089 status = NT_STATUS_LDAP(rc);
2092 if (talloc_array_length(ncname) != 1) {
2093 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2097 state->netbiosname = tldap_talloc_single_attribute(
2098 ncname[0], "netbiosname", state);
2099 if (state->netbiosname == NULL) {
2100 DEBUG(10, ("Could not get netbiosname\n"));
2101 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2104 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2106 if (!strequal(lp_workgroup(), state->netbiosname)) {
2107 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2108 state->netbiosname, lp_workgroup()));
2109 status = NT_STATUS_NO_SUCH_DOMAIN;
2113 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2115 status = NT_STATUS_OK;
2121 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2122 const char *location)
2124 struct pdb_methods *m;
2125 struct pdb_ads_state *state;
2129 m = talloc(talloc_autofree_context(), struct pdb_methods);
2131 return NT_STATUS_NO_MEMORY;
2133 state = talloc(m, struct pdb_ads_state);
2134 if (state == NULL) {
2137 m->private_data = state;
2138 m->free_private_data = free_private_data;
2139 pdb_ads_init_methods(m);
2141 if (location == NULL) {
2142 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2146 if (location == NULL) {
2150 status = pdb_ads_connect(state, location);
2151 if (!NT_STATUS_IS_OK(status)) {
2152 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2157 return NT_STATUS_OK;
2159 status = NT_STATUS_NO_MEMORY;
2165 NTSTATUS pdb_ads_init(void);
2166 NTSTATUS pdb_ads_init(void)
2168 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",