2 Unix SMB/CIFS implementation.
3 pdb_ldap with ads schema
4 Copyright (C) Volker Lendecke 2009
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 struct pdb_ads_state {
23 struct tldap_context *ld;
24 struct dom_sid domainsid;
30 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
31 struct samu *sam_acct,
33 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
35 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
36 struct dom_sid *psid);
37 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
38 const struct dom_sid *sid,
39 TALLOC_CTX *mem_ctx, char **pdn);
41 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
46 if (!tldap_pull_uint64(msg, attr, &tmp)) {
49 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
53 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
56 sid_peek_rid(sid, &rid);
60 struct pdb_ads_samu_private {
62 struct tldap_message *ldapmsg;
65 static struct samu *pdb_ads_init_guest(TALLOC_CTX *mem_ctx,
66 struct pdb_methods *m)
68 struct pdb_ads_state *state = talloc_get_type_abort(
69 m->private_data, struct pdb_ads_state);
70 struct dom_sid guest_sid;
74 sid_compose(&guest_sid, &state->domainsid, DOMAIN_USER_RID_GUEST);
76 guest = samu_new(mem_ctx);
81 status = pdb_ads_getsampwsid(m, guest, &guest_sid);
82 if (!NT_STATUS_IS_OK(status)) {
83 DEBUG(10, ("Could not init guest account: %s\n",
91 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
92 struct pdb_methods *m, struct samu *sam)
94 struct pdb_ads_samu_private *result;
97 result = (struct pdb_ads_samu_private *)
98 pdb_get_backend_private_data(sam, m);
100 if (result != NULL) {
101 return talloc_get_type_abort(
102 result, struct pdb_ads_samu_private);
106 * This is now a weirdness of the passdb API. For the guest user we
107 * are not asked first.
109 sid_peek_rid(pdb_get_user_sid(sam), &rid);
111 if (rid == DOMAIN_USER_RID_GUEST) {
112 struct samu *guest = pdb_ads_init_guest(talloc_tos(), m);
117 result = talloc_get_type_abort(
118 pdb_get_backend_private_data(guest, m),
119 struct pdb_ads_samu_private);
120 pdb_set_backend_private_data(
121 sam, talloc_move(sam, &result), NULL, m, PDB_SET);
123 return talloc_get_type_abort(
124 pdb_get_backend_private_data(sam, m),
125 struct pdb_ads_samu_private);
131 static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m,
133 struct tldap_message *entry)
135 struct pdb_ads_state *state = talloc_get_type_abort(
136 m->private_data, struct pdb_ads_state);
137 TALLOC_CTX *frame = talloc_stackframe();
138 struct pdb_ads_samu_private *priv;
139 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
146 priv = talloc(sam, struct pdb_ads_samu_private);
148 return NT_STATUS_NO_MEMORY;
150 if (!tldap_entry_dn(entry, &priv->dn)) {
152 return NT_STATUS_INTERNAL_DB_CORRUPTION;
155 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
157 DEBUG(10, ("no samAccountName\n"));
160 pdb_set_username(sam, str, PDB_SET);
162 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
163 pdb_set_logon_time(sam, tmp_time, PDB_SET);
165 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
166 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
168 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
169 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
171 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
172 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
175 str = tldap_talloc_single_attribute(entry, "displayName",
178 pdb_set_fullname(sam, str, PDB_SET);
181 str = tldap_talloc_single_attribute(entry, "homeDirectory",
184 pdb_set_homedir(sam, str, PDB_SET);
187 str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
189 pdb_set_dir_drive(sam, str, PDB_SET);
192 str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
194 pdb_set_logon_script(sam, str, PDB_SET);
197 str = tldap_talloc_single_attribute(entry, "profilePath",
200 pdb_set_profile_path(sam, str, PDB_SET);
203 str = tldap_talloc_single_attribute(entry, "profilePath",
206 pdb_set_profile_path(sam, str, PDB_SET);
209 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
210 DEBUG(10, ("Could not pull SID\n"));
213 pdb_set_user_sid(sam, &sid, PDB_SET);
215 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
216 DEBUG(10, ("Could not pull userAccountControl\n"));
219 pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET);
221 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
222 if (blob.length != NT_HASH_LEN) {
223 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
224 (int)blob.length, NT_HASH_LEN));
227 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
230 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
231 if (blob.length != LM_HASH_LEN) {
232 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
233 (int)blob.length, LM_HASH_LEN));
236 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
239 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
240 sid_compose(&sid, &state->domainsid, n);
241 pdb_set_group_sid(sam, &sid, PDB_SET);
245 priv->ldapmsg = talloc_move(priv, &entry);
246 pdb_set_backend_private_data(sam, priv, NULL, m, PDB_SET);
248 status = NT_STATUS_OK;
254 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
255 struct tldap_message *existing,
257 int *pnum_mods, struct tldap_mod **pmods,
263 /* TODO: All fields :-) */
265 ret &= tldap_make_mod_fmt(
266 existing, mem_ctx, pnum_mods, pmods, "displayName",
267 "%s", pdb_get_fullname(sam));
269 blob = data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN);
270 if (blob.data != NULL) {
271 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
272 "unicodePwd", 1, &blob);
275 blob = data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN);
276 if (blob.data != NULL) {
277 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
278 "dBCSPwd", 1, &blob);
281 ret &= tldap_make_mod_fmt(
282 existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
283 "%d", ads_acb2uf(pdb_get_acct_ctrl(sam)));
285 ret &= tldap_make_mod_fmt(
286 existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
287 "%s", pdb_get_homedir(sam));
289 ret &= tldap_make_mod_fmt(
290 existing, mem_ctx, pnum_mods, pmods, "homeDrive",
291 "%s", pdb_get_dir_drive(sam));
293 ret &= tldap_make_mod_fmt(
294 existing, mem_ctx, pnum_mods, pmods, "scriptPath",
295 "%s", pdb_get_logon_script(sam));
297 ret &= tldap_make_mod_fmt(
298 existing, mem_ctx, pnum_mods, pmods, "profilePath",
299 "%s", pdb_get_profile_path(sam));
304 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
305 struct pdb_ads_state *state,
306 struct samu *sam_acct,
309 const char * attrs[] = {
310 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
311 "sAMAccountName", "displayName", "homeDirectory",
312 "homeDrive", "scriptPath", "profilePath", "description",
313 "userWorkstations", "comment", "userParameters", "objectSid",
314 "primaryGroupID", "userAccountControl", "logonHours",
315 "badPwdCount", "logonCount", "countryCode", "codePage",
316 "unicodePwd", "dBCSPwd" };
317 struct tldap_message **users;
320 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
321 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
322 &users, "%s", filter);
323 if (rc != TLDAP_SUCCESS) {
324 DEBUG(10, ("ldap_search failed %s\n",
325 tldap_errstr(debug_ctx(), state->ld, rc)));
326 return NT_STATUS_LDAP(rc);
329 count = talloc_array_length(users);
331 DEBUG(10, ("Expected 1 user, got %d\n", count));
332 return NT_STATUS_INTERNAL_DB_CORRUPTION;
335 return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]);
338 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
339 struct samu *sam_acct,
340 const char *username)
342 struct pdb_ads_state *state = talloc_get_type_abort(
343 m->private_data, struct pdb_ads_state);
346 filter = talloc_asprintf(
347 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
349 NT_STATUS_HAVE_NO_MEMORY(filter);
351 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
354 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
355 struct samu *sam_acct,
358 struct pdb_ads_state *state = talloc_get_type_abort(
359 m->private_data, struct pdb_ads_state);
360 char *sidstr, *filter;
362 sidstr = sid_binstring(talloc_tos(), sid);
363 NT_STATUS_HAVE_NO_MEMORY(sidstr);
365 filter = talloc_asprintf(
366 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
368 NT_STATUS_HAVE_NO_MEMORY(filter);
370 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
373 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
375 const char *name, uint32 acct_flags,
378 struct pdb_ads_state *state = talloc_get_type_abort(
379 m->private_data, struct pdb_ads_state);
380 const char *attrs[1] = { "objectSid" };
381 struct tldap_mod *mods = NULL;
383 struct tldap_message **user;
389 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
392 return NT_STATUS_NO_MEMORY;
395 /* TODO: Create machines etc */
398 ok &= tldap_make_mod_fmt(
399 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
400 ok &= tldap_make_mod_fmt(
401 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
404 return NT_STATUS_NO_MEMORY;
407 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, 0, NULL, 0);
408 if (rc != TLDAP_SUCCESS) {
409 DEBUG(10, ("ldap_add failed %s\n",
410 tldap_errstr(debug_ctx(), state->ld, rc)));
412 return NT_STATUS_LDAP(rc);
415 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
416 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &user,
417 "(&(objectclass=user)(samaccountname=%s))",
419 if (rc != TLDAP_SUCCESS) {
420 DEBUG(10, ("Could not find just created user %s: %s\n",
421 name, tldap_errstr(debug_ctx(), state->ld, rc)));
423 return NT_STATUS_LDAP(rc);
426 if (talloc_array_length(user) != 1) {
427 DEBUG(10, ("Got %d users, expected one\n",
428 (int)talloc_array_length(user)));
430 return NT_STATUS_LDAP(rc);
433 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
434 DEBUG(10, ("Could not fetch objectSid from user %s\n",
437 return NT_STATUS_INTERNAL_DB_CORRUPTION;
440 sid_peek_rid(&sid, rid);
445 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
449 struct pdb_ads_state *state = talloc_get_type_abort(
450 m->private_data, struct pdb_ads_state);
455 status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
457 if (!NT_STATUS_IS_OK(status)) {
461 rc = tldap_delete(state->ld, dn, NULL, 0, NULL, 0);
463 if (rc != TLDAP_SUCCESS) {
464 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
465 tldap_errstr(debug_ctx(), state->ld, rc)));
466 return NT_STATUS_LDAP(rc);
471 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
472 struct samu *sampass)
474 return NT_STATUS_NOT_IMPLEMENTED;
477 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
480 struct pdb_ads_state *state = talloc_get_type_abort(
481 m->private_data, struct pdb_ads_state);
482 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
483 struct tldap_mod *mods = NULL;
484 int rc, num_mods = 0;
486 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
487 &num_mods, &mods, sam)) {
488 return NT_STATUS_NO_MEMORY;
492 /* Nothing to do, just return success */
496 rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, 0,
498 if (rc != TLDAP_SUCCESS) {
499 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
500 tldap_errstr(debug_ctx(), state->ld, rc)));
501 return NT_STATUS_LDAP(rc);
509 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
510 struct samu *username)
512 return NT_STATUS_NOT_IMPLEMENTED;
515 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
516 struct samu *oldname,
519 return NT_STATUS_NOT_IMPLEMENTED;
522 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
523 struct samu *sam_acct,
526 return NT_STATUS_NOT_IMPLEMENTED;
529 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
532 struct pdb_ads_state *state = talloc_get_type_abort(
533 m->private_data, struct pdb_ads_state);
534 const char *attrs[4] = { "objectSid", "description", "samAccountName",
537 struct tldap_message **group;
541 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
542 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
543 &group, "%s", filter);
544 if (rc != TLDAP_SUCCESS) {
545 DEBUG(10, ("ldap_search failed %s\n",
546 tldap_errstr(debug_ctx(), state->ld, rc)));
547 return NT_STATUS_LDAP(rc);
549 if (talloc_array_length(group) != 1) {
550 DEBUG(10, ("Expected 1 user, got %d\n",
551 (int)talloc_array_length(group)));
552 return NT_STATUS_INTERNAL_DB_CORRUPTION;
555 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
556 return NT_STATUS_INTERNAL_DB_CORRUPTION;
558 map->gid = pdb_ads_sid2gid(&map->sid);
560 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
561 return NT_STATUS_INTERNAL_DB_CORRUPTION;
564 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
565 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
566 map->sid_name_use = SID_NAME_ALIAS;
568 case GTYPE_SECURITY_GLOBAL_GROUP:
569 map->sid_name_use = SID_NAME_DOM_GRP;
572 return NT_STATUS_INTERNAL_DB_CORRUPTION;
575 str = tldap_talloc_single_attribute(group[0], "samAccountName",
578 return NT_STATUS_INTERNAL_DB_CORRUPTION;
580 fstrcpy(map->nt_name, str);
583 str = tldap_talloc_single_attribute(group[0], "description",
586 fstrcpy(map->comment, str);
589 map->comment[0] = '\0';
596 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
602 filter = talloc_asprintf(talloc_tos(),
603 "(&(objectsid=%s)(objectclass=group))",
604 sid_string_talloc(talloc_tos(), &sid));
605 if (filter == NULL) {
606 return NT_STATUS_NO_MEMORY;
609 status = pdb_ads_getgrfilter(m, map, filter);
614 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
618 pdb_ads_gid_to_sid(m, gid, &sid);
619 return pdb_ads_getgrsid(m, map, sid);
622 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
628 filter = talloc_asprintf(talloc_tos(),
629 "(&(samaccountname=%s)(objectclass=group))",
631 if (filter == NULL) {
632 return NT_STATUS_NO_MEMORY;
635 status = pdb_ads_getgrfilter(m, map, filter);
640 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
641 TALLOC_CTX *mem_ctx, const char *name,
644 TALLOC_CTX *frame = talloc_stackframe();
645 struct pdb_ads_state *state = talloc_get_type_abort(
646 m->private_data, struct pdb_ads_state);
647 const char *attrs[1] = { "objectSid" };
649 struct tldap_mod *mods = NULL;
650 struct tldap_message **alias;
656 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
660 return NT_STATUS_NO_MEMORY;
663 ok &= tldap_make_mod_fmt(
664 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
666 ok &= tldap_make_mod_fmt(
667 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
668 ok &= tldap_make_mod_fmt(
669 NULL, talloc_tos(), &num_mods, &mods, "groupType",
670 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
674 return NT_STATUS_NO_MEMORY;
677 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, 0, NULL, 0);
678 if (rc != TLDAP_SUCCESS) {
679 DEBUG(10, ("ldap_add failed %s\n",
680 tldap_errstr(debug_ctx(), state->ld, rc)));
682 return NT_STATUS_LDAP(rc);
685 rc = tldap_search_fmt(
686 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
687 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
688 "(&(objectclass=group)(samaccountname=%s))", name);
689 if (rc != TLDAP_SUCCESS) {
690 DEBUG(10, ("Could not find just created alias %s: %s\n",
691 name, tldap_errstr(debug_ctx(), state->ld, rc)));
693 return NT_STATUS_LDAP(rc);
696 if (talloc_array_length(alias) != 1) {
697 DEBUG(10, ("Got %d alias, expected one\n",
698 (int)talloc_array_length(alias)));
700 return NT_STATUS_LDAP(rc);
703 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
704 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
707 return NT_STATUS_INTERNAL_DB_CORRUPTION;
710 sid_peek_rid(&sid, rid);
715 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
716 TALLOC_CTX *mem_ctx, uint32 rid)
718 struct pdb_ads_state *state = talloc_get_type_abort(
719 m->private_data, struct pdb_ads_state);
722 struct tldap_message **msg;
726 sid_compose(&sid, &state->domainsid, rid);
728 sidstr = sid_binstring(talloc_tos(), &sid);
729 NT_STATUS_HAVE_NO_MEMORY(sidstr);
731 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
732 NULL, 0, 0, talloc_tos(), &msg,
733 ("(&(objectSid=%s)(objectClass=group))"),
736 if (rc != TLDAP_SUCCESS) {
737 DEBUG(10, ("ldap_search failed %s\n",
738 tldap_errstr(debug_ctx(), state->ld, rc)));
739 return NT_STATUS_LDAP(rc);
742 switch talloc_array_length(msg) {
744 return NT_STATUS_NO_SUCH_GROUP;
748 return NT_STATUS_INTERNAL_DB_CORRUPTION;
751 if (!tldap_entry_dn(msg[0], &dn)) {
752 return NT_STATUS_INTERNAL_DB_CORRUPTION;
755 rc = tldap_delete(state->ld, dn, NULL, 0, NULL, 0);
756 if (rc != TLDAP_SUCCESS) {
757 DEBUG(10, ("ldap_delete failed: %s\n",
758 tldap_errstr(debug_ctx(), state->ld, rc)));
760 return NT_STATUS_LDAP(rc);
767 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
770 return NT_STATUS_NOT_IMPLEMENTED;
773 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
776 return NT_STATUS_NOT_IMPLEMENTED;
779 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
782 return NT_STATUS_NOT_IMPLEMENTED;
785 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
787 enum lsa_SidType sid_name_use,
789 size_t *p_num_entries,
792 return NT_STATUS_NOT_IMPLEMENTED;
795 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
797 const DOM_SID *group,
799 size_t *pnum_members)
801 struct pdb_ads_state *state = talloc_get_type_abort(
802 m->private_data, struct pdb_ads_state);
803 const char *attrs[1] = { "member" };
805 struct tldap_message **msg;
806 int i, rc, num_members;
810 sidstr = sid_binstring(talloc_tos(), group);
811 NT_STATUS_HAVE_NO_MEMORY(sidstr);
813 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
814 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
815 "(objectsid=%s)", sidstr);
817 if (rc != TLDAP_SUCCESS) {
818 DEBUG(10, ("ldap_search failed %s\n",
819 tldap_errstr(debug_ctx(), state->ld, rc)));
820 return NT_STATUS_LDAP(rc);
822 switch talloc_array_length(msg) {
824 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
829 return NT_STATUS_INTERNAL_DB_CORRUPTION;
833 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
834 return NT_STATUS_INTERNAL_DB_CORRUPTION;
837 members = talloc_array(mem_ctx, uint32_t, num_members);
838 if (members == NULL) {
839 return NT_STATUS_NO_MEMORY;
842 for (i=0; i<num_members; i++) {
844 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &sid)
845 || !sid_peek_rid(&sid, &members[i])) {
846 TALLOC_FREE(members);
847 return NT_STATUS_INTERNAL_DB_CORRUPTION;
852 *pnum_members = num_members;
856 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
861 size_t *p_num_groups)
863 struct pdb_ads_state *state = talloc_get_type_abort(
864 m->private_data, struct pdb_ads_state);
865 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
867 const char *attrs[1] = { "objectSid" };
868 struct tldap_message **groups;
871 struct dom_sid *group_sids;
874 rc = tldap_search_fmt(
875 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
876 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
877 "(&(member=%s)(grouptype=%d)(objectclass=group))",
878 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
879 if (rc != TLDAP_SUCCESS) {
880 DEBUG(10, ("ldap_search failed %s\n",
881 tldap_errstr(debug_ctx(), state->ld, rc)));
882 return NT_STATUS_LDAP(rc);
885 count = talloc_array_length(groups);
887 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
888 if (group_sids == NULL) {
889 return NT_STATUS_NO_MEMORY;
891 gids = talloc_array(mem_ctx, gid_t, count);
893 TALLOC_FREE(group_sids);
894 return NT_STATUS_NO_MEMORY;
898 for (i=0; i<count; i++) {
899 if (!tldap_pull_binsid(groups[i], "objectSid",
900 &group_sids[num_groups])) {
903 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
906 if (num_groups == count) {
911 *pp_sids = group_sids;
913 *p_num_groups = num_groups;
917 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
921 return NT_STATUS_NOT_IMPLEMENTED;
924 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
926 uint32 grouprid, uint32 memberrid,
929 struct pdb_ads_state *state = talloc_get_type_abort(
930 m->private_data, struct pdb_ads_state);
931 TALLOC_CTX *frame = talloc_stackframe();
932 struct dom_sid groupsid, membersid;
933 char *groupdn, *memberdn;
934 struct tldap_mod *mods;
938 sid_compose(&groupsid, &state->domainsid, grouprid);
939 sid_compose(&membersid, &state->domainsid, memberrid);
941 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
942 if (!NT_STATUS_IS_OK(status)) {
944 return NT_STATUS_NO_SUCH_GROUP;
946 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
947 if (!NT_STATUS_IS_OK(status)) {
949 return NT_STATUS_NO_SUCH_USER;
954 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
955 "member", memberdn)) {
957 return NT_STATUS_NO_MEMORY;
960 rc = tldap_modify(state->ld, groupdn, 1, mods, NULL, 0, NULL, 0);
962 if (rc != TLDAP_SUCCESS) {
963 DEBUG(10, ("ldap_modify failed: %s\n",
964 tldap_errstr(debug_ctx(), state->ld, rc)));
965 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
966 return NT_STATUS_MEMBER_IN_GROUP;
968 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
969 return NT_STATUS_MEMBER_NOT_IN_GROUP;
971 return NT_STATUS_LDAP(rc);
977 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
979 uint32 group_rid, uint32 member_rid)
981 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
985 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
987 uint32 group_rid, uint32 member_rid)
989 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
993 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
994 const char *name, uint32 *rid)
996 TALLOC_CTX *frame = talloc_stackframe();
997 struct pdb_ads_state *state = talloc_get_type_abort(
998 m->private_data, struct pdb_ads_state);
999 const char *attrs[1] = { "objectSid" };
1001 struct tldap_mod *mods = NULL;
1002 struct tldap_message **alias;
1008 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1012 return NT_STATUS_NO_MEMORY;
1015 ok &= tldap_make_mod_fmt(
1016 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
1018 ok &= tldap_make_mod_fmt(
1019 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
1020 ok &= tldap_make_mod_fmt(
1021 NULL, talloc_tos(), &num_mods, &mods, "groupType",
1022 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1026 return NT_STATUS_NO_MEMORY;
1029 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1030 if (rc != TLDAP_SUCCESS) {
1031 DEBUG(10, ("ldap_add failed %s\n",
1032 tldap_errstr(debug_ctx(), state->ld, rc)));
1034 return NT_STATUS_LDAP(rc);
1037 rc = tldap_search_fmt(
1038 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1039 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1040 "(&(objectclass=group)(samaccountname=%s))", name);
1041 if (rc != TLDAP_SUCCESS) {
1042 DEBUG(10, ("Could not find just created alias %s: %s\n",
1043 name, tldap_errstr(debug_ctx(), state->ld, rc)));
1045 return NT_STATUS_LDAP(rc);
1048 if (talloc_array_length(alias) != 1) {
1049 DEBUG(10, ("Got %d alias, expected one\n",
1050 (int)talloc_array_length(alias)));
1052 return NT_STATUS_LDAP(rc);
1055 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1056 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1059 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1062 sid_peek_rid(&sid, rid);
1064 return NT_STATUS_OK;
1067 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1070 struct pdb_ads_state *state = talloc_get_type_abort(
1071 m->private_data, struct pdb_ads_state);
1072 struct tldap_message **alias;
1076 sidstr = sid_binstring(talloc_tos(), sid);
1077 if (sidstr == NULL) {
1078 return NT_STATUS_NO_MEMORY;
1081 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1082 NULL, 0, 0, talloc_tos(), &alias,
1083 "(&(objectSid=%s)(objectclass=group)"
1084 "(|(grouptype=%d)(grouptype=%d)))",
1085 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1086 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1087 TALLOC_FREE(sidstr);
1088 if (rc != TLDAP_SUCCESS) {
1089 DEBUG(10, ("ldap_search failed: %s\n",
1090 tldap_errstr(debug_ctx(), state->ld, rc)));
1092 return NT_STATUS_LDAP(rc);
1094 if (talloc_array_length(alias) != 1) {
1095 DEBUG(10, ("Expected 1 alias, got %d\n",
1096 (int)talloc_array_length(alias)));
1097 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1099 if (!tldap_entry_dn(alias[0], &dn)) {
1100 DEBUG(10, ("Could not get DN for alias %s\n",
1101 sid_string_dbg(sid)));
1102 return NT_STATUS_INTERNAL_ERROR;
1105 rc = tldap_delete(state->ld, dn, NULL, 0, NULL, 0);
1106 if (rc != TLDAP_SUCCESS) {
1107 DEBUG(10, ("ldap_delete failed: %s\n",
1108 tldap_errstr(debug_ctx(), state->ld, rc)));
1110 return NT_STATUS_LDAP(rc);
1113 return NT_STATUS_OK;
1116 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1118 struct acct_info *info)
1120 struct pdb_ads_state *state = talloc_get_type_abort(
1121 m->private_data, struct pdb_ads_state);
1122 const char *attrs[3] = { "objectSid", "description",
1124 struct tldap_message **msg;
1127 struct tldap_mod *mods;
1131 sidstr = sid_binstring(talloc_tos(), sid);
1132 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1134 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1135 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1136 &msg, "(&(objectSid=%s)(objectclass=group)"
1137 "(|(grouptype=%d)(grouptype=%d)))",
1138 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1139 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1140 TALLOC_FREE(sidstr);
1141 if (rc != TLDAP_SUCCESS) {
1142 DEBUG(10, ("ldap_search failed %s\n",
1143 tldap_errstr(debug_ctx(), state->ld, rc)));
1144 return NT_STATUS_LDAP(rc);
1146 switch talloc_array_length(msg) {
1148 return NT_STATUS_NO_SUCH_ALIAS;
1152 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1155 if (!tldap_entry_dn(msg[0], &dn)) {
1157 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1164 ok &= tldap_make_mod_fmt(
1165 msg[0], msg, &num_mods, &mods, "description",
1166 "%s", info->acct_desc);
1167 ok &= tldap_make_mod_fmt(
1168 msg[0], msg, &num_mods, &mods, "samAccountName",
1169 "%s", info->acct_name);
1172 return NT_STATUS_NO_MEMORY;
1174 if (num_mods == 0) {
1177 return NT_STATUS_OK;
1180 rc = tldap_modify(state->ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1182 if (rc != TLDAP_SUCCESS) {
1183 DEBUG(10, ("ldap_modify failed: %s\n",
1184 tldap_errstr(debug_ctx(), state->ld, rc)));
1185 return NT_STATUS_LDAP(rc);
1187 return NT_STATUS_OK;
1190 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1191 const struct dom_sid *sid,
1192 TALLOC_CTX *mem_ctx, char **pdn)
1194 struct tldap_message **msg;
1198 sidstr = sid_binstring(talloc_tos(), sid);
1199 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1201 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1202 NULL, 0, 0, talloc_tos(), &msg,
1203 "(objectsid=%s)", sidstr);
1204 TALLOC_FREE(sidstr);
1205 if (rc != TLDAP_SUCCESS) {
1206 DEBUG(10, ("ldap_search failed %s\n",
1207 tldap_errstr(debug_ctx(), state->ld, rc)));
1208 return NT_STATUS_LDAP(rc);
1211 switch talloc_array_length(msg) {
1213 return NT_STATUS_NOT_FOUND;
1217 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1220 if (!tldap_entry_dn(msg[0], &dn)) {
1221 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1224 dn = talloc_strdup(mem_ctx, dn);
1226 return NT_STATUS_NO_MEMORY;
1231 return NT_STATUS_OK;
1234 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1235 const DOM_SID *alias,
1236 const DOM_SID *member,
1239 struct pdb_ads_state *state = talloc_get_type_abort(
1240 m->private_data, struct pdb_ads_state);
1241 TALLOC_CTX *frame = talloc_stackframe();
1242 struct tldap_mod *mods;
1244 char *aliasdn, *memberdn;
1247 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1248 if (!NT_STATUS_IS_OK(status)) {
1249 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1250 sid_string_dbg(alias), nt_errstr(status)));
1252 return NT_STATUS_NO_SUCH_ALIAS;
1254 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1255 if (!NT_STATUS_IS_OK(status)) {
1256 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1257 sid_string_dbg(member), nt_errstr(status)));
1264 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1265 "member", memberdn)) {
1267 return NT_STATUS_NO_MEMORY;
1270 rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, 0, NULL, 0);
1272 if (rc != TLDAP_SUCCESS) {
1273 DEBUG(10, ("ldap_modify failed: %s\n",
1274 tldap_errstr(debug_ctx(), state->ld, rc)));
1275 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1276 return NT_STATUS_MEMBER_IN_ALIAS;
1278 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1279 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1281 return NT_STATUS_LDAP(rc);
1284 return NT_STATUS_OK;
1287 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1288 const DOM_SID *alias,
1289 const DOM_SID *member)
1291 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1294 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1295 const DOM_SID *alias,
1296 const DOM_SID *member)
1298 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1301 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1302 struct dom_sid *psid)
1304 const char *attrs[1] = { "objectSid" };
1305 struct tldap_message **msg;
1311 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1312 dnblob->data, dnblob->length, &dn, &len,
1316 rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1317 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1318 &msg, "(objectclass=*)");
1320 if (talloc_array_length(msg) != 1) {
1321 DEBUG(10, ("Got %d objects, expected one\n",
1322 (int)talloc_array_length(msg)));
1327 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1332 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1333 const DOM_SID *alias,
1334 TALLOC_CTX *mem_ctx,
1336 size_t *pnum_members)
1338 struct pdb_ads_state *state = talloc_get_type_abort(
1339 m->private_data, struct pdb_ads_state);
1340 const char *attrs[1] = { "member" };
1342 struct tldap_message **msg;
1343 int i, rc, num_members;
1345 struct dom_sid *members;
1347 sidstr = sid_binstring(talloc_tos(), alias);
1348 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1350 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1351 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1352 "(objectsid=%s)", sidstr);
1353 TALLOC_FREE(sidstr);
1354 if (rc != TLDAP_SUCCESS) {
1355 DEBUG(10, ("ldap_search failed %s\n",
1356 tldap_errstr(debug_ctx(), state->ld, rc)));
1357 return NT_STATUS_LDAP(rc);
1359 switch talloc_array_length(msg) {
1361 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1366 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1370 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1371 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1374 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1375 if (members == NULL) {
1376 return NT_STATUS_NO_MEMORY;
1379 for (i=0; i<num_members; i++) {
1380 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1381 TALLOC_FREE(members);
1382 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1386 *pmembers = members;
1387 *pnum_members = num_members;
1388 return NT_STATUS_OK;
1391 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1392 TALLOC_CTX *mem_ctx,
1393 const DOM_SID *domain_sid,
1394 const DOM_SID *members,
1396 uint32_t **palias_rids,
1397 size_t *pnum_alias_rids)
1399 struct pdb_ads_state *state = talloc_get_type_abort(
1400 m->private_data, struct pdb_ads_state);
1401 const char *attrs[1] = { "objectSid" };
1402 struct tldap_message **msg;
1403 uint32_t *alias_rids = NULL;
1404 size_t num_alias_rids = 0;
1406 bool got_members = false;
1411 * TODO: Get the filter right so that we only get the aliases from
1412 * either the SAM or BUILTIN
1415 filter = talloc_asprintf(talloc_tos(),
1416 "(&(|(grouptype=%d)(grouptype=%d))"
1417 "(objectclass=group)(|",
1418 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1419 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1420 if (filter == NULL) {
1421 return NT_STATUS_NO_MEMORY;
1424 for (i=0; i<num_members; i++) {
1427 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1428 if (!NT_STATUS_IS_OK(status)) {
1429 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1430 sid_string_dbg(&members[i]),
1431 nt_errstr(status)));
1434 filter = talloc_asprintf_append_buffer(
1435 filter, "(member=%s)", dn);
1437 if (filter == NULL) {
1438 return NT_STATUS_NO_MEMORY;
1447 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1448 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1449 &msg, "%s))", filter);
1450 TALLOC_FREE(filter);
1451 if (rc != TLDAP_SUCCESS) {
1452 DEBUG(10, ("tldap_search failed %s\n",
1453 tldap_errstr(debug_ctx(), state->ld, rc)));
1454 return NT_STATUS_LDAP(rc);
1457 count = talloc_array_length(msg);
1462 alias_rids = talloc_array(mem_ctx, uint32_t, count);
1463 if (alias_rids == NULL) {
1465 return NT_STATUS_NO_MEMORY;
1468 for (i=0; i<count; i++) {
1471 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1472 DEBUG(10, ("Could not pull SID for member %d\n", i));
1475 if (sid_peek_check_rid(domain_sid, &sid,
1476 &alias_rids[num_alias_rids])) {
1477 num_alias_rids += 1;
1482 *palias_rids = alias_rids;
1483 *pnum_alias_rids = 0;
1484 return NT_STATUS_OK;
1487 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1488 const DOM_SID *domain_sid,
1492 enum lsa_SidType *lsa_attrs)
1494 struct pdb_ads_state *state = talloc_get_type_abort(
1495 m->private_data, struct pdb_ads_state);
1496 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1499 if (num_rids == 0) {
1500 return NT_STATUS_NONE_MAPPED;
1505 for (i=0; i<num_rids; i++) {
1507 struct tldap_message **msg;
1512 lsa_attrs[i] = SID_NAME_UNKNOWN;
1514 sid_compose(&sid, domain_sid, rids[i]);
1516 sidstr = sid_binstring(talloc_tos(), &sid);
1517 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1519 rc = tldap_search_fmt(state->ld, state->domaindn,
1520 TLDAP_SCOPE_SUB, attrs,
1521 ARRAY_SIZE(attrs), 0, talloc_tos(),
1522 &msg, "(objectsid=%s)", sidstr);
1523 TALLOC_FREE(sidstr);
1524 if (rc != TLDAP_SUCCESS) {
1525 DEBUG(10, ("ldap_search failed %s\n",
1526 tldap_errstr(debug_ctx(), state->ld, rc)));
1530 switch talloc_array_length(msg) {
1532 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1537 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1540 names[i] = tldap_talloc_single_attribute(
1541 msg[0], "samAccountName", talloc_tos());
1542 if (names[i] == NULL) {
1543 DEBUG(10, ("no samAccountName\n"));
1546 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1547 DEBUG(10, ("no samAccountType"));
1550 lsa_attrs[i] = ads_atype_map(attr);
1554 if (num_mapped == 0) {
1555 return NT_STATUS_NONE_MAPPED;
1557 if (num_mapped < num_rids) {
1558 return STATUS_SOME_UNMAPPED;
1560 return NT_STATUS_OK;
1563 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1564 const DOM_SID *domain_sid,
1566 const char **pp_names,
1568 enum lsa_SidType *attrs)
1570 return NT_STATUS_NOT_IMPLEMENTED;
1573 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1574 int policy_index, uint32 *value)
1576 return account_policy_get(policy_index, value)
1577 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1580 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1581 int policy_index, uint32 value)
1583 return account_policy_set(policy_index, value)
1584 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1587 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1590 return NT_STATUS_NOT_IMPLEMENTED;
1593 struct pdb_ads_search_state {
1594 uint32_t acct_flags;
1595 struct samr_displayentry *entries;
1596 uint32_t num_entries;
1601 static bool pdb_ads_next_entry(struct pdb_search *search,
1602 struct samr_displayentry *entry)
1604 struct pdb_ads_search_state *state = talloc_get_type_abort(
1605 search->private_data, struct pdb_ads_search_state);
1607 if (state->current == state->num_entries) {
1611 entry->idx = state->entries[state->current].idx;
1612 entry->rid = state->entries[state->current].rid;
1613 entry->acct_flags = state->entries[state->current].acct_flags;
1615 entry->account_name = talloc_strdup(
1616 search, state->entries[state->current].account_name);
1617 entry->fullname = talloc_strdup(
1618 search, state->entries[state->current].fullname);
1619 entry->description = talloc_strdup(
1620 search, state->entries[state->current].description);
1622 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1623 || (entry->description == NULL)) {
1624 DEBUG(0, ("talloc_strdup failed\n"));
1628 state->current += 1;
1632 static void pdb_ads_search_end(struct pdb_search *search)
1634 struct pdb_ads_search_state *state = talloc_get_type_abort(
1635 search->private_data, struct pdb_ads_search_state);
1639 static bool pdb_ads_search_filter(struct pdb_methods *m,
1640 struct pdb_search *search,
1642 struct pdb_ads_search_state **pstate)
1644 struct pdb_ads_state *state = talloc_get_type_abort(
1645 m->private_data, struct pdb_ads_state);
1646 struct pdb_ads_search_state *sstate;
1647 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1648 "userAccountControl", "description" };
1649 struct tldap_message **users;
1650 int i, rc, num_users;
1652 sstate = talloc_zero(search, struct pdb_ads_search_state);
1653 if (sstate == NULL) {
1657 rc = tldap_search_fmt(
1658 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1659 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1661 if (rc != TLDAP_SUCCESS) {
1662 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1663 tldap_errstr(debug_ctx(), state->ld, rc)));
1667 num_users = talloc_array_length(users);
1669 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1671 if (sstate->entries == NULL) {
1672 DEBUG(10, ("talloc failed\n"));
1676 sstate->num_entries = 0;
1678 for (i=0; i<num_users; i++) {
1679 struct samr_displayentry *e;
1682 e = &sstate->entries[sstate->num_entries];
1684 e->idx = sstate->num_entries;
1685 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1686 DEBUG(10, ("Could not pull sid\n"));
1689 sid_peek_rid(&sid, &e->rid);
1690 e->acct_flags = ACB_NORMAL;
1691 e->account_name = tldap_talloc_single_attribute(
1692 users[i], "samAccountName", sstate->entries);
1693 if (e->account_name == NULL) {
1696 e->fullname = tldap_talloc_single_attribute(
1697 users[i], "displayName", sstate->entries);
1698 if (e->fullname == NULL) {
1701 e->description = tldap_talloc_single_attribute(
1702 users[i], "description", sstate->entries);
1703 if (e->description == NULL) {
1704 e->description = "";
1707 sstate->num_entries += 1;
1708 if (sstate->num_entries >= num_users) {
1713 search->private_data = sstate;
1714 search->next_entry = pdb_ads_next_entry;
1715 search->search_end = pdb_ads_search_end;
1720 static bool pdb_ads_search_users(struct pdb_methods *m,
1721 struct pdb_search *search,
1724 struct pdb_ads_search_state *sstate;
1727 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1731 sstate->acct_flags = acct_flags;
1735 static bool pdb_ads_search_groups(struct pdb_methods *m,
1736 struct pdb_search *search)
1738 struct pdb_ads_search_state *sstate;
1742 filter = talloc_asprintf(talloc_tos(),
1743 "(&(grouptype=%d)(objectclass=group))",
1744 GTYPE_SECURITY_GLOBAL_GROUP);
1745 if (filter == NULL) {
1748 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1749 TALLOC_FREE(filter);
1753 sstate->acct_flags = 0;
1757 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1758 struct pdb_search *search,
1761 struct pdb_ads_search_state *sstate;
1765 filter = talloc_asprintf(
1766 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1767 sid_check_is_builtin(sid)
1768 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1769 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1771 if (filter == NULL) {
1774 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1775 TALLOC_FREE(filter);
1779 sstate->acct_flags = 0;
1783 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1789 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1792 struct pdb_ads_state *state = talloc_get_type_abort(
1793 m->private_data, struct pdb_ads_state);
1794 sid_compose(sid, &state->domainsid, uid);
1798 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1801 struct pdb_ads_state *state = talloc_get_type_abort(
1802 m->private_data, struct pdb_ads_state);
1803 sid_compose(sid, &state->domainsid, gid);
1807 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1808 union unid_t *id, enum lsa_SidType *type)
1810 struct pdb_ads_state *state = talloc_get_type_abort(
1811 m->private_data, struct pdb_ads_state);
1812 struct tldap_message **msg;
1818 * This is a big, big hack: Just hard-code the rid as uid/gid.
1821 sid_peek_rid(sid, &rid);
1823 sidstr = sid_binstring(talloc_tos(), sid);
1824 if (sidstr == NULL) {
1828 rc = tldap_search_fmt(
1829 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1830 NULL, 0, 0, talloc_tos(), &msg,
1831 "(&(objectsid=%s)(objectclass=user))", sidstr);
1832 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1834 *type = SID_NAME_USER;
1835 TALLOC_FREE(sidstr);
1839 rc = tldap_search_fmt(
1840 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1841 NULL, 0, 0, talloc_tos(), &msg,
1842 "(&(objectsid=%s)(objectclass=group))", sidstr);
1843 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1845 *type = SID_NAME_DOM_GRP;
1846 TALLOC_FREE(sidstr);
1850 TALLOC_FREE(sidstr);
1854 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1859 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1864 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1865 const char *domain, char** pwd,
1867 time_t *pass_last_set_time)
1872 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1873 const char* domain, const char* pwd,
1879 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1885 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1886 TALLOC_CTX *mem_ctx,
1887 uint32 *num_domains,
1888 struct trustdom_info ***domains)
1890 return NT_STATUS_NOT_IMPLEMENTED;
1893 static void pdb_ads_init_methods(struct pdb_methods *m)
1896 m->getsampwnam = pdb_ads_getsampwnam;
1897 m->getsampwsid = pdb_ads_getsampwsid;
1898 m->create_user = pdb_ads_create_user;
1899 m->delete_user = pdb_ads_delete_user;
1900 m->add_sam_account = pdb_ads_add_sam_account;
1901 m->update_sam_account = pdb_ads_update_sam_account;
1902 m->delete_sam_account = pdb_ads_delete_sam_account;
1903 m->rename_sam_account = pdb_ads_rename_sam_account;
1904 m->update_login_attempts = pdb_ads_update_login_attempts;
1905 m->getgrsid = pdb_ads_getgrsid;
1906 m->getgrgid = pdb_ads_getgrgid;
1907 m->getgrnam = pdb_ads_getgrnam;
1908 m->create_dom_group = pdb_ads_create_dom_group;
1909 m->delete_dom_group = pdb_ads_delete_dom_group;
1910 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1911 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1912 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1913 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1914 m->enum_group_members = pdb_ads_enum_group_members;
1915 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1916 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1917 m->add_groupmem = pdb_ads_add_groupmem;
1918 m->del_groupmem = pdb_ads_del_groupmem;
1919 m->create_alias = pdb_ads_create_alias;
1920 m->delete_alias = pdb_ads_delete_alias;
1921 m->get_aliasinfo = pdb_default_get_aliasinfo;
1922 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1923 m->add_aliasmem = pdb_ads_add_aliasmem;
1924 m->del_aliasmem = pdb_ads_del_aliasmem;
1925 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1926 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1927 m->lookup_rids = pdb_ads_lookup_rids;
1928 m->lookup_names = pdb_ads_lookup_names;
1929 m->get_account_policy = pdb_ads_get_account_policy;
1930 m->set_account_policy = pdb_ads_set_account_policy;
1931 m->get_seq_num = pdb_ads_get_seq_num;
1932 m->search_users = pdb_ads_search_users;
1933 m->search_groups = pdb_ads_search_groups;
1934 m->search_aliases = pdb_ads_search_aliases;
1935 m->uid_to_rid = pdb_ads_uid_to_rid;
1936 m->uid_to_sid = pdb_ads_uid_to_sid;
1937 m->gid_to_sid = pdb_ads_gid_to_sid;
1938 m->sid_to_id = pdb_ads_sid_to_id;
1939 m->rid_algorithm = pdb_ads_rid_algorithm;
1940 m->new_rid = pdb_ads_new_rid;
1941 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1942 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1943 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1944 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1947 static void free_private_data(void **vp)
1949 struct pdb_ads_state *state = talloc_get_type_abort(
1950 *vp, struct pdb_ads_state);
1952 TALLOC_FREE(state->ld);
1957 this is used to catch debug messages from events
1959 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
1960 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
1962 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
1963 const char *fmt, va_list ap)
1965 int samba_level = -1;
1968 case TLDAP_DEBUG_FATAL:
1971 case TLDAP_DEBUG_ERROR:
1974 case TLDAP_DEBUG_WARNING:
1977 case TLDAP_DEBUG_TRACE:
1982 if (vasprintf(&s, fmt, ap) == -1) {
1985 DEBUG(samba_level, ("tldap: %s", s));
1989 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1990 const char *location)
1992 const char *rootdse_attrs[2] = {
1993 "defaultNamingContext", "configurationNamingContext" };
1994 const char *domain_attrs[1] = { "objectSid" };
1995 const char *ncname_attrs[1] = { "netbiosname" };
1996 struct tldap_message **rootdse, **domain, **ncname;
1997 TALLOC_CTX *frame = talloc_stackframe();
1998 struct sockaddr_un sunaddr;
2003 ZERO_STRUCT(sunaddr);
2004 sunaddr.sun_family = AF_UNIX;
2005 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
2007 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
2009 if (!NT_STATUS_IS_OK(status)) {
2010 DEBUG(10, ("Could not connect to %s: %s\n", location,
2011 nt_errstr(status)));
2015 state->ld = tldap_context_create(state, fd);
2016 if (state->ld == NULL) {
2018 status = NT_STATUS_NO_MEMORY;
2021 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2023 rc = tldap_search_fmt(
2024 state->ld, "", TLDAP_SCOPE_BASE,
2025 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
2026 talloc_tos(), &rootdse, "(objectclass=*)");
2027 if (rc != TLDAP_SUCCESS) {
2028 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2029 tldap_errstr(debug_ctx(), state->ld, rc)));
2030 status = NT_STATUS_LDAP(rc);
2033 if (talloc_array_length(rootdse) != 1) {
2034 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2038 state->domaindn = tldap_talloc_single_attribute(
2039 rootdse[0], "defaultNamingContext", state);
2040 if (state->domaindn == NULL) {
2041 DEBUG(10, ("Could not get defaultNamingContext\n"));
2042 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2045 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2047 state->configdn = tldap_talloc_single_attribute(
2048 rootdse[0], "configurationNamingContext", state);
2049 if (state->domaindn == NULL) {
2050 DEBUG(10, ("Could not get configurationNamingContext\n"));
2051 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2054 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2057 * Figure out our domain's SID
2059 rc = tldap_search_fmt(
2060 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
2061 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2062 talloc_tos(), &domain, "(objectclass=*)");
2063 if (rc != TLDAP_SUCCESS) {
2064 DEBUG(10, ("Could not retrieve domain: %s\n",
2065 tldap_errstr(debug_ctx(), state->ld, rc)));
2066 status = NT_STATUS_LDAP(rc);
2070 num_domains = talloc_array_length(domain);
2071 if (num_domains != 1) {
2072 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2073 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2076 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2077 DEBUG(10, ("Could not retrieve domain SID\n"));
2078 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2081 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2084 * Figure out our domain's short name
2086 rc = tldap_search_fmt(
2087 state->ld, state->configdn, TLDAP_SCOPE_SUB,
2088 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2089 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2090 if (rc != TLDAP_SUCCESS) {
2091 DEBUG(10, ("Could not retrieve ncname: %s\n",
2092 tldap_errstr(debug_ctx(), state->ld, rc)));
2093 status = NT_STATUS_LDAP(rc);
2096 if (talloc_array_length(ncname) != 1) {
2097 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2101 state->netbiosname = tldap_talloc_single_attribute(
2102 ncname[0], "netbiosname", state);
2103 if (state->netbiosname == NULL) {
2104 DEBUG(10, ("Could not get netbiosname\n"));
2105 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2108 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2110 if (!strequal(lp_workgroup(), state->netbiosname)) {
2111 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2112 state->netbiosname, lp_workgroup()));
2113 status = NT_STATUS_NO_SUCH_DOMAIN;
2117 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2119 status = NT_STATUS_OK;
2125 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2126 const char *location)
2128 struct pdb_methods *m;
2129 struct pdb_ads_state *state;
2133 m = talloc(talloc_autofree_context(), struct pdb_methods);
2135 return NT_STATUS_NO_MEMORY;
2137 state = talloc(m, struct pdb_ads_state);
2138 if (state == NULL) {
2141 m->private_data = state;
2142 m->free_private_data = free_private_data;
2143 pdb_ads_init_methods(m);
2145 if (location == NULL) {
2146 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2150 if (location == NULL) {
2154 status = pdb_ads_connect(state, location);
2155 if (!NT_STATUS_IS_OK(status)) {
2156 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2161 return NT_STATUS_OK;
2163 status = NT_STATUS_NO_MEMORY;
2169 NTSTATUS pdb_ads_init(void);
2170 NTSTATUS pdb_ads_init(void)
2172 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",