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_t **palias_rids,
1391 size_t *pnum_alias_rids)
1393 struct pdb_ads_state *state = talloc_get_type_abort(
1394 m->private_data, struct pdb_ads_state);
1395 const char *attrs[1] = { "objectSid" };
1396 struct tldap_message **msg;
1397 uint32_t *alias_rids = NULL;
1398 size_t num_alias_rids = 0;
1400 bool got_members = false;
1405 * TODO: Get the filter right so that we only get the aliases from
1406 * either the SAM or BUILTIN
1409 filter = talloc_asprintf(talloc_tos(),
1410 "(&(|(grouptype=%d)(grouptype=%d))"
1411 "(objectclass=group)(|",
1412 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1413 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1414 if (filter == NULL) {
1415 return NT_STATUS_NO_MEMORY;
1418 for (i=0; i<num_members; i++) {
1421 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1422 if (!NT_STATUS_IS_OK(status)) {
1423 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1424 sid_string_dbg(&members[i]),
1425 nt_errstr(status)));
1428 filter = talloc_asprintf_append_buffer(
1429 filter, "(member=%s)", dn);
1431 if (filter == NULL) {
1432 return NT_STATUS_NO_MEMORY;
1441 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1442 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1443 &msg, "%s))", filter);
1444 TALLOC_FREE(filter);
1445 if (rc != TLDAP_SUCCESS) {
1446 DEBUG(10, ("tldap_search failed %s\n",
1447 tldap_errstr(debug_ctx(), state->ld, rc)));
1448 return NT_STATUS_LDAP(rc);
1451 count = talloc_array_length(msg);
1456 alias_rids = talloc_array(mem_ctx, uint32_t, count);
1457 if (alias_rids == NULL) {
1459 return NT_STATUS_NO_MEMORY;
1462 for (i=0; i<count; i++) {
1465 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1466 DEBUG(10, ("Could not pull SID for member %d\n", i));
1469 if (sid_peek_check_rid(domain_sid, &sid,
1470 &alias_rids[num_alias_rids])) {
1471 num_alias_rids += 1;
1476 *palias_rids = alias_rids;
1477 *pnum_alias_rids = 0;
1478 return NT_STATUS_OK;
1481 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1482 const DOM_SID *domain_sid,
1486 enum lsa_SidType *lsa_attrs)
1488 struct pdb_ads_state *state = talloc_get_type_abort(
1489 m->private_data, struct pdb_ads_state);
1490 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1493 if (num_rids == 0) {
1494 return NT_STATUS_NONE_MAPPED;
1499 for (i=0; i<num_rids; i++) {
1501 struct tldap_message **msg;
1506 lsa_attrs[i] = SID_NAME_UNKNOWN;
1508 sid_compose(&sid, domain_sid, rids[i]);
1510 sidstr = sid_binstring(talloc_tos(), &sid);
1511 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1513 rc = tldap_search_fmt(state->ld, state->domaindn,
1514 TLDAP_SCOPE_SUB, attrs,
1515 ARRAY_SIZE(attrs), 0, talloc_tos(),
1516 &msg, "(objectsid=%s)", sidstr);
1517 TALLOC_FREE(sidstr);
1518 if (rc != TLDAP_SUCCESS) {
1519 DEBUG(10, ("ldap_search failed %s\n",
1520 tldap_errstr(debug_ctx(), state->ld, rc)));
1524 switch talloc_array_length(msg) {
1526 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1531 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1534 names[i] = tldap_talloc_single_attribute(
1535 msg[0], "samAccountName", talloc_tos());
1536 if (names[i] == NULL) {
1537 DEBUG(10, ("no samAccountName\n"));
1540 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1541 DEBUG(10, ("no samAccountType"));
1544 lsa_attrs[i] = ads_atype_map(attr);
1548 if (num_mapped == 0) {
1549 return NT_STATUS_NONE_MAPPED;
1551 if (num_mapped < num_rids) {
1552 return STATUS_SOME_UNMAPPED;
1554 return NT_STATUS_OK;
1557 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1558 const DOM_SID *domain_sid,
1560 const char **pp_names,
1562 enum lsa_SidType *attrs)
1564 return NT_STATUS_NOT_IMPLEMENTED;
1567 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1568 int policy_index, uint32 *value)
1570 return account_policy_get(policy_index, value)
1571 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1574 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1575 int policy_index, uint32 value)
1577 return account_policy_set(policy_index, value)
1578 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1581 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1584 return NT_STATUS_NOT_IMPLEMENTED;
1587 struct pdb_ads_search_state {
1588 uint32_t acct_flags;
1589 struct samr_displayentry *entries;
1590 uint32_t num_entries;
1595 static bool pdb_ads_next_entry(struct pdb_search *search,
1596 struct samr_displayentry *entry)
1598 struct pdb_ads_search_state *state = talloc_get_type_abort(
1599 search->private_data, struct pdb_ads_search_state);
1601 if (state->current == state->num_entries) {
1605 entry->idx = state->entries[state->current].idx;
1606 entry->rid = state->entries[state->current].rid;
1607 entry->acct_flags = state->entries[state->current].acct_flags;
1609 entry->account_name = talloc_strdup(
1610 search, state->entries[state->current].account_name);
1611 entry->fullname = talloc_strdup(
1612 search, state->entries[state->current].fullname);
1613 entry->description = talloc_strdup(
1614 search, state->entries[state->current].description);
1616 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1617 || (entry->description == NULL)) {
1618 DEBUG(0, ("talloc_strdup failed\n"));
1622 state->current += 1;
1626 static void pdb_ads_search_end(struct pdb_search *search)
1628 struct pdb_ads_search_state *state = talloc_get_type_abort(
1629 search->private_data, struct pdb_ads_search_state);
1633 static bool pdb_ads_search_filter(struct pdb_methods *m,
1634 struct pdb_search *search,
1636 struct pdb_ads_search_state **pstate)
1638 struct pdb_ads_state *state = talloc_get_type_abort(
1639 m->private_data, struct pdb_ads_state);
1640 struct pdb_ads_search_state *sstate;
1641 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1642 "userAccountControl", "description" };
1643 struct tldap_message **users;
1644 int i, rc, num_users;
1646 sstate = talloc_zero(search, struct pdb_ads_search_state);
1647 if (sstate == NULL) {
1651 rc = tldap_search_fmt(
1652 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1653 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1655 if (rc != TLDAP_SUCCESS) {
1656 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1657 tldap_errstr(debug_ctx(), state->ld, rc)));
1661 num_users = talloc_array_length(users);
1663 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1665 if (sstate->entries == NULL) {
1666 DEBUG(10, ("talloc failed\n"));
1670 sstate->num_entries = 0;
1672 for (i=0; i<num_users; i++) {
1673 struct samr_displayentry *e;
1676 e = &sstate->entries[sstate->num_entries];
1678 e->idx = sstate->num_entries;
1679 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1680 DEBUG(10, ("Could not pull sid\n"));
1683 sid_peek_rid(&sid, &e->rid);
1684 e->acct_flags = ACB_NORMAL;
1685 e->account_name = tldap_talloc_single_attribute(
1686 users[i], "samAccountName", sstate->entries);
1687 if (e->account_name == NULL) {
1690 e->fullname = tldap_talloc_single_attribute(
1691 users[i], "displayName", sstate->entries);
1692 if (e->fullname == NULL) {
1695 e->description = tldap_talloc_single_attribute(
1696 users[i], "description", sstate->entries);
1697 if (e->description == NULL) {
1698 e->description = "";
1701 sstate->num_entries += 1;
1702 if (sstate->num_entries >= num_users) {
1707 search->private_data = sstate;
1708 search->next_entry = pdb_ads_next_entry;
1709 search->search_end = pdb_ads_search_end;
1714 static bool pdb_ads_search_users(struct pdb_methods *m,
1715 struct pdb_search *search,
1718 struct pdb_ads_search_state *sstate;
1721 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1725 sstate->acct_flags = acct_flags;
1729 static bool pdb_ads_search_groups(struct pdb_methods *m,
1730 struct pdb_search *search)
1732 struct pdb_ads_search_state *sstate;
1736 filter = talloc_asprintf(talloc_tos(),
1737 "(&(grouptype=%d)(objectclass=group))",
1738 GTYPE_SECURITY_GLOBAL_GROUP);
1739 if (filter == NULL) {
1742 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1743 TALLOC_FREE(filter);
1747 sstate->acct_flags = 0;
1751 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1752 struct pdb_search *search,
1755 struct pdb_ads_search_state *sstate;
1759 filter = talloc_asprintf(
1760 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1761 sid_check_is_builtin(sid)
1762 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1763 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1765 if (filter == NULL) {
1768 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1769 TALLOC_FREE(filter);
1773 sstate->acct_flags = 0;
1777 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1783 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1786 struct pdb_ads_state *state = talloc_get_type_abort(
1787 m->private_data, struct pdb_ads_state);
1788 sid_compose(sid, &state->domainsid, uid);
1792 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1795 struct pdb_ads_state *state = talloc_get_type_abort(
1796 m->private_data, struct pdb_ads_state);
1797 sid_compose(sid, &state->domainsid, gid);
1801 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1802 union unid_t *id, enum lsa_SidType *type)
1804 struct pdb_ads_state *state = talloc_get_type_abort(
1805 m->private_data, struct pdb_ads_state);
1806 struct tldap_message **msg;
1812 * This is a big, big hack: Just hard-code the rid as uid/gid.
1815 sid_peek_rid(sid, &rid);
1817 sidstr = sid_binstring(talloc_tos(), sid);
1818 if (sidstr == NULL) {
1822 rc = tldap_search_fmt(
1823 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1824 NULL, 0, 0, talloc_tos(), &msg,
1825 "(&(objectsid=%s)(objectclass=user))", sidstr);
1826 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1828 *type = SID_NAME_USER;
1829 TALLOC_FREE(sidstr);
1833 rc = tldap_search_fmt(
1834 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1835 NULL, 0, 0, talloc_tos(), &msg,
1836 "(&(objectsid=%s)(objectclass=group))", sidstr);
1837 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1839 *type = SID_NAME_DOM_GRP;
1840 TALLOC_FREE(sidstr);
1844 TALLOC_FREE(sidstr);
1848 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1853 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1858 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1859 const char *domain, char** pwd,
1861 time_t *pass_last_set_time)
1866 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1867 const char* domain, const char* pwd,
1873 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1879 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1880 TALLOC_CTX *mem_ctx,
1881 uint32 *num_domains,
1882 struct trustdom_info ***domains)
1884 return NT_STATUS_NOT_IMPLEMENTED;
1887 static void pdb_ads_init_methods(struct pdb_methods *m)
1890 m->getsampwnam = pdb_ads_getsampwnam;
1891 m->getsampwsid = pdb_ads_getsampwsid;
1892 m->create_user = pdb_ads_create_user;
1893 m->delete_user = pdb_ads_delete_user;
1894 m->add_sam_account = pdb_ads_add_sam_account;
1895 m->update_sam_account = pdb_ads_update_sam_account;
1896 m->delete_sam_account = pdb_ads_delete_sam_account;
1897 m->rename_sam_account = pdb_ads_rename_sam_account;
1898 m->update_login_attempts = pdb_ads_update_login_attempts;
1899 m->getgrsid = pdb_ads_getgrsid;
1900 m->getgrgid = pdb_ads_getgrgid;
1901 m->getgrnam = pdb_ads_getgrnam;
1902 m->create_dom_group = pdb_ads_create_dom_group;
1903 m->delete_dom_group = pdb_ads_delete_dom_group;
1904 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1905 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1906 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1907 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1908 m->enum_group_members = pdb_ads_enum_group_members;
1909 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1910 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1911 m->add_groupmem = pdb_ads_add_groupmem;
1912 m->del_groupmem = pdb_ads_del_groupmem;
1913 m->create_alias = pdb_ads_create_alias;
1914 m->delete_alias = pdb_ads_delete_alias;
1915 m->get_aliasinfo = pdb_default_get_aliasinfo;
1916 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1917 m->add_aliasmem = pdb_ads_add_aliasmem;
1918 m->del_aliasmem = pdb_ads_del_aliasmem;
1919 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1920 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1921 m->lookup_rids = pdb_ads_lookup_rids;
1922 m->lookup_names = pdb_ads_lookup_names;
1923 m->get_account_policy = pdb_ads_get_account_policy;
1924 m->set_account_policy = pdb_ads_set_account_policy;
1925 m->get_seq_num = pdb_ads_get_seq_num;
1926 m->search_users = pdb_ads_search_users;
1927 m->search_groups = pdb_ads_search_groups;
1928 m->search_aliases = pdb_ads_search_aliases;
1929 m->uid_to_rid = pdb_ads_uid_to_rid;
1930 m->uid_to_sid = pdb_ads_uid_to_sid;
1931 m->gid_to_sid = pdb_ads_gid_to_sid;
1932 m->sid_to_id = pdb_ads_sid_to_id;
1933 m->rid_algorithm = pdb_ads_rid_algorithm;
1934 m->new_rid = pdb_ads_new_rid;
1935 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1936 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1937 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1938 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1941 static void free_private_data(void **vp)
1943 struct pdb_ads_state *state = talloc_get_type_abort(
1944 *vp, struct pdb_ads_state);
1946 TALLOC_FREE(state->ld);
1951 this is used to catch debug messages from events
1953 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
1954 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
1956 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
1957 const char *fmt, va_list ap)
1959 int samba_level = -1;
1962 case TLDAP_DEBUG_FATAL:
1965 case TLDAP_DEBUG_ERROR:
1968 case TLDAP_DEBUG_WARNING:
1971 case TLDAP_DEBUG_TRACE:
1976 if (vasprintf(&s, fmt, ap) == -1) {
1979 DEBUG(samba_level, ("tldap: %s", s));
1983 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1984 const char *location)
1986 const char *rootdse_attrs[2] = {
1987 "defaultNamingContext", "configurationNamingContext" };
1988 const char *domain_attrs[1] = { "objectSid" };
1989 const char *ncname_attrs[1] = { "netbiosname" };
1990 struct tldap_message **rootdse, **domain, **ncname;
1991 TALLOC_CTX *frame = talloc_stackframe();
1992 struct sockaddr_un sunaddr;
1997 ZERO_STRUCT(sunaddr);
1998 sunaddr.sun_family = AF_UNIX;
1999 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
2001 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
2003 if (!NT_STATUS_IS_OK(status)) {
2004 DEBUG(10, ("Could not connect to %s: %s\n", location,
2005 nt_errstr(status)));
2009 state->ld = tldap_context_create(state, fd);
2010 if (state->ld == NULL) {
2012 status = NT_STATUS_NO_MEMORY;
2015 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2017 rc = tldap_search_fmt(
2018 state->ld, "", TLDAP_SCOPE_BASE,
2019 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
2020 talloc_tos(), &rootdse, "(objectclass=*)");
2021 if (rc != TLDAP_SUCCESS) {
2022 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2023 tldap_errstr(debug_ctx(), state->ld, rc)));
2024 status = NT_STATUS_LDAP(rc);
2027 if (talloc_array_length(rootdse) != 1) {
2028 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2032 state->domaindn = tldap_talloc_single_attribute(
2033 rootdse[0], "defaultNamingContext", state);
2034 if (state->domaindn == NULL) {
2035 DEBUG(10, ("Could not get defaultNamingContext\n"));
2036 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2039 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2041 state->configdn = tldap_talloc_single_attribute(
2042 rootdse[0], "configurationNamingContext", state);
2043 if (state->domaindn == NULL) {
2044 DEBUG(10, ("Could not get configurationNamingContext\n"));
2045 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2048 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2051 * Figure out our domain's SID
2053 rc = tldap_search_fmt(
2054 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
2055 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2056 talloc_tos(), &domain, "(objectclass=*)");
2057 if (rc != TLDAP_SUCCESS) {
2058 DEBUG(10, ("Could not retrieve domain: %s\n",
2059 tldap_errstr(debug_ctx(), state->ld, rc)));
2060 status = NT_STATUS_LDAP(rc);
2064 num_domains = talloc_array_length(domain);
2065 if (num_domains != 1) {
2066 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2067 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2070 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2071 DEBUG(10, ("Could not retrieve domain SID\n"));
2072 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2075 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2078 * Figure out our domain's short name
2080 rc = tldap_search_fmt(
2081 state->ld, state->configdn, TLDAP_SCOPE_SUB,
2082 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2083 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2084 if (rc != TLDAP_SUCCESS) {
2085 DEBUG(10, ("Could not retrieve ncname: %s\n",
2086 tldap_errstr(debug_ctx(), state->ld, rc)));
2087 status = NT_STATUS_LDAP(rc);
2090 if (talloc_array_length(ncname) != 1) {
2091 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2095 state->netbiosname = tldap_talloc_single_attribute(
2096 ncname[0], "netbiosname", state);
2097 if (state->netbiosname == NULL) {
2098 DEBUG(10, ("Could not get netbiosname\n"));
2099 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2102 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2104 if (!strequal(lp_workgroup(), state->netbiosname)) {
2105 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2106 state->netbiosname, lp_workgroup()));
2107 status = NT_STATUS_NO_SUCH_DOMAIN;
2111 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2113 status = NT_STATUS_OK;
2119 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2120 const char *location)
2122 struct pdb_methods *m;
2123 struct pdb_ads_state *state;
2127 m = talloc(talloc_autofree_context(), struct pdb_methods);
2129 return NT_STATUS_NO_MEMORY;
2131 state = talloc(m, struct pdb_ads_state);
2132 if (state == NULL) {
2135 m->private_data = state;
2136 m->free_private_data = free_private_data;
2137 pdb_ads_init_methods(m);
2139 if (location == NULL) {
2140 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2144 if (location == NULL) {
2148 status = pdb_ads_connect(state, location);
2149 if (!NT_STATUS_IS_OK(status)) {
2150 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2155 return NT_STATUS_OK;
2157 status = NT_STATUS_NO_MEMORY;
2163 NTSTATUS pdb_ads_init(void);
2164 NTSTATUS pdb_ads_init(void)
2166 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",