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);
446 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
449 rc = tldap_delete(state->ld, priv->dn, NULL, NULL);
450 if (rc != TLDAP_SUCCESS) {
451 DEBUG(10, ("ldap_delete for %s failed: %s\n", priv->dn,
452 tldap_errstr(debug_ctx(), state->ld, rc)));
453 return NT_STATUS_LDAP(rc);
458 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
459 struct samu *sampass)
461 return NT_STATUS_NOT_IMPLEMENTED;
464 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
467 struct pdb_ads_state *state = talloc_get_type_abort(
468 m->private_data, struct pdb_ads_state);
469 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
470 struct tldap_mod *mods = NULL;
471 int rc, num_mods = 0;
473 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
474 &num_mods, &mods, sam)) {
475 return NT_STATUS_NO_MEMORY;
479 /* Nothing to do, just return success */
483 rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, NULL);
484 if (rc != TLDAP_SUCCESS) {
485 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
486 tldap_errstr(debug_ctx(), state->ld, rc)));
487 return NT_STATUS_LDAP(rc);
495 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
496 struct samu *username)
498 return NT_STATUS_NOT_IMPLEMENTED;
501 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
502 struct samu *oldname,
505 return NT_STATUS_NOT_IMPLEMENTED;
508 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
509 struct samu *sam_acct,
512 return NT_STATUS_NOT_IMPLEMENTED;
515 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
518 struct pdb_ads_state *state = talloc_get_type_abort(
519 m->private_data, struct pdb_ads_state);
520 const char *attrs[4] = { "objectSid", "description", "samAccountName",
523 struct tldap_message **group;
527 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
528 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
529 &group, "%s", filter);
530 if (rc != TLDAP_SUCCESS) {
531 DEBUG(10, ("ldap_search failed %s\n",
532 tldap_errstr(debug_ctx(), state->ld, rc)));
533 return NT_STATUS_LDAP(rc);
535 if (talloc_array_length(group) != 1) {
536 DEBUG(10, ("Expected 1 user, got %d\n",
537 (int)talloc_array_length(group)));
538 return NT_STATUS_INTERNAL_DB_CORRUPTION;
541 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
542 return NT_STATUS_INTERNAL_DB_CORRUPTION;
544 map->gid = pdb_ads_sid2gid(&map->sid);
546 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
547 return NT_STATUS_INTERNAL_DB_CORRUPTION;
550 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
551 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
552 map->sid_name_use = SID_NAME_ALIAS;
554 case GTYPE_SECURITY_GLOBAL_GROUP:
555 map->sid_name_use = SID_NAME_DOM_GRP;
558 return NT_STATUS_INTERNAL_DB_CORRUPTION;
561 str = tldap_talloc_single_attribute(group[0], "samAccountName",
564 return NT_STATUS_INTERNAL_DB_CORRUPTION;
566 fstrcpy(map->nt_name, str);
569 str = tldap_talloc_single_attribute(group[0], "description",
572 fstrcpy(map->comment, str);
575 map->comment[0] = '\0';
582 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
588 filter = talloc_asprintf(talloc_tos(),
589 "(&(objectsid=%s)(objectclass=group))",
590 sid_string_talloc(talloc_tos(), &sid));
591 if (filter == NULL) {
592 return NT_STATUS_NO_MEMORY;
595 status = pdb_ads_getgrfilter(m, map, filter);
600 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
604 pdb_ads_gid_to_sid(m, gid, &sid);
605 return pdb_ads_getgrsid(m, map, sid);
608 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
614 filter = talloc_asprintf(talloc_tos(),
615 "(&(samaccountname=%s)(objectclass=group))",
617 if (filter == NULL) {
618 return NT_STATUS_NO_MEMORY;
621 status = pdb_ads_getgrfilter(m, map, filter);
626 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
627 TALLOC_CTX *mem_ctx, const char *name,
630 TALLOC_CTX *frame = talloc_stackframe();
631 struct pdb_ads_state *state = talloc_get_type_abort(
632 m->private_data, struct pdb_ads_state);
633 const char *attrs[1] = { "objectSid" };
635 struct tldap_mod *mods = NULL;
636 struct tldap_message **alias;
642 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
646 return NT_STATUS_NO_MEMORY;
649 ok &= tldap_make_mod_fmt(
650 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
652 ok &= tldap_make_mod_fmt(
653 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
654 ok &= tldap_make_mod_fmt(
655 NULL, talloc_tos(), &num_mods, &mods, "groupType",
656 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
660 return NT_STATUS_NO_MEMORY;
663 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
664 if (rc != TLDAP_SUCCESS) {
665 DEBUG(10, ("ldap_add failed %s\n",
666 tldap_errstr(debug_ctx(), state->ld, rc)));
668 return NT_STATUS_LDAP(rc);
671 rc = tldap_search_fmt(
672 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
673 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
674 "(&(objectclass=group)(samaccountname=%s))", name);
675 if (rc != TLDAP_SUCCESS) {
676 DEBUG(10, ("Could not find just created alias %s: %s\n",
677 name, tldap_errstr(debug_ctx(), state->ld, rc)));
679 return NT_STATUS_LDAP(rc);
682 if (talloc_array_length(alias) != 1) {
683 DEBUG(10, ("Got %d alias, expected one\n",
684 (int)talloc_array_length(alias)));
686 return NT_STATUS_LDAP(rc);
689 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
690 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
693 return NT_STATUS_INTERNAL_DB_CORRUPTION;
696 sid_peek_rid(&sid, rid);
701 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
702 TALLOC_CTX *mem_ctx, uint32 rid)
704 struct pdb_ads_state *state = talloc_get_type_abort(
705 m->private_data, struct pdb_ads_state);
708 struct tldap_message **msg;
712 sid_compose(&sid, &state->domainsid, rid);
714 sidstr = sid_binstring(talloc_tos(), &sid);
715 NT_STATUS_HAVE_NO_MEMORY(sidstr);
717 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
718 NULL, 0, 0, talloc_tos(), &msg,
719 ("(&(objectSid=%s)(objectClass=group))"),
722 if (rc != TLDAP_SUCCESS) {
723 DEBUG(10, ("ldap_search failed %s\n",
724 tldap_errstr(debug_ctx(), state->ld, rc)));
725 return NT_STATUS_LDAP(rc);
728 switch talloc_array_length(msg) {
730 return NT_STATUS_NO_SUCH_GROUP;
734 return NT_STATUS_INTERNAL_DB_CORRUPTION;
737 if (!tldap_entry_dn(msg[0], &dn)) {
738 return NT_STATUS_INTERNAL_DB_CORRUPTION;
741 rc = tldap_delete(state->ld, dn, NULL, NULL);
742 if (rc != TLDAP_SUCCESS) {
743 DEBUG(10, ("ldap_delete failed: %s\n",
744 tldap_errstr(debug_ctx(), state->ld, rc)));
746 return NT_STATUS_LDAP(rc);
753 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
756 return NT_STATUS_NOT_IMPLEMENTED;
759 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
762 return NT_STATUS_NOT_IMPLEMENTED;
765 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
768 return NT_STATUS_NOT_IMPLEMENTED;
771 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
773 enum lsa_SidType sid_name_use,
775 size_t *p_num_entries,
778 return NT_STATUS_NOT_IMPLEMENTED;
781 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
783 const DOM_SID *group,
785 size_t *pnum_members)
787 struct pdb_ads_state *state = talloc_get_type_abort(
788 m->private_data, struct pdb_ads_state);
789 const char *attrs[1] = { "member" };
791 struct tldap_message **msg;
792 int i, rc, num_members;
796 sidstr = sid_binstring(talloc_tos(), group);
797 NT_STATUS_HAVE_NO_MEMORY(sidstr);
799 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
800 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
801 "(objectsid=%s)", sidstr);
803 if (rc != TLDAP_SUCCESS) {
804 DEBUG(10, ("ldap_search failed %s\n",
805 tldap_errstr(debug_ctx(), state->ld, rc)));
806 return NT_STATUS_LDAP(rc);
808 switch talloc_array_length(msg) {
810 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
815 return NT_STATUS_INTERNAL_DB_CORRUPTION;
819 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
820 return NT_STATUS_INTERNAL_DB_CORRUPTION;
823 members = talloc_array(mem_ctx, uint32_t, num_members);
824 if (members == NULL) {
825 return NT_STATUS_NO_MEMORY;
828 for (i=0; i<num_members; i++) {
830 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &sid)
831 || !sid_peek_rid(&sid, &members[i])) {
832 TALLOC_FREE(members);
833 return NT_STATUS_INTERNAL_DB_CORRUPTION;
838 *pnum_members = num_members;
842 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
847 size_t *p_num_groups)
849 struct pdb_ads_state *state = talloc_get_type_abort(
850 m->private_data, struct pdb_ads_state);
851 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
853 const char *attrs[1] = { "objectSid" };
854 struct tldap_message **groups;
857 struct dom_sid *group_sids;
860 rc = tldap_search_fmt(
861 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
862 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
863 "(&(member=%s)(grouptype=%d)(objectclass=group))",
864 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
865 if (rc != TLDAP_SUCCESS) {
866 DEBUG(10, ("ldap_search failed %s\n",
867 tldap_errstr(debug_ctx(), state->ld, rc)));
868 return NT_STATUS_LDAP(rc);
871 count = talloc_array_length(groups);
873 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
874 if (group_sids == NULL) {
875 return NT_STATUS_NO_MEMORY;
877 gids = talloc_array(mem_ctx, gid_t, count);
879 TALLOC_FREE(group_sids);
880 return NT_STATUS_NO_MEMORY;
884 for (i=0; i<count; i++) {
885 if (!tldap_pull_binsid(groups[i], "objectSid",
886 &group_sids[num_groups])) {
889 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
892 if (num_groups == count) {
897 *pp_sids = group_sids;
899 *p_num_groups = num_groups;
903 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
907 return NT_STATUS_NOT_IMPLEMENTED;
910 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
912 uint32 grouprid, uint32 memberrid,
915 struct pdb_ads_state *state = talloc_get_type_abort(
916 m->private_data, struct pdb_ads_state);
917 TALLOC_CTX *frame = talloc_stackframe();
918 struct dom_sid groupsid, membersid;
919 char *groupdn, *memberdn;
920 struct tldap_mod *mods;
924 sid_compose(&groupsid, &state->domainsid, grouprid);
925 sid_compose(&membersid, &state->domainsid, memberrid);
927 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
928 if (!NT_STATUS_IS_OK(status)) {
930 return NT_STATUS_NO_SUCH_GROUP;
932 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
933 if (!NT_STATUS_IS_OK(status)) {
935 return NT_STATUS_NO_SUCH_USER;
940 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
941 "member", memberdn)) {
943 return NT_STATUS_NO_MEMORY;
946 rc = tldap_modify(state->ld, groupdn, 1, mods, NULL, NULL);
948 if (rc != TLDAP_SUCCESS) {
949 DEBUG(10, ("ldap_modify failed: %s\n",
950 tldap_errstr(debug_ctx(), state->ld, rc)));
951 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
952 return NT_STATUS_MEMBER_IN_GROUP;
954 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
955 return NT_STATUS_MEMBER_NOT_IN_GROUP;
957 return NT_STATUS_LDAP(rc);
963 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
965 uint32 group_rid, uint32 member_rid)
967 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
971 static NTSTATUS pdb_ads_del_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_create_alias(struct pdb_methods *m,
980 const char *name, uint32 *rid)
982 TALLOC_CTX *frame = talloc_stackframe();
983 struct pdb_ads_state *state = talloc_get_type_abort(
984 m->private_data, struct pdb_ads_state);
985 const char *attrs[1] = { "objectSid" };
987 struct tldap_mod *mods = NULL;
988 struct tldap_message **alias;
994 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
998 return NT_STATUS_NO_MEMORY;
1001 ok &= tldap_make_mod_fmt(
1002 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
1004 ok &= tldap_make_mod_fmt(
1005 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
1006 ok &= tldap_make_mod_fmt(
1007 NULL, talloc_tos(), &num_mods, &mods, "groupType",
1008 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1012 return NT_STATUS_NO_MEMORY;
1015 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
1016 if (rc != TLDAP_SUCCESS) {
1017 DEBUG(10, ("ldap_add failed %s\n",
1018 tldap_errstr(debug_ctx(), state->ld, rc)));
1020 return NT_STATUS_LDAP(rc);
1023 rc = tldap_search_fmt(
1024 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1025 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1026 "(&(objectclass=group)(samaccountname=%s))", name);
1027 if (rc != TLDAP_SUCCESS) {
1028 DEBUG(10, ("Could not find just created alias %s: %s\n",
1029 name, tldap_errstr(debug_ctx(), state->ld, rc)));
1031 return NT_STATUS_LDAP(rc);
1034 if (talloc_array_length(alias) != 1) {
1035 DEBUG(10, ("Got %d alias, expected one\n",
1036 (int)talloc_array_length(alias)));
1038 return NT_STATUS_LDAP(rc);
1041 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1042 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1045 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1048 sid_peek_rid(&sid, rid);
1050 return NT_STATUS_OK;
1053 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1056 struct pdb_ads_state *state = talloc_get_type_abort(
1057 m->private_data, struct pdb_ads_state);
1058 struct tldap_message **alias;
1062 sidstr = sid_binstring(talloc_tos(), sid);
1063 if (sidstr == NULL) {
1064 return NT_STATUS_NO_MEMORY;
1067 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1068 NULL, 0, 0, talloc_tos(), &alias,
1069 "(&(objectSid=%s)(objectclass=group)"
1070 "(|(grouptype=%d)(grouptype=%d)))",
1071 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1072 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1073 TALLOC_FREE(sidstr);
1074 if (rc != TLDAP_SUCCESS) {
1075 DEBUG(10, ("ldap_search failed: %s\n",
1076 tldap_errstr(debug_ctx(), state->ld, rc)));
1078 return NT_STATUS_LDAP(rc);
1080 if (talloc_array_length(alias) != 1) {
1081 DEBUG(10, ("Expected 1 alias, got %d\n",
1082 (int)talloc_array_length(alias)));
1083 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1085 if (!tldap_entry_dn(alias[0], &dn)) {
1086 DEBUG(10, ("Could not get DN for alias %s\n",
1087 sid_string_dbg(sid)));
1088 return NT_STATUS_INTERNAL_ERROR;
1091 rc = tldap_delete(state->ld, dn, NULL, NULL);
1092 if (rc != TLDAP_SUCCESS) {
1093 DEBUG(10, ("ldap_delete failed: %s\n",
1094 tldap_errstr(debug_ctx(), state->ld, rc)));
1096 return NT_STATUS_LDAP(rc);
1099 return NT_STATUS_OK;
1102 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
1104 struct acct_info *info)
1106 return NT_STATUS_NOT_IMPLEMENTED;
1109 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1111 struct acct_info *info)
1113 return NT_STATUS_NOT_IMPLEMENTED;
1116 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1117 const struct dom_sid *sid,
1118 TALLOC_CTX *mem_ctx, char **pdn)
1120 struct tldap_message **msg;
1124 sidstr = sid_binstring(talloc_tos(), sid);
1125 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1127 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1128 NULL, 0, 0, talloc_tos(), &msg,
1129 "(objectsid=%s)", sidstr);
1130 TALLOC_FREE(sidstr);
1131 if (rc != TLDAP_SUCCESS) {
1132 DEBUG(10, ("ldap_search failed %s\n",
1133 tldap_errstr(debug_ctx(), state->ld, rc)));
1134 return NT_STATUS_LDAP(rc);
1137 switch talloc_array_length(msg) {
1139 return NT_STATUS_NOT_FOUND;
1143 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1146 if (!tldap_entry_dn(msg[0], &dn)) {
1147 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1150 dn = talloc_strdup(mem_ctx, dn);
1152 return NT_STATUS_NO_MEMORY;
1157 return NT_STATUS_OK;
1160 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1161 const DOM_SID *alias,
1162 const DOM_SID *member,
1165 struct pdb_ads_state *state = talloc_get_type_abort(
1166 m->private_data, struct pdb_ads_state);
1167 TALLOC_CTX *frame = talloc_stackframe();
1168 struct tldap_mod *mods;
1170 char *aliasdn, *memberdn;
1173 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1174 if (!NT_STATUS_IS_OK(status)) {
1175 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1176 sid_string_dbg(alias), nt_errstr(status)));
1178 return NT_STATUS_NO_SUCH_ALIAS;
1180 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1181 if (!NT_STATUS_IS_OK(status)) {
1182 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1183 sid_string_dbg(member), nt_errstr(status)));
1190 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1191 "member", memberdn)) {
1193 return NT_STATUS_NO_MEMORY;
1196 rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
1198 if (rc != TLDAP_SUCCESS) {
1199 DEBUG(10, ("ldap_modify failed: %s\n",
1200 tldap_errstr(debug_ctx(), state->ld, rc)));
1201 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1202 return NT_STATUS_MEMBER_IN_ALIAS;
1204 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1205 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1207 return NT_STATUS_LDAP(rc);
1210 return NT_STATUS_OK;
1213 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1214 const DOM_SID *alias,
1215 const DOM_SID *member)
1217 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1220 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1221 const DOM_SID *alias,
1222 const DOM_SID *member)
1224 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1227 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1228 struct dom_sid *psid)
1230 const char *attrs[1] = { "objectSid" };
1231 struct tldap_message **msg;
1237 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1238 dnblob->data, dnblob->length, &dn, &len,
1242 rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1243 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1244 &msg, "(objectclass=*)");
1246 if (talloc_array_length(msg) != 1) {
1247 DEBUG(10, ("Got %d objects, expected one\n",
1248 (int)talloc_array_length(msg)));
1253 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1258 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1259 const DOM_SID *alias,
1260 TALLOC_CTX *mem_ctx,
1262 size_t *pnum_members)
1264 struct pdb_ads_state *state = talloc_get_type_abort(
1265 m->private_data, struct pdb_ads_state);
1266 const char *attrs[1] = { "member" };
1268 struct tldap_message **msg;
1269 int i, rc, num_members;
1271 struct dom_sid *members;
1273 sidstr = sid_binstring(talloc_tos(), alias);
1274 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1276 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1277 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1278 "(objectsid=%s)", sidstr);
1279 TALLOC_FREE(sidstr);
1280 if (rc != TLDAP_SUCCESS) {
1281 DEBUG(10, ("ldap_search failed %s\n",
1282 tldap_errstr(debug_ctx(), state->ld, rc)));
1283 return NT_STATUS_LDAP(rc);
1285 switch talloc_array_length(msg) {
1287 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1292 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1296 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1297 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1300 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1301 if (members == NULL) {
1302 return NT_STATUS_NO_MEMORY;
1305 for (i=0; i<num_members; i++) {
1306 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1307 TALLOC_FREE(members);
1308 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1312 *pmembers = members;
1313 *pnum_members = num_members;
1314 return NT_STATUS_OK;
1317 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1318 TALLOC_CTX *mem_ctx,
1319 const DOM_SID *domain_sid,
1320 const DOM_SID *members,
1322 uint32 **pp_alias_rids,
1323 size_t *p_num_alias_rids)
1325 return NT_STATUS_NOT_IMPLEMENTED;
1328 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1329 const DOM_SID *domain_sid,
1332 const char **pp_names,
1333 enum lsa_SidType *attrs)
1335 return NT_STATUS_NOT_IMPLEMENTED;
1338 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1339 const DOM_SID *domain_sid,
1341 const char **pp_names,
1343 enum lsa_SidType *attrs)
1345 return NT_STATUS_NOT_IMPLEMENTED;
1348 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1349 int policy_index, uint32 *value)
1351 return account_policy_get(policy_index, value)
1352 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1355 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1356 int policy_index, uint32 value)
1358 return account_policy_set(policy_index, value)
1359 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1362 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1365 return NT_STATUS_NOT_IMPLEMENTED;
1368 struct pdb_ads_search_state {
1369 uint32_t acct_flags;
1370 struct samr_displayentry *entries;
1371 uint32_t num_entries;
1376 static bool pdb_ads_next_entry(struct pdb_search *search,
1377 struct samr_displayentry *entry)
1379 struct pdb_ads_search_state *state = talloc_get_type_abort(
1380 search->private_data, struct pdb_ads_search_state);
1382 if (state->current == state->num_entries) {
1386 entry->idx = state->entries[state->current].idx;
1387 entry->rid = state->entries[state->current].rid;
1388 entry->acct_flags = state->entries[state->current].acct_flags;
1390 entry->account_name = talloc_strdup(
1391 search, state->entries[state->current].account_name);
1392 entry->fullname = talloc_strdup(
1393 search, state->entries[state->current].fullname);
1394 entry->description = talloc_strdup(
1395 search, state->entries[state->current].description);
1397 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1398 || (entry->description == NULL)) {
1399 DEBUG(0, ("talloc_strdup failed\n"));
1403 state->current += 1;
1407 static void pdb_ads_search_end(struct pdb_search *search)
1409 struct pdb_ads_search_state *state = talloc_get_type_abort(
1410 search->private_data, struct pdb_ads_search_state);
1414 static bool pdb_ads_search_filter(struct pdb_methods *m,
1415 struct pdb_search *search,
1417 struct pdb_ads_search_state **pstate)
1419 struct pdb_ads_state *state = talloc_get_type_abort(
1420 m->private_data, struct pdb_ads_state);
1421 struct pdb_ads_search_state *sstate;
1422 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1423 "userAccountControl", "description" };
1424 struct tldap_message **users;
1425 int i, rc, num_users;
1427 sstate = talloc_zero(search, struct pdb_ads_search_state);
1428 if (sstate == NULL) {
1432 rc = tldap_search_fmt(
1433 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1434 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1436 if (rc != TLDAP_SUCCESS) {
1437 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1438 tldap_errstr(debug_ctx(), state->ld, rc)));
1442 num_users = talloc_array_length(users);
1444 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1446 if (sstate->entries == NULL) {
1447 DEBUG(10, ("talloc failed\n"));
1451 sstate->num_entries = 0;
1453 for (i=0; i<num_users; i++) {
1454 struct samr_displayentry *e;
1457 e = &sstate->entries[sstate->num_entries];
1459 e->idx = sstate->num_entries;
1460 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1461 DEBUG(10, ("Could not pull sid\n"));
1464 sid_peek_rid(&sid, &e->rid);
1465 e->acct_flags = ACB_NORMAL;
1466 e->account_name = tldap_talloc_single_attribute(
1467 users[i], "samAccountName", sstate->entries);
1468 if (e->account_name == NULL) {
1471 e->fullname = tldap_talloc_single_attribute(
1472 users[i], "displayName", sstate->entries);
1473 if (e->fullname == NULL) {
1476 e->description = tldap_talloc_single_attribute(
1477 users[i], "description", sstate->entries);
1478 if (e->description == NULL) {
1479 e->description = "";
1482 sstate->num_entries += 1;
1483 if (sstate->num_entries >= num_users) {
1488 search->private_data = sstate;
1489 search->next_entry = pdb_ads_next_entry;
1490 search->search_end = pdb_ads_search_end;
1495 static bool pdb_ads_search_users(struct pdb_methods *m,
1496 struct pdb_search *search,
1499 struct pdb_ads_search_state *sstate;
1502 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1506 sstate->acct_flags = acct_flags;
1510 static bool pdb_ads_search_groups(struct pdb_methods *m,
1511 struct pdb_search *search)
1513 struct pdb_ads_search_state *sstate;
1517 filter = talloc_asprintf(talloc_tos(),
1518 "(&(grouptype=%d)(objectclass=group))",
1519 GTYPE_SECURITY_GLOBAL_GROUP);
1520 if (filter == NULL) {
1523 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1524 TALLOC_FREE(filter);
1528 sstate->acct_flags = 0;
1532 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1533 struct pdb_search *search,
1536 struct pdb_ads_search_state *sstate;
1540 filter = talloc_asprintf(
1541 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1542 sid_check_is_builtin(sid)
1543 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1544 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1546 if (filter == NULL) {
1549 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1550 TALLOC_FREE(filter);
1554 sstate->acct_flags = 0;
1558 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1564 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1567 struct pdb_ads_state *state = talloc_get_type_abort(
1568 m->private_data, struct pdb_ads_state);
1569 sid_compose(sid, &state->domainsid, uid);
1573 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1576 struct pdb_ads_state *state = talloc_get_type_abort(
1577 m->private_data, struct pdb_ads_state);
1578 sid_compose(sid, &state->domainsid, gid);
1582 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1583 union unid_t *id, enum lsa_SidType *type)
1585 struct pdb_ads_state *state = talloc_get_type_abort(
1586 m->private_data, struct pdb_ads_state);
1587 struct tldap_message **msg;
1593 * This is a big, big hack: Just hard-code the rid as uid/gid.
1596 sid_peek_rid(sid, &rid);
1598 sidstr = sid_binstring(talloc_tos(), sid);
1599 if (sidstr == NULL) {
1603 rc = tldap_search_fmt(
1604 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1605 NULL, 0, 0, talloc_tos(), &msg,
1606 "(&(objectsid=%s)(objectclass=user))", sidstr);
1607 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1609 *type = SID_NAME_USER;
1610 TALLOC_FREE(sidstr);
1614 rc = tldap_search_fmt(
1615 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1616 NULL, 0, 0, talloc_tos(), &msg,
1617 "(&(objectsid=%s)(objectclass=group))", sidstr);
1618 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1620 *type = SID_NAME_DOM_GRP;
1621 TALLOC_FREE(sidstr);
1625 TALLOC_FREE(sidstr);
1629 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1634 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1639 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1640 const char *domain, char** pwd,
1642 time_t *pass_last_set_time)
1647 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1648 const char* domain, const char* pwd,
1654 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1660 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1661 TALLOC_CTX *mem_ctx,
1662 uint32 *num_domains,
1663 struct trustdom_info ***domains)
1665 return NT_STATUS_NOT_IMPLEMENTED;
1668 static void pdb_ads_init_methods(struct pdb_methods *m)
1671 m->getsampwnam = pdb_ads_getsampwnam;
1672 m->getsampwsid = pdb_ads_getsampwsid;
1673 m->create_user = pdb_ads_create_user;
1674 m->delete_user = pdb_ads_delete_user;
1675 m->add_sam_account = pdb_ads_add_sam_account;
1676 m->update_sam_account = pdb_ads_update_sam_account;
1677 m->delete_sam_account = pdb_ads_delete_sam_account;
1678 m->rename_sam_account = pdb_ads_rename_sam_account;
1679 m->update_login_attempts = pdb_ads_update_login_attempts;
1680 m->getgrsid = pdb_ads_getgrsid;
1681 m->getgrgid = pdb_ads_getgrgid;
1682 m->getgrnam = pdb_ads_getgrnam;
1683 m->create_dom_group = pdb_ads_create_dom_group;
1684 m->delete_dom_group = pdb_ads_delete_dom_group;
1685 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1686 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1687 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1688 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1689 m->enum_group_members = pdb_ads_enum_group_members;
1690 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1691 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1692 m->add_groupmem = pdb_ads_add_groupmem;
1693 m->del_groupmem = pdb_ads_del_groupmem;
1694 m->create_alias = pdb_ads_create_alias;
1695 m->delete_alias = pdb_ads_delete_alias;
1696 m->get_aliasinfo = pdb_ads_get_aliasinfo;
1697 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1698 m->add_aliasmem = pdb_ads_add_aliasmem;
1699 m->del_aliasmem = pdb_ads_del_aliasmem;
1700 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1701 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1702 m->lookup_rids = pdb_ads_lookup_rids;
1703 m->lookup_names = pdb_ads_lookup_names;
1704 m->get_account_policy = pdb_ads_get_account_policy;
1705 m->set_account_policy = pdb_ads_set_account_policy;
1706 m->get_seq_num = pdb_ads_get_seq_num;
1707 m->search_users = pdb_ads_search_users;
1708 m->search_groups = pdb_ads_search_groups;
1709 m->search_aliases = pdb_ads_search_aliases;
1710 m->uid_to_rid = pdb_ads_uid_to_rid;
1711 m->uid_to_sid = pdb_ads_uid_to_sid;
1712 m->gid_to_sid = pdb_ads_gid_to_sid;
1713 m->sid_to_id = pdb_ads_sid_to_id;
1714 m->rid_algorithm = pdb_ads_rid_algorithm;
1715 m->new_rid = pdb_ads_new_rid;
1716 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1717 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1718 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1719 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1722 static void free_private_data(void **vp)
1724 struct pdb_ads_state *state = talloc_get_type_abort(
1725 *vp, struct pdb_ads_state);
1727 TALLOC_FREE(state->ld);
1731 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1732 const char *location)
1734 const char *rootdse_attrs[2] = {
1735 "defaultNamingContext", "configurationNamingContext" };
1736 const char *domain_attrs[1] = { "objectSid" };
1737 const char *ncname_attrs[1] = { "netbiosname" };
1738 struct tldap_message **rootdse, **domain, **ncname;
1739 TALLOC_CTX *frame = talloc_stackframe();
1740 struct sockaddr_un sunaddr;
1745 ZERO_STRUCT(sunaddr);
1746 sunaddr.sun_family = AF_UNIX;
1747 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1749 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1751 if (!NT_STATUS_IS_OK(status)) {
1752 DEBUG(10, ("Could not connect to %s: %s\n", location,
1753 nt_errstr(status)));
1757 state->ld = tldap_context_create(state, fd);
1758 if (state->ld == NULL) {
1760 status = NT_STATUS_NO_MEMORY;
1764 rc = tldap_search_fmt(
1765 state->ld, "", TLDAP_SCOPE_BASE,
1766 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1767 talloc_tos(), &rootdse, "(objectclass=*)");
1768 if (rc != TLDAP_SUCCESS) {
1769 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1770 tldap_errstr(debug_ctx(), state->ld, rc)));
1771 status = NT_STATUS_LDAP(rc);
1774 if (talloc_array_length(rootdse) != 1) {
1775 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1779 state->domaindn = tldap_talloc_single_attribute(
1780 rootdse[0], "defaultNamingContext", state);
1781 if (state->domaindn == NULL) {
1782 DEBUG(10, ("Could not get defaultNamingContext\n"));
1783 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1786 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1788 state->configdn = tldap_talloc_single_attribute(
1789 rootdse[0], "configurationNamingContext", state);
1790 if (state->domaindn == NULL) {
1791 DEBUG(10, ("Could not get configurationNamingContext\n"));
1792 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1795 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1798 * Figure out our domain's SID
1800 rc = tldap_search_fmt(
1801 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1802 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1803 talloc_tos(), &domain, "(objectclass=*)");
1804 if (rc != TLDAP_SUCCESS) {
1805 DEBUG(10, ("Could not retrieve domain: %s\n",
1806 tldap_errstr(debug_ctx(), state->ld, rc)));
1807 status = NT_STATUS_LDAP(rc);
1811 num_domains = talloc_array_length(domain);
1812 if (num_domains != 1) {
1813 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1814 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1817 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1818 DEBUG(10, ("Could not retrieve domain SID\n"));
1819 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1822 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1825 * Figure out our domain's short name
1827 rc = tldap_search_fmt(
1828 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1829 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1830 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1831 if (rc != TLDAP_SUCCESS) {
1832 DEBUG(10, ("Could not retrieve ncname: %s\n",
1833 tldap_errstr(debug_ctx(), state->ld, rc)));
1834 status = NT_STATUS_LDAP(rc);
1837 if (talloc_array_length(ncname) != 1) {
1838 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1842 state->netbiosname = tldap_talloc_single_attribute(
1843 ncname[0], "netbiosname", state);
1844 if (state->netbiosname == NULL) {
1845 DEBUG(10, ("Could not get netbiosname\n"));
1846 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1849 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1851 if (!strequal(lp_workgroup(), state->netbiosname)) {
1852 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1853 state->netbiosname, lp_workgroup()));
1854 status = NT_STATUS_NO_SUCH_DOMAIN;
1858 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1860 status = NT_STATUS_OK;
1866 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1867 const char *location)
1869 struct pdb_methods *m;
1870 struct pdb_ads_state *state;
1874 m = talloc(talloc_autofree_context(), struct pdb_methods);
1876 return NT_STATUS_NO_MEMORY;
1878 state = talloc(m, struct pdb_ads_state);
1879 if (state == NULL) {
1882 m->private_data = state;
1883 m->free_private_data = free_private_data;
1884 pdb_ads_init_methods(m);
1886 if (location == NULL) {
1887 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1891 if (location == NULL) {
1895 status = pdb_ads_connect(state, location);
1896 if (!NT_STATUS_IS_OK(status)) {
1897 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1902 return NT_STATUS_OK;
1904 status = NT_STATUS_NO_MEMORY;
1910 NTSTATUS pdb_ads_init(void);
1911 NTSTATUS pdb_ads_init(void)
1913 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",