2 Unix SMB/CIFS implementation.
3 pdb_ldap with ads schema
4 Copyright (C) Volker Lendecke 2009
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 struct pdb_ads_state {
23 struct tldap_context *ld;
24 struct dom_sid domainsid;
30 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
31 struct samu *sam_acct,
33 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
35 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
36 struct dom_sid *psid);
37 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
38 const struct dom_sid *sid,
39 TALLOC_CTX *mem_ctx, char **pdn);
41 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
46 if (!tldap_pull_uint64(msg, attr, &tmp)) {
49 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
53 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
56 sid_peek_rid(sid, &rid);
60 struct pdb_ads_samu_private {
62 struct tldap_message *ldapmsg;
65 static struct samu *pdb_ads_init_guest(TALLOC_CTX *mem_ctx,
66 struct pdb_methods *m)
68 struct pdb_ads_state *state = talloc_get_type_abort(
69 m->private_data, struct pdb_ads_state);
70 struct dom_sid guest_sid;
74 sid_compose(&guest_sid, &state->domainsid, DOMAIN_USER_RID_GUEST);
76 guest = samu_new(mem_ctx);
81 status = pdb_ads_getsampwsid(m, guest, &guest_sid);
82 if (!NT_STATUS_IS_OK(status)) {
83 DEBUG(10, ("Could not init guest account: %s\n",
91 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
92 struct pdb_methods *m, struct samu *sam)
94 struct pdb_ads_samu_private *result;
97 result = (struct pdb_ads_samu_private *)
98 pdb_get_backend_private_data(sam, m);
100 if (result != NULL) {
101 return talloc_get_type_abort(
102 result, struct pdb_ads_samu_private);
106 * This is now a weirdness of the passdb API. For the guest user we
107 * are not asked first.
109 sid_peek_rid(pdb_get_user_sid(sam), &rid);
111 if (rid == DOMAIN_USER_RID_GUEST) {
112 struct samu *guest = pdb_ads_init_guest(talloc_tos(), m);
117 result = talloc_get_type_abort(
118 pdb_get_backend_private_data(guest, m),
119 struct pdb_ads_samu_private);
120 pdb_set_backend_private_data(
121 sam, talloc_move(sam, &result), NULL, m, PDB_SET);
123 return talloc_get_type_abort(
124 pdb_get_backend_private_data(sam, m),
125 struct pdb_ads_samu_private);
131 static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m,
133 struct tldap_message *entry)
135 struct pdb_ads_state *state = talloc_get_type_abort(
136 m->private_data, struct pdb_ads_state);
137 TALLOC_CTX *frame = talloc_stackframe();
138 struct pdb_ads_samu_private *priv;
139 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
146 priv = talloc(sam, struct pdb_ads_samu_private);
148 return NT_STATUS_NO_MEMORY;
150 if (!tldap_entry_dn(entry, &priv->dn)) {
152 return NT_STATUS_INTERNAL_DB_CORRUPTION;
155 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
157 DEBUG(10, ("no samAccountName\n"));
160 pdb_set_username(sam, str, PDB_SET);
162 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
163 pdb_set_logon_time(sam, tmp_time, PDB_SET);
165 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
166 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
168 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
169 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
171 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
172 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
175 str = tldap_talloc_single_attribute(entry, "displayName",
178 pdb_set_fullname(sam, str, PDB_SET);
181 str = tldap_talloc_single_attribute(entry, "homeDirectory",
184 pdb_set_homedir(sam, str, PDB_SET);
187 str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
189 pdb_set_dir_drive(sam, str, PDB_SET);
192 str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
194 pdb_set_logon_script(sam, str, PDB_SET);
197 str = tldap_talloc_single_attribute(entry, "profilePath",
200 pdb_set_profile_path(sam, str, PDB_SET);
203 str = tldap_talloc_single_attribute(entry, "profilePath",
206 pdb_set_profile_path(sam, str, PDB_SET);
209 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
210 DEBUG(10, ("Could not pull SID\n"));
213 pdb_set_user_sid(sam, &sid, PDB_SET);
215 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
216 DEBUG(10, ("Could not pull userAccountControl\n"));
219 pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET);
221 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
222 if (blob.length != NT_HASH_LEN) {
223 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
224 (int)blob.length, NT_HASH_LEN));
227 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
230 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
231 if (blob.length != LM_HASH_LEN) {
232 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
233 (int)blob.length, LM_HASH_LEN));
236 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
239 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
240 sid_compose(&sid, &state->domainsid, n);
241 pdb_set_group_sid(sam, &sid, PDB_SET);
245 priv->ldapmsg = talloc_move(priv, &entry);
246 pdb_set_backend_private_data(sam, priv, NULL, m, PDB_SET);
248 status = NT_STATUS_OK;
254 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
255 struct tldap_message *existing,
257 int *pnum_mods, struct tldap_mod **pmods,
262 /* TODO: All fields :-) */
264 ret &= tldap_make_mod_fmt(
265 existing, mem_ctx, pnum_mods, pmods, "displayName",
266 "%s", pdb_get_fullname(sam));
268 ret &= tldap_make_mod_blob(
269 existing, mem_ctx, pnum_mods, pmods, "unicodePwd",
270 data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN));
272 ret &= tldap_make_mod_blob(
273 existing, mem_ctx, pnum_mods, pmods, "dBCSPwd",
274 data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN));
276 ret &= tldap_make_mod_fmt(
277 existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
278 "%d", ads_acb2uf(pdb_get_acct_ctrl(sam)));
280 ret &= tldap_make_mod_fmt(
281 existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
282 "%s", pdb_get_homedir(sam));
284 ret &= tldap_make_mod_fmt(
285 existing, mem_ctx, pnum_mods, pmods, "homeDrive",
286 "%s", pdb_get_dir_drive(sam));
288 ret &= tldap_make_mod_fmt(
289 existing, mem_ctx, pnum_mods, pmods, "scriptPath",
290 "%s", pdb_get_logon_script(sam));
292 ret &= tldap_make_mod_fmt(
293 existing, mem_ctx, pnum_mods, pmods, "profilePath",
294 "%s", pdb_get_profile_path(sam));
299 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
300 struct pdb_ads_state *state,
301 struct samu *sam_acct,
304 const char * attrs[] = {
305 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
306 "sAMAccountName", "displayName", "homeDirectory",
307 "homeDrive", "scriptPath", "profilePath", "description",
308 "userWorkstations", "comment", "userParameters", "objectSid",
309 "primaryGroupID", "userAccountControl", "logonHours",
310 "badPwdCount", "logonCount", "countryCode", "codePage",
311 "unicodePwd", "dBCSPwd" };
312 struct tldap_message **users;
315 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
316 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
317 &users, "%s", filter);
318 if (rc != TLDAP_SUCCESS) {
319 DEBUG(10, ("ldap_search failed %s\n",
320 tldap_errstr(debug_ctx(), state->ld, rc)));
321 return NT_STATUS_LDAP(rc);
324 count = talloc_array_length(users);
326 DEBUG(10, ("Expected 1 user, got %d\n", count));
327 return NT_STATUS_INTERNAL_DB_CORRUPTION;
330 return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]);
333 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
334 struct samu *sam_acct,
335 const char *username)
337 struct pdb_ads_state *state = talloc_get_type_abort(
338 m->private_data, struct pdb_ads_state);
341 filter = talloc_asprintf(
342 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
344 NT_STATUS_HAVE_NO_MEMORY(filter);
346 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
349 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
350 struct samu *sam_acct,
353 struct pdb_ads_state *state = talloc_get_type_abort(
354 m->private_data, struct pdb_ads_state);
355 char *sidstr, *filter;
357 sidstr = sid_binstring(talloc_tos(), sid);
358 NT_STATUS_HAVE_NO_MEMORY(sidstr);
360 filter = talloc_asprintf(
361 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
363 NT_STATUS_HAVE_NO_MEMORY(filter);
365 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
368 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
370 const char *name, uint32 acct_flags,
373 struct pdb_ads_state *state = talloc_get_type_abort(
374 m->private_data, struct pdb_ads_state);
375 const char *attrs[1] = { "objectSid" };
376 struct tldap_mod *mods = NULL;
378 struct tldap_message **user;
384 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
387 return NT_STATUS_NO_MEMORY;
390 /* TODO: Create machines etc */
393 ok &= tldap_make_mod_fmt(
394 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
395 ok &= tldap_make_mod_fmt(
396 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
399 return NT_STATUS_NO_MEMORY;
402 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
403 if (rc != TLDAP_SUCCESS) {
404 DEBUG(10, ("ldap_add failed %s\n",
405 tldap_errstr(debug_ctx(), state->ld, rc)));
407 return NT_STATUS_LDAP(rc);
410 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
411 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &user,
412 "(&(objectclass=user)(samaccountname=%s))",
414 if (rc != TLDAP_SUCCESS) {
415 DEBUG(10, ("Could not find just created user %s: %s\n",
416 name, tldap_errstr(debug_ctx(), state->ld, rc)));
418 return NT_STATUS_LDAP(rc);
421 if (talloc_array_length(user) != 1) {
422 DEBUG(10, ("Got %d users, expected one\n",
423 (int)talloc_array_length(user)));
425 return NT_STATUS_LDAP(rc);
428 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
429 DEBUG(10, ("Could not fetch objectSid from user %s\n",
432 return NT_STATUS_INTERNAL_DB_CORRUPTION;
435 sid_peek_rid(&sid, rid);
440 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
444 struct pdb_ads_state *state = talloc_get_type_abort(
445 m->private_data, struct pdb_ads_state);
450 status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
452 if (!NT_STATUS_IS_OK(status)) {
456 rc = tldap_delete(state->ld, dn, NULL, NULL);
458 if (rc != TLDAP_SUCCESS) {
459 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
460 tldap_errstr(debug_ctx(), state->ld, rc)));
461 return NT_STATUS_LDAP(rc);
466 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
467 struct samu *sampass)
469 return NT_STATUS_NOT_IMPLEMENTED;
472 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
475 struct pdb_ads_state *state = talloc_get_type_abort(
476 m->private_data, struct pdb_ads_state);
477 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
478 struct tldap_mod *mods = NULL;
479 int rc, num_mods = 0;
481 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
482 &num_mods, &mods, sam)) {
483 return NT_STATUS_NO_MEMORY;
487 /* Nothing to do, just return success */
491 rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, NULL);
492 if (rc != TLDAP_SUCCESS) {
493 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
494 tldap_errstr(debug_ctx(), state->ld, rc)));
495 return NT_STATUS_LDAP(rc);
503 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
504 struct samu *username)
506 return NT_STATUS_NOT_IMPLEMENTED;
509 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
510 struct samu *oldname,
513 return NT_STATUS_NOT_IMPLEMENTED;
516 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
517 struct samu *sam_acct,
520 return NT_STATUS_NOT_IMPLEMENTED;
523 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
526 struct pdb_ads_state *state = talloc_get_type_abort(
527 m->private_data, struct pdb_ads_state);
528 const char *attrs[4] = { "objectSid", "description", "samAccountName",
531 struct tldap_message **group;
535 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
536 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
537 &group, "%s", filter);
538 if (rc != TLDAP_SUCCESS) {
539 DEBUG(10, ("ldap_search failed %s\n",
540 tldap_errstr(debug_ctx(), state->ld, rc)));
541 return NT_STATUS_LDAP(rc);
543 if (talloc_array_length(group) != 1) {
544 DEBUG(10, ("Expected 1 user, got %d\n",
545 (int)talloc_array_length(group)));
546 return NT_STATUS_INTERNAL_DB_CORRUPTION;
549 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
550 return NT_STATUS_INTERNAL_DB_CORRUPTION;
552 map->gid = pdb_ads_sid2gid(&map->sid);
554 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
555 return NT_STATUS_INTERNAL_DB_CORRUPTION;
558 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
559 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
560 map->sid_name_use = SID_NAME_ALIAS;
562 case GTYPE_SECURITY_GLOBAL_GROUP:
563 map->sid_name_use = SID_NAME_DOM_GRP;
566 return NT_STATUS_INTERNAL_DB_CORRUPTION;
569 str = tldap_talloc_single_attribute(group[0], "samAccountName",
572 return NT_STATUS_INTERNAL_DB_CORRUPTION;
574 fstrcpy(map->nt_name, str);
577 str = tldap_talloc_single_attribute(group[0], "description",
580 fstrcpy(map->comment, str);
583 map->comment[0] = '\0';
590 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
596 filter = talloc_asprintf(talloc_tos(),
597 "(&(objectsid=%s)(objectclass=group))",
598 sid_string_talloc(talloc_tos(), &sid));
599 if (filter == NULL) {
600 return NT_STATUS_NO_MEMORY;
603 status = pdb_ads_getgrfilter(m, map, filter);
608 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
612 pdb_ads_gid_to_sid(m, gid, &sid);
613 return pdb_ads_getgrsid(m, map, sid);
616 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
622 filter = talloc_asprintf(talloc_tos(),
623 "(&(samaccountname=%s)(objectclass=group))",
625 if (filter == NULL) {
626 return NT_STATUS_NO_MEMORY;
629 status = pdb_ads_getgrfilter(m, map, filter);
634 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
635 TALLOC_CTX *mem_ctx, const char *name,
638 TALLOC_CTX *frame = talloc_stackframe();
639 struct pdb_ads_state *state = talloc_get_type_abort(
640 m->private_data, struct pdb_ads_state);
641 const char *attrs[1] = { "objectSid" };
643 struct tldap_mod *mods = NULL;
644 struct tldap_message **alias;
650 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
654 return NT_STATUS_NO_MEMORY;
657 ok &= tldap_make_mod_fmt(
658 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
660 ok &= tldap_make_mod_fmt(
661 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
662 ok &= tldap_make_mod_fmt(
663 NULL, talloc_tos(), &num_mods, &mods, "groupType",
664 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
668 return NT_STATUS_NO_MEMORY;
671 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
672 if (rc != TLDAP_SUCCESS) {
673 DEBUG(10, ("ldap_add failed %s\n",
674 tldap_errstr(debug_ctx(), state->ld, rc)));
676 return NT_STATUS_LDAP(rc);
679 rc = tldap_search_fmt(
680 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
681 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
682 "(&(objectclass=group)(samaccountname=%s))", name);
683 if (rc != TLDAP_SUCCESS) {
684 DEBUG(10, ("Could not find just created alias %s: %s\n",
685 name, tldap_errstr(debug_ctx(), state->ld, rc)));
687 return NT_STATUS_LDAP(rc);
690 if (talloc_array_length(alias) != 1) {
691 DEBUG(10, ("Got %d alias, expected one\n",
692 (int)talloc_array_length(alias)));
694 return NT_STATUS_LDAP(rc);
697 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
698 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
701 return NT_STATUS_INTERNAL_DB_CORRUPTION;
704 sid_peek_rid(&sid, rid);
709 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
710 TALLOC_CTX *mem_ctx, uint32 rid)
712 struct pdb_ads_state *state = talloc_get_type_abort(
713 m->private_data, struct pdb_ads_state);
716 struct tldap_message **msg;
720 sid_compose(&sid, &state->domainsid, rid);
722 sidstr = sid_binstring(talloc_tos(), &sid);
723 NT_STATUS_HAVE_NO_MEMORY(sidstr);
725 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
726 NULL, 0, 0, talloc_tos(), &msg,
727 ("(&(objectSid=%s)(objectClass=group))"),
730 if (rc != TLDAP_SUCCESS) {
731 DEBUG(10, ("ldap_search failed %s\n",
732 tldap_errstr(debug_ctx(), state->ld, rc)));
733 return NT_STATUS_LDAP(rc);
736 switch talloc_array_length(msg) {
738 return NT_STATUS_NO_SUCH_GROUP;
742 return NT_STATUS_INTERNAL_DB_CORRUPTION;
745 if (!tldap_entry_dn(msg[0], &dn)) {
746 return NT_STATUS_INTERNAL_DB_CORRUPTION;
749 rc = tldap_delete(state->ld, dn, NULL, NULL);
750 if (rc != TLDAP_SUCCESS) {
751 DEBUG(10, ("ldap_delete failed: %s\n",
752 tldap_errstr(debug_ctx(), state->ld, rc)));
754 return NT_STATUS_LDAP(rc);
761 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
764 return NT_STATUS_NOT_IMPLEMENTED;
767 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
770 return NT_STATUS_NOT_IMPLEMENTED;
773 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
776 return NT_STATUS_NOT_IMPLEMENTED;
779 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
781 enum lsa_SidType sid_name_use,
783 size_t *p_num_entries,
786 return NT_STATUS_NOT_IMPLEMENTED;
789 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
791 const DOM_SID *group,
793 size_t *pnum_members)
795 struct pdb_ads_state *state = talloc_get_type_abort(
796 m->private_data, struct pdb_ads_state);
797 const char *attrs[1] = { "member" };
799 struct tldap_message **msg;
800 int i, rc, num_members;
804 sidstr = sid_binstring(talloc_tos(), group);
805 NT_STATUS_HAVE_NO_MEMORY(sidstr);
807 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
808 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
809 "(objectsid=%s)", sidstr);
811 if (rc != TLDAP_SUCCESS) {
812 DEBUG(10, ("ldap_search failed %s\n",
813 tldap_errstr(debug_ctx(), state->ld, rc)));
814 return NT_STATUS_LDAP(rc);
816 switch talloc_array_length(msg) {
818 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
823 return NT_STATUS_INTERNAL_DB_CORRUPTION;
827 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
828 return NT_STATUS_INTERNAL_DB_CORRUPTION;
831 members = talloc_array(mem_ctx, uint32_t, num_members);
832 if (members == NULL) {
833 return NT_STATUS_NO_MEMORY;
836 for (i=0; i<num_members; i++) {
838 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &sid)
839 || !sid_peek_rid(&sid, &members[i])) {
840 TALLOC_FREE(members);
841 return NT_STATUS_INTERNAL_DB_CORRUPTION;
846 *pnum_members = num_members;
850 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
855 size_t *p_num_groups)
857 struct pdb_ads_state *state = talloc_get_type_abort(
858 m->private_data, struct pdb_ads_state);
859 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
861 const char *attrs[1] = { "objectSid" };
862 struct tldap_message **groups;
865 struct dom_sid *group_sids;
868 rc = tldap_search_fmt(
869 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
870 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
871 "(&(member=%s)(grouptype=%d)(objectclass=group))",
872 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
873 if (rc != TLDAP_SUCCESS) {
874 DEBUG(10, ("ldap_search failed %s\n",
875 tldap_errstr(debug_ctx(), state->ld, rc)));
876 return NT_STATUS_LDAP(rc);
879 count = talloc_array_length(groups);
881 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
882 if (group_sids == NULL) {
883 return NT_STATUS_NO_MEMORY;
885 gids = talloc_array(mem_ctx, gid_t, count);
887 TALLOC_FREE(group_sids);
888 return NT_STATUS_NO_MEMORY;
892 for (i=0; i<count; i++) {
893 if (!tldap_pull_binsid(groups[i], "objectSid",
894 &group_sids[num_groups])) {
897 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
900 if (num_groups == count) {
905 *pp_sids = group_sids;
907 *p_num_groups = num_groups;
911 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
915 return NT_STATUS_NOT_IMPLEMENTED;
918 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
920 uint32 grouprid, uint32 memberrid,
923 struct pdb_ads_state *state = talloc_get_type_abort(
924 m->private_data, struct pdb_ads_state);
925 TALLOC_CTX *frame = talloc_stackframe();
926 struct dom_sid groupsid, membersid;
927 char *groupdn, *memberdn;
928 struct tldap_mod *mods;
932 sid_compose(&groupsid, &state->domainsid, grouprid);
933 sid_compose(&membersid, &state->domainsid, memberrid);
935 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
936 if (!NT_STATUS_IS_OK(status)) {
938 return NT_STATUS_NO_SUCH_GROUP;
940 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
941 if (!NT_STATUS_IS_OK(status)) {
943 return NT_STATUS_NO_SUCH_USER;
948 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
949 "member", memberdn)) {
951 return NT_STATUS_NO_MEMORY;
954 rc = tldap_modify(state->ld, groupdn, 1, mods, NULL, NULL);
956 if (rc != TLDAP_SUCCESS) {
957 DEBUG(10, ("ldap_modify failed: %s\n",
958 tldap_errstr(debug_ctx(), state->ld, rc)));
959 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
960 return NT_STATUS_MEMBER_IN_GROUP;
962 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
963 return NT_STATUS_MEMBER_NOT_IN_GROUP;
965 return NT_STATUS_LDAP(rc);
971 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
973 uint32 group_rid, uint32 member_rid)
975 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
979 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
981 uint32 group_rid, uint32 member_rid)
983 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
987 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
988 const char *name, uint32 *rid)
990 TALLOC_CTX *frame = talloc_stackframe();
991 struct pdb_ads_state *state = talloc_get_type_abort(
992 m->private_data, struct pdb_ads_state);
993 const char *attrs[1] = { "objectSid" };
995 struct tldap_mod *mods = NULL;
996 struct tldap_message **alias;
1002 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1006 return NT_STATUS_NO_MEMORY;
1009 ok &= tldap_make_mod_fmt(
1010 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
1012 ok &= tldap_make_mod_fmt(
1013 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
1014 ok &= tldap_make_mod_fmt(
1015 NULL, talloc_tos(), &num_mods, &mods, "groupType",
1016 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1020 return NT_STATUS_NO_MEMORY;
1023 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
1024 if (rc != TLDAP_SUCCESS) {
1025 DEBUG(10, ("ldap_add failed %s\n",
1026 tldap_errstr(debug_ctx(), state->ld, rc)));
1028 return NT_STATUS_LDAP(rc);
1031 rc = tldap_search_fmt(
1032 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1033 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1034 "(&(objectclass=group)(samaccountname=%s))", name);
1035 if (rc != TLDAP_SUCCESS) {
1036 DEBUG(10, ("Could not find just created alias %s: %s\n",
1037 name, tldap_errstr(debug_ctx(), state->ld, rc)));
1039 return NT_STATUS_LDAP(rc);
1042 if (talloc_array_length(alias) != 1) {
1043 DEBUG(10, ("Got %d alias, expected one\n",
1044 (int)talloc_array_length(alias)));
1046 return NT_STATUS_LDAP(rc);
1049 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1050 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1053 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1056 sid_peek_rid(&sid, rid);
1058 return NT_STATUS_OK;
1061 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1064 struct pdb_ads_state *state = talloc_get_type_abort(
1065 m->private_data, struct pdb_ads_state);
1066 struct tldap_message **alias;
1070 sidstr = sid_binstring(talloc_tos(), sid);
1071 if (sidstr == NULL) {
1072 return NT_STATUS_NO_MEMORY;
1075 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1076 NULL, 0, 0, talloc_tos(), &alias,
1077 "(&(objectSid=%s)(objectclass=group)"
1078 "(|(grouptype=%d)(grouptype=%d)))",
1079 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1080 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1081 TALLOC_FREE(sidstr);
1082 if (rc != TLDAP_SUCCESS) {
1083 DEBUG(10, ("ldap_search failed: %s\n",
1084 tldap_errstr(debug_ctx(), state->ld, rc)));
1086 return NT_STATUS_LDAP(rc);
1088 if (talloc_array_length(alias) != 1) {
1089 DEBUG(10, ("Expected 1 alias, got %d\n",
1090 (int)talloc_array_length(alias)));
1091 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1093 if (!tldap_entry_dn(alias[0], &dn)) {
1094 DEBUG(10, ("Could not get DN for alias %s\n",
1095 sid_string_dbg(sid)));
1096 return NT_STATUS_INTERNAL_ERROR;
1099 rc = tldap_delete(state->ld, dn, NULL, NULL);
1100 if (rc != TLDAP_SUCCESS) {
1101 DEBUG(10, ("ldap_delete failed: %s\n",
1102 tldap_errstr(debug_ctx(), state->ld, rc)));
1104 return NT_STATUS_LDAP(rc);
1107 return NT_STATUS_OK;
1110 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
1112 struct acct_info *info)
1114 return NT_STATUS_NOT_IMPLEMENTED;
1117 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1119 struct acct_info *info)
1121 return NT_STATUS_NOT_IMPLEMENTED;
1124 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1125 const struct dom_sid *sid,
1126 TALLOC_CTX *mem_ctx, char **pdn)
1128 struct tldap_message **msg;
1132 sidstr = sid_binstring(talloc_tos(), sid);
1133 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1135 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1136 NULL, 0, 0, talloc_tos(), &msg,
1137 "(objectsid=%s)", sidstr);
1138 TALLOC_FREE(sidstr);
1139 if (rc != TLDAP_SUCCESS) {
1140 DEBUG(10, ("ldap_search failed %s\n",
1141 tldap_errstr(debug_ctx(), state->ld, rc)));
1142 return NT_STATUS_LDAP(rc);
1145 switch talloc_array_length(msg) {
1147 return NT_STATUS_NOT_FOUND;
1151 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1154 if (!tldap_entry_dn(msg[0], &dn)) {
1155 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1158 dn = talloc_strdup(mem_ctx, dn);
1160 return NT_STATUS_NO_MEMORY;
1165 return NT_STATUS_OK;
1168 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1169 const DOM_SID *alias,
1170 const DOM_SID *member,
1173 struct pdb_ads_state *state = talloc_get_type_abort(
1174 m->private_data, struct pdb_ads_state);
1175 TALLOC_CTX *frame = talloc_stackframe();
1176 struct tldap_mod *mods;
1178 char *aliasdn, *memberdn;
1181 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1182 if (!NT_STATUS_IS_OK(status)) {
1183 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1184 sid_string_dbg(alias), nt_errstr(status)));
1186 return NT_STATUS_NO_SUCH_ALIAS;
1188 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1189 if (!NT_STATUS_IS_OK(status)) {
1190 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1191 sid_string_dbg(member), nt_errstr(status)));
1198 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1199 "member", memberdn)) {
1201 return NT_STATUS_NO_MEMORY;
1204 rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
1206 if (rc != TLDAP_SUCCESS) {
1207 DEBUG(10, ("ldap_modify failed: %s\n",
1208 tldap_errstr(debug_ctx(), state->ld, rc)));
1209 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1210 return NT_STATUS_MEMBER_IN_ALIAS;
1212 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1213 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1215 return NT_STATUS_LDAP(rc);
1218 return NT_STATUS_OK;
1221 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1222 const DOM_SID *alias,
1223 const DOM_SID *member)
1225 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1228 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1229 const DOM_SID *alias,
1230 const DOM_SID *member)
1232 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1235 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1236 struct dom_sid *psid)
1238 const char *attrs[1] = { "objectSid" };
1239 struct tldap_message **msg;
1245 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1246 dnblob->data, dnblob->length, &dn, &len,
1250 rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1251 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1252 &msg, "(objectclass=*)");
1254 if (talloc_array_length(msg) != 1) {
1255 DEBUG(10, ("Got %d objects, expected one\n",
1256 (int)talloc_array_length(msg)));
1261 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1266 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1267 const DOM_SID *alias,
1268 TALLOC_CTX *mem_ctx,
1270 size_t *pnum_members)
1272 struct pdb_ads_state *state = talloc_get_type_abort(
1273 m->private_data, struct pdb_ads_state);
1274 const char *attrs[1] = { "member" };
1276 struct tldap_message **msg;
1277 int i, rc, num_members;
1279 struct dom_sid *members;
1281 sidstr = sid_binstring(talloc_tos(), alias);
1282 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1284 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1285 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1286 "(objectsid=%s)", sidstr);
1287 TALLOC_FREE(sidstr);
1288 if (rc != TLDAP_SUCCESS) {
1289 DEBUG(10, ("ldap_search failed %s\n",
1290 tldap_errstr(debug_ctx(), state->ld, rc)));
1291 return NT_STATUS_LDAP(rc);
1293 switch talloc_array_length(msg) {
1295 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1300 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1304 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1305 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1308 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1309 if (members == NULL) {
1310 return NT_STATUS_NO_MEMORY;
1313 for (i=0; i<num_members; i++) {
1314 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1315 TALLOC_FREE(members);
1316 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1320 *pmembers = members;
1321 *pnum_members = num_members;
1322 return NT_STATUS_OK;
1325 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1326 TALLOC_CTX *mem_ctx,
1327 const DOM_SID *domain_sid,
1328 const DOM_SID *members,
1330 uint32 **pp_alias_rids,
1331 size_t *p_num_alias_rids)
1333 return NT_STATUS_NOT_IMPLEMENTED;
1336 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1337 const DOM_SID *domain_sid,
1340 const char **pp_names,
1341 enum lsa_SidType *attrs)
1343 return NT_STATUS_NOT_IMPLEMENTED;
1346 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1347 const DOM_SID *domain_sid,
1349 const char **pp_names,
1351 enum lsa_SidType *attrs)
1353 return NT_STATUS_NOT_IMPLEMENTED;
1356 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1357 int policy_index, uint32 *value)
1359 return account_policy_get(policy_index, value)
1360 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1363 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1364 int policy_index, uint32 value)
1366 return account_policy_set(policy_index, value)
1367 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1370 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1373 return NT_STATUS_NOT_IMPLEMENTED;
1376 struct pdb_ads_search_state {
1377 uint32_t acct_flags;
1378 struct samr_displayentry *entries;
1379 uint32_t num_entries;
1384 static bool pdb_ads_next_entry(struct pdb_search *search,
1385 struct samr_displayentry *entry)
1387 struct pdb_ads_search_state *state = talloc_get_type_abort(
1388 search->private_data, struct pdb_ads_search_state);
1390 if (state->current == state->num_entries) {
1394 entry->idx = state->entries[state->current].idx;
1395 entry->rid = state->entries[state->current].rid;
1396 entry->acct_flags = state->entries[state->current].acct_flags;
1398 entry->account_name = talloc_strdup(
1399 search, state->entries[state->current].account_name);
1400 entry->fullname = talloc_strdup(
1401 search, state->entries[state->current].fullname);
1402 entry->description = talloc_strdup(
1403 search, state->entries[state->current].description);
1405 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1406 || (entry->description == NULL)) {
1407 DEBUG(0, ("talloc_strdup failed\n"));
1411 state->current += 1;
1415 static void pdb_ads_search_end(struct pdb_search *search)
1417 struct pdb_ads_search_state *state = talloc_get_type_abort(
1418 search->private_data, struct pdb_ads_search_state);
1422 static bool pdb_ads_search_filter(struct pdb_methods *m,
1423 struct pdb_search *search,
1425 struct pdb_ads_search_state **pstate)
1427 struct pdb_ads_state *state = talloc_get_type_abort(
1428 m->private_data, struct pdb_ads_state);
1429 struct pdb_ads_search_state *sstate;
1430 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1431 "userAccountControl", "description" };
1432 struct tldap_message **users;
1433 int i, rc, num_users;
1435 sstate = talloc_zero(search, struct pdb_ads_search_state);
1436 if (sstate == NULL) {
1440 rc = tldap_search_fmt(
1441 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1442 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1444 if (rc != TLDAP_SUCCESS) {
1445 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1446 tldap_errstr(debug_ctx(), state->ld, rc)));
1450 num_users = talloc_array_length(users);
1452 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1454 if (sstate->entries == NULL) {
1455 DEBUG(10, ("talloc failed\n"));
1459 sstate->num_entries = 0;
1461 for (i=0; i<num_users; i++) {
1462 struct samr_displayentry *e;
1465 e = &sstate->entries[sstate->num_entries];
1467 e->idx = sstate->num_entries;
1468 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1469 DEBUG(10, ("Could not pull sid\n"));
1472 sid_peek_rid(&sid, &e->rid);
1473 e->acct_flags = ACB_NORMAL;
1474 e->account_name = tldap_talloc_single_attribute(
1475 users[i], "samAccountName", sstate->entries);
1476 if (e->account_name == NULL) {
1479 e->fullname = tldap_talloc_single_attribute(
1480 users[i], "displayName", sstate->entries);
1481 if (e->fullname == NULL) {
1484 e->description = tldap_talloc_single_attribute(
1485 users[i], "description", sstate->entries);
1486 if (e->description == NULL) {
1487 e->description = "";
1490 sstate->num_entries += 1;
1491 if (sstate->num_entries >= num_users) {
1496 search->private_data = sstate;
1497 search->next_entry = pdb_ads_next_entry;
1498 search->search_end = pdb_ads_search_end;
1503 static bool pdb_ads_search_users(struct pdb_methods *m,
1504 struct pdb_search *search,
1507 struct pdb_ads_search_state *sstate;
1510 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1514 sstate->acct_flags = acct_flags;
1518 static bool pdb_ads_search_groups(struct pdb_methods *m,
1519 struct pdb_search *search)
1521 struct pdb_ads_search_state *sstate;
1525 filter = talloc_asprintf(talloc_tos(),
1526 "(&(grouptype=%d)(objectclass=group))",
1527 GTYPE_SECURITY_GLOBAL_GROUP);
1528 if (filter == NULL) {
1531 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1532 TALLOC_FREE(filter);
1536 sstate->acct_flags = 0;
1540 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1541 struct pdb_search *search,
1544 struct pdb_ads_search_state *sstate;
1548 filter = talloc_asprintf(
1549 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1550 sid_check_is_builtin(sid)
1551 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1552 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1554 if (filter == NULL) {
1557 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1558 TALLOC_FREE(filter);
1562 sstate->acct_flags = 0;
1566 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1572 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1575 struct pdb_ads_state *state = talloc_get_type_abort(
1576 m->private_data, struct pdb_ads_state);
1577 sid_compose(sid, &state->domainsid, uid);
1581 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1584 struct pdb_ads_state *state = talloc_get_type_abort(
1585 m->private_data, struct pdb_ads_state);
1586 sid_compose(sid, &state->domainsid, gid);
1590 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1591 union unid_t *id, enum lsa_SidType *type)
1593 struct pdb_ads_state *state = talloc_get_type_abort(
1594 m->private_data, struct pdb_ads_state);
1595 struct tldap_message **msg;
1601 * This is a big, big hack: Just hard-code the rid as uid/gid.
1604 sid_peek_rid(sid, &rid);
1606 sidstr = sid_binstring(talloc_tos(), sid);
1607 if (sidstr == NULL) {
1611 rc = tldap_search_fmt(
1612 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1613 NULL, 0, 0, talloc_tos(), &msg,
1614 "(&(objectsid=%s)(objectclass=user))", sidstr);
1615 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1617 *type = SID_NAME_USER;
1618 TALLOC_FREE(sidstr);
1622 rc = tldap_search_fmt(
1623 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1624 NULL, 0, 0, talloc_tos(), &msg,
1625 "(&(objectsid=%s)(objectclass=group))", sidstr);
1626 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1628 *type = SID_NAME_DOM_GRP;
1629 TALLOC_FREE(sidstr);
1633 TALLOC_FREE(sidstr);
1637 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1642 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1647 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1648 const char *domain, char** pwd,
1650 time_t *pass_last_set_time)
1655 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1656 const char* domain, const char* pwd,
1662 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1668 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1669 TALLOC_CTX *mem_ctx,
1670 uint32 *num_domains,
1671 struct trustdom_info ***domains)
1673 return NT_STATUS_NOT_IMPLEMENTED;
1676 static void pdb_ads_init_methods(struct pdb_methods *m)
1679 m->getsampwnam = pdb_ads_getsampwnam;
1680 m->getsampwsid = pdb_ads_getsampwsid;
1681 m->create_user = pdb_ads_create_user;
1682 m->delete_user = pdb_ads_delete_user;
1683 m->add_sam_account = pdb_ads_add_sam_account;
1684 m->update_sam_account = pdb_ads_update_sam_account;
1685 m->delete_sam_account = pdb_ads_delete_sam_account;
1686 m->rename_sam_account = pdb_ads_rename_sam_account;
1687 m->update_login_attempts = pdb_ads_update_login_attempts;
1688 m->getgrsid = pdb_ads_getgrsid;
1689 m->getgrgid = pdb_ads_getgrgid;
1690 m->getgrnam = pdb_ads_getgrnam;
1691 m->create_dom_group = pdb_ads_create_dom_group;
1692 m->delete_dom_group = pdb_ads_delete_dom_group;
1693 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1694 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1695 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1696 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1697 m->enum_group_members = pdb_ads_enum_group_members;
1698 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1699 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1700 m->add_groupmem = pdb_ads_add_groupmem;
1701 m->del_groupmem = pdb_ads_del_groupmem;
1702 m->create_alias = pdb_ads_create_alias;
1703 m->delete_alias = pdb_ads_delete_alias;
1704 m->get_aliasinfo = pdb_ads_get_aliasinfo;
1705 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1706 m->add_aliasmem = pdb_ads_add_aliasmem;
1707 m->del_aliasmem = pdb_ads_del_aliasmem;
1708 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1709 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1710 m->lookup_rids = pdb_ads_lookup_rids;
1711 m->lookup_names = pdb_ads_lookup_names;
1712 m->get_account_policy = pdb_ads_get_account_policy;
1713 m->set_account_policy = pdb_ads_set_account_policy;
1714 m->get_seq_num = pdb_ads_get_seq_num;
1715 m->search_users = pdb_ads_search_users;
1716 m->search_groups = pdb_ads_search_groups;
1717 m->search_aliases = pdb_ads_search_aliases;
1718 m->uid_to_rid = pdb_ads_uid_to_rid;
1719 m->uid_to_sid = pdb_ads_uid_to_sid;
1720 m->gid_to_sid = pdb_ads_gid_to_sid;
1721 m->sid_to_id = pdb_ads_sid_to_id;
1722 m->rid_algorithm = pdb_ads_rid_algorithm;
1723 m->new_rid = pdb_ads_new_rid;
1724 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1725 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1726 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1727 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1730 static void free_private_data(void **vp)
1732 struct pdb_ads_state *state = talloc_get_type_abort(
1733 *vp, struct pdb_ads_state);
1735 TALLOC_FREE(state->ld);
1739 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1740 const char *location)
1742 const char *rootdse_attrs[2] = {
1743 "defaultNamingContext", "configurationNamingContext" };
1744 const char *domain_attrs[1] = { "objectSid" };
1745 const char *ncname_attrs[1] = { "netbiosname" };
1746 struct tldap_message **rootdse, **domain, **ncname;
1747 TALLOC_CTX *frame = talloc_stackframe();
1748 struct sockaddr_un sunaddr;
1753 ZERO_STRUCT(sunaddr);
1754 sunaddr.sun_family = AF_UNIX;
1755 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1757 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1759 if (!NT_STATUS_IS_OK(status)) {
1760 DEBUG(10, ("Could not connect to %s: %s\n", location,
1761 nt_errstr(status)));
1765 state->ld = tldap_context_create(state, fd);
1766 if (state->ld == NULL) {
1768 status = NT_STATUS_NO_MEMORY;
1772 rc = tldap_search_fmt(
1773 state->ld, "", TLDAP_SCOPE_BASE,
1774 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1775 talloc_tos(), &rootdse, "(objectclass=*)");
1776 if (rc != TLDAP_SUCCESS) {
1777 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1778 tldap_errstr(debug_ctx(), state->ld, rc)));
1779 status = NT_STATUS_LDAP(rc);
1782 if (talloc_array_length(rootdse) != 1) {
1783 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1787 state->domaindn = tldap_talloc_single_attribute(
1788 rootdse[0], "defaultNamingContext", state);
1789 if (state->domaindn == NULL) {
1790 DEBUG(10, ("Could not get defaultNamingContext\n"));
1791 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1794 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1796 state->configdn = tldap_talloc_single_attribute(
1797 rootdse[0], "configurationNamingContext", state);
1798 if (state->domaindn == NULL) {
1799 DEBUG(10, ("Could not get configurationNamingContext\n"));
1800 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1803 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1806 * Figure out our domain's SID
1808 rc = tldap_search_fmt(
1809 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1810 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1811 talloc_tos(), &domain, "(objectclass=*)");
1812 if (rc != TLDAP_SUCCESS) {
1813 DEBUG(10, ("Could not retrieve domain: %s\n",
1814 tldap_errstr(debug_ctx(), state->ld, rc)));
1815 status = NT_STATUS_LDAP(rc);
1819 num_domains = talloc_array_length(domain);
1820 if (num_domains != 1) {
1821 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1822 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1825 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1826 DEBUG(10, ("Could not retrieve domain SID\n"));
1827 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1830 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1833 * Figure out our domain's short name
1835 rc = tldap_search_fmt(
1836 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1837 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1838 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1839 if (rc != TLDAP_SUCCESS) {
1840 DEBUG(10, ("Could not retrieve ncname: %s\n",
1841 tldap_errstr(debug_ctx(), state->ld, rc)));
1842 status = NT_STATUS_LDAP(rc);
1845 if (talloc_array_length(ncname) != 1) {
1846 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1850 state->netbiosname = tldap_talloc_single_attribute(
1851 ncname[0], "netbiosname", state);
1852 if (state->netbiosname == NULL) {
1853 DEBUG(10, ("Could not get netbiosname\n"));
1854 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1857 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1859 if (!strequal(lp_workgroup(), state->netbiosname)) {
1860 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1861 state->netbiosname, lp_workgroup()));
1862 status = NT_STATUS_NO_SUCH_DOMAIN;
1866 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1868 status = NT_STATUS_OK;
1874 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1875 const char *location)
1877 struct pdb_methods *m;
1878 struct pdb_ads_state *state;
1882 m = talloc(talloc_autofree_context(), struct pdb_methods);
1884 return NT_STATUS_NO_MEMORY;
1886 state = talloc(m, struct pdb_ads_state);
1887 if (state == NULL) {
1890 m->private_data = state;
1891 m->free_private_data = free_private_data;
1892 pdb_ads_init_methods(m);
1894 if (location == NULL) {
1895 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1899 if (location == NULL) {
1903 status = pdb_ads_connect(state, location);
1904 if (!NT_STATUS_IS_OK(status)) {
1905 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1910 return NT_STATUS_OK;
1912 status = NT_STATUS_NO_MEMORY;
1918 NTSTATUS pdb_ads_init(void);
1919 NTSTATUS pdb_ads_init(void)
1921 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",