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;
478 rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, NULL);
479 if (rc != TLDAP_SUCCESS) {
480 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
481 tldap_errstr(debug_ctx(), state->ld, rc)));
482 return NT_STATUS_LDAP(rc);
490 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
491 struct samu *username)
493 return NT_STATUS_NOT_IMPLEMENTED;
496 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
497 struct samu *oldname,
500 return NT_STATUS_NOT_IMPLEMENTED;
503 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
504 struct samu *sam_acct,
507 return NT_STATUS_NOT_IMPLEMENTED;
510 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
513 struct pdb_ads_state *state = talloc_get_type_abort(
514 m->private_data, struct pdb_ads_state);
515 const char *attrs[4] = { "objectSid", "description", "samAccountName",
518 struct tldap_message **group;
522 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
523 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
524 &group, "%s", filter);
525 if (rc != TLDAP_SUCCESS) {
526 DEBUG(10, ("ldap_search failed %s\n",
527 tldap_errstr(debug_ctx(), state->ld, rc)));
528 return NT_STATUS_LDAP(rc);
530 if (talloc_array_length(group) != 1) {
531 DEBUG(10, ("Expected 1 user, got %d\n",
532 (int)talloc_array_length(group)));
533 return NT_STATUS_INTERNAL_DB_CORRUPTION;
536 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
537 return NT_STATUS_INTERNAL_DB_CORRUPTION;
539 map->gid = pdb_ads_sid2gid(&map->sid);
541 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
542 return NT_STATUS_INTERNAL_DB_CORRUPTION;
545 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
546 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
547 map->sid_name_use = SID_NAME_ALIAS;
549 case GTYPE_SECURITY_GLOBAL_GROUP:
550 map->sid_name_use = SID_NAME_DOM_GRP;
553 return NT_STATUS_INTERNAL_DB_CORRUPTION;
556 str = tldap_talloc_single_attribute(group[0], "samAccountName",
559 return NT_STATUS_INTERNAL_DB_CORRUPTION;
561 fstrcpy(map->nt_name, str);
564 str = tldap_talloc_single_attribute(group[0], "description",
567 fstrcpy(map->comment, str);
570 map->comment[0] = '\0';
577 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
583 filter = talloc_asprintf(talloc_tos(),
584 "(&(objectsid=%s)(objectclass=group))",
585 sid_string_talloc(talloc_tos(), &sid));
586 if (filter == NULL) {
587 return NT_STATUS_NO_MEMORY;
590 status = pdb_ads_getgrfilter(m, map, filter);
595 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
599 pdb_ads_gid_to_sid(m, gid, &sid);
600 return pdb_ads_getgrsid(m, map, sid);
603 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
609 filter = talloc_asprintf(talloc_tos(),
610 "(&(samaccountname=%s)(objectclass=group))",
612 if (filter == NULL) {
613 return NT_STATUS_NO_MEMORY;
616 status = pdb_ads_getgrfilter(m, map, filter);
621 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
622 TALLOC_CTX *mem_ctx, const char *name,
625 TALLOC_CTX *frame = talloc_stackframe();
626 struct pdb_ads_state *state = talloc_get_type_abort(
627 m->private_data, struct pdb_ads_state);
628 const char *attrs[1] = { "objectSid" };
630 struct tldap_mod *mods = NULL;
631 struct tldap_message **alias;
637 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
641 return NT_STATUS_NO_MEMORY;
644 ok &= tldap_make_mod_fmt(
645 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
647 ok &= tldap_make_mod_fmt(
648 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
649 ok &= tldap_make_mod_fmt(
650 NULL, talloc_tos(), &num_mods, &mods, "groupType",
651 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
655 return NT_STATUS_NO_MEMORY;
658 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
659 if (rc != TLDAP_SUCCESS) {
660 DEBUG(10, ("ldap_add failed %s\n",
661 tldap_errstr(debug_ctx(), state->ld, rc)));
663 return NT_STATUS_LDAP(rc);
666 rc = tldap_search_fmt(
667 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
668 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
669 "(&(objectclass=group)(samaccountname=%s))", name);
670 if (rc != TLDAP_SUCCESS) {
671 DEBUG(10, ("Could not find just created alias %s: %s\n",
672 name, tldap_errstr(debug_ctx(), state->ld, rc)));
674 return NT_STATUS_LDAP(rc);
677 if (talloc_array_length(alias) != 1) {
678 DEBUG(10, ("Got %d alias, expected one\n",
679 (int)talloc_array_length(alias)));
681 return NT_STATUS_LDAP(rc);
684 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
685 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
688 return NT_STATUS_INTERNAL_DB_CORRUPTION;
691 sid_peek_rid(&sid, rid);
696 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
697 TALLOC_CTX *mem_ctx, uint32 rid)
699 struct pdb_ads_state *state = talloc_get_type_abort(
700 m->private_data, struct pdb_ads_state);
703 struct tldap_message **msg;
707 sid_compose(&sid, &state->domainsid, rid);
709 sidstr = sid_binstring(talloc_tos(), &sid);
710 NT_STATUS_HAVE_NO_MEMORY(sidstr);
712 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
713 NULL, 0, 0, talloc_tos(), &msg,
714 ("(&(objectSid=%s)(objectClass=group))"),
717 if (rc != TLDAP_SUCCESS) {
718 DEBUG(10, ("ldap_search failed %s\n",
719 tldap_errstr(debug_ctx(), state->ld, rc)));
720 return NT_STATUS_LDAP(rc);
723 switch talloc_array_length(msg) {
725 return NT_STATUS_NO_SUCH_GROUP;
729 return NT_STATUS_INTERNAL_DB_CORRUPTION;
732 if (!tldap_entry_dn(msg[0], &dn)) {
733 return NT_STATUS_INTERNAL_DB_CORRUPTION;
736 rc = tldap_delete(state->ld, dn, NULL, NULL);
737 if (rc != TLDAP_SUCCESS) {
738 DEBUG(10, ("ldap_delete failed: %s\n",
739 tldap_errstr(debug_ctx(), state->ld, rc)));
741 return NT_STATUS_LDAP(rc);
748 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
751 return NT_STATUS_NOT_IMPLEMENTED;
754 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
757 return NT_STATUS_NOT_IMPLEMENTED;
760 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
763 return NT_STATUS_NOT_IMPLEMENTED;
766 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
768 enum lsa_SidType sid_name_use,
770 size_t *p_num_entries,
773 return NT_STATUS_NOT_IMPLEMENTED;
776 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
778 const DOM_SID *group,
780 size_t *pnum_members)
782 struct pdb_ads_state *state = talloc_get_type_abort(
783 m->private_data, struct pdb_ads_state);
784 const char *attrs[1] = { "member" };
786 struct tldap_message **msg;
787 int i, rc, num_members;
791 sidstr = sid_binstring(talloc_tos(), group);
792 NT_STATUS_HAVE_NO_MEMORY(sidstr);
794 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
795 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
796 "(objectsid=%s)", sidstr);
798 if (rc != TLDAP_SUCCESS) {
799 DEBUG(10, ("ldap_search failed %s\n",
800 tldap_errstr(debug_ctx(), state->ld, rc)));
801 return NT_STATUS_LDAP(rc);
803 switch talloc_array_length(msg) {
805 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
810 return NT_STATUS_INTERNAL_DB_CORRUPTION;
814 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
815 return NT_STATUS_INTERNAL_DB_CORRUPTION;
818 members = talloc_array(mem_ctx, uint32_t, num_members);
819 if (members == NULL) {
820 return NT_STATUS_NO_MEMORY;
823 for (i=0; i<num_members; i++) {
825 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &sid)
826 || !sid_peek_rid(&sid, &members[i])) {
827 TALLOC_FREE(members);
828 return NT_STATUS_INTERNAL_DB_CORRUPTION;
833 *pnum_members = num_members;
837 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
842 size_t *p_num_groups)
844 struct pdb_ads_state *state = talloc_get_type_abort(
845 m->private_data, struct pdb_ads_state);
846 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
848 const char *attrs[1] = { "objectSid" };
849 struct tldap_message **groups;
852 struct dom_sid *group_sids;
855 rc = tldap_search_fmt(
856 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
857 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
858 "(&(member=%s)(grouptype=%d)(objectclass=group))",
859 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
860 if (rc != TLDAP_SUCCESS) {
861 DEBUG(10, ("ldap_search failed %s\n",
862 tldap_errstr(debug_ctx(), state->ld, rc)));
863 return NT_STATUS_LDAP(rc);
866 count = talloc_array_length(groups);
868 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
869 if (group_sids == NULL) {
870 return NT_STATUS_NO_MEMORY;
872 gids = talloc_array(mem_ctx, gid_t, count);
874 TALLOC_FREE(group_sids);
875 return NT_STATUS_NO_MEMORY;
879 for (i=0; i<count; i++) {
880 if (!tldap_pull_binsid(groups[i], "objectSid",
881 &group_sids[num_groups])) {
884 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
887 if (num_groups == count) {
892 *pp_sids = group_sids;
894 *p_num_groups = num_groups;
898 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
902 return NT_STATUS_NOT_IMPLEMENTED;
905 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
907 uint32 grouprid, uint32 memberrid,
910 struct pdb_ads_state *state = talloc_get_type_abort(
911 m->private_data, struct pdb_ads_state);
912 TALLOC_CTX *frame = talloc_stackframe();
913 struct dom_sid groupsid, membersid;
914 char *groupdn, *memberdn;
915 struct tldap_mod *mods;
919 sid_compose(&groupsid, &state->domainsid, grouprid);
920 sid_compose(&membersid, &state->domainsid, memberrid);
922 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
923 if (!NT_STATUS_IS_OK(status)) {
925 return NT_STATUS_NO_SUCH_GROUP;
927 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
928 if (!NT_STATUS_IS_OK(status)) {
930 return NT_STATUS_NO_SUCH_USER;
935 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
936 "member", memberdn)) {
938 return NT_STATUS_NO_MEMORY;
941 rc = tldap_modify(state->ld, groupdn, 1, mods, NULL, NULL);
943 if (rc != TLDAP_SUCCESS) {
944 DEBUG(10, ("ldap_modify failed: %s\n",
945 tldap_errstr(debug_ctx(), state->ld, rc)));
946 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
947 return NT_STATUS_MEMBER_IN_GROUP;
949 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
950 return NT_STATUS_MEMBER_NOT_IN_GROUP;
952 return NT_STATUS_LDAP(rc);
958 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
960 uint32 group_rid, uint32 member_rid)
962 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
966 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
968 uint32 group_rid, uint32 member_rid)
970 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
974 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
975 const char *name, uint32 *rid)
977 TALLOC_CTX *frame = talloc_stackframe();
978 struct pdb_ads_state *state = talloc_get_type_abort(
979 m->private_data, struct pdb_ads_state);
980 const char *attrs[1] = { "objectSid" };
982 struct tldap_mod *mods = NULL;
983 struct tldap_message **alias;
989 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
993 return NT_STATUS_NO_MEMORY;
996 ok &= tldap_make_mod_fmt(
997 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
999 ok &= tldap_make_mod_fmt(
1000 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
1001 ok &= tldap_make_mod_fmt(
1002 NULL, talloc_tos(), &num_mods, &mods, "groupType",
1003 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1007 return NT_STATUS_NO_MEMORY;
1010 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
1011 if (rc != TLDAP_SUCCESS) {
1012 DEBUG(10, ("ldap_add failed %s\n",
1013 tldap_errstr(debug_ctx(), state->ld, rc)));
1015 return NT_STATUS_LDAP(rc);
1018 rc = tldap_search_fmt(
1019 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1020 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1021 "(&(objectclass=group)(samaccountname=%s))", name);
1022 if (rc != TLDAP_SUCCESS) {
1023 DEBUG(10, ("Could not find just created alias %s: %s\n",
1024 name, tldap_errstr(debug_ctx(), state->ld, rc)));
1026 return NT_STATUS_LDAP(rc);
1029 if (talloc_array_length(alias) != 1) {
1030 DEBUG(10, ("Got %d alias, expected one\n",
1031 (int)talloc_array_length(alias)));
1033 return NT_STATUS_LDAP(rc);
1036 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1037 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1040 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1043 sid_peek_rid(&sid, rid);
1045 return NT_STATUS_OK;
1048 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1051 struct pdb_ads_state *state = talloc_get_type_abort(
1052 m->private_data, struct pdb_ads_state);
1053 struct tldap_message **alias;
1057 sidstr = sid_binstring(talloc_tos(), sid);
1058 if (sidstr == NULL) {
1059 return NT_STATUS_NO_MEMORY;
1062 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1063 NULL, 0, 0, talloc_tos(), &alias,
1064 "(&(objectSid=%s)(objectclass=group)"
1065 "(|(grouptype=%d)(grouptype=%d)))",
1066 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1067 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1068 TALLOC_FREE(sidstr);
1069 if (rc != TLDAP_SUCCESS) {
1070 DEBUG(10, ("ldap_search failed: %s\n",
1071 tldap_errstr(debug_ctx(), state->ld, rc)));
1073 return NT_STATUS_LDAP(rc);
1075 if (talloc_array_length(alias) != 1) {
1076 DEBUG(10, ("Expected 1 alias, got %d\n",
1077 (int)talloc_array_length(alias)));
1078 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1080 if (!tldap_entry_dn(alias[0], &dn)) {
1081 DEBUG(10, ("Could not get DN for alias %s\n",
1082 sid_string_dbg(sid)));
1083 return NT_STATUS_INTERNAL_ERROR;
1086 rc = tldap_delete(state->ld, dn, NULL, NULL);
1087 if (rc != TLDAP_SUCCESS) {
1088 DEBUG(10, ("ldap_delete failed: %s\n",
1089 tldap_errstr(debug_ctx(), state->ld, rc)));
1091 return NT_STATUS_LDAP(rc);
1094 return NT_STATUS_OK;
1097 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
1099 struct acct_info *info)
1101 return NT_STATUS_NOT_IMPLEMENTED;
1104 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1106 struct acct_info *info)
1108 return NT_STATUS_NOT_IMPLEMENTED;
1111 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1112 const struct dom_sid *sid,
1113 TALLOC_CTX *mem_ctx, char **pdn)
1115 struct tldap_message **msg;
1119 sidstr = sid_binstring(talloc_tos(), sid);
1120 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1122 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1123 NULL, 0, 0, talloc_tos(), &msg,
1124 "(objectsid=%s)", sidstr);
1125 TALLOC_FREE(sidstr);
1126 if (rc != TLDAP_SUCCESS) {
1127 DEBUG(10, ("ldap_search failed %s\n",
1128 tldap_errstr(debug_ctx(), state->ld, rc)));
1129 return NT_STATUS_LDAP(rc);
1132 switch talloc_array_length(msg) {
1134 return NT_STATUS_NOT_FOUND;
1138 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1141 if (!tldap_entry_dn(msg[0], &dn)) {
1142 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1145 dn = talloc_strdup(mem_ctx, dn);
1147 return NT_STATUS_NO_MEMORY;
1152 return NT_STATUS_OK;
1155 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1156 const DOM_SID *alias,
1157 const DOM_SID *member,
1160 struct pdb_ads_state *state = talloc_get_type_abort(
1161 m->private_data, struct pdb_ads_state);
1162 TALLOC_CTX *frame = talloc_stackframe();
1163 struct tldap_mod *mods;
1165 char *aliasdn, *memberdn;
1168 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1169 if (!NT_STATUS_IS_OK(status)) {
1170 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1171 sid_string_dbg(alias), nt_errstr(status)));
1173 return NT_STATUS_NO_SUCH_ALIAS;
1175 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1176 if (!NT_STATUS_IS_OK(status)) {
1177 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1178 sid_string_dbg(member), nt_errstr(status)));
1185 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1186 "member", memberdn)) {
1188 return NT_STATUS_NO_MEMORY;
1191 rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
1193 if (rc != TLDAP_SUCCESS) {
1194 DEBUG(10, ("ldap_modify failed: %s\n",
1195 tldap_errstr(debug_ctx(), state->ld, rc)));
1196 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1197 return NT_STATUS_MEMBER_IN_ALIAS;
1199 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1200 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1202 return NT_STATUS_LDAP(rc);
1205 return NT_STATUS_OK;
1208 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1209 const DOM_SID *alias,
1210 const DOM_SID *member)
1212 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1215 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1216 const DOM_SID *alias,
1217 const DOM_SID *member)
1219 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1222 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1223 struct dom_sid *psid)
1225 const char *attrs[1] = { "objectSid" };
1226 struct tldap_message **msg;
1232 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1233 dnblob->data, dnblob->length, &dn, &len,
1237 rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1238 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1239 &msg, "(objectclass=*)");
1241 if (talloc_array_length(msg) != 1) {
1242 DEBUG(10, ("Got %d objects, expected one\n",
1243 (int)talloc_array_length(msg)));
1248 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1253 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1254 const DOM_SID *alias,
1255 TALLOC_CTX *mem_ctx,
1257 size_t *pnum_members)
1259 struct pdb_ads_state *state = talloc_get_type_abort(
1260 m->private_data, struct pdb_ads_state);
1261 const char *attrs[1] = { "member" };
1263 struct tldap_message **msg;
1264 int i, rc, num_members;
1266 struct dom_sid *members;
1268 sidstr = sid_binstring(talloc_tos(), alias);
1269 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1271 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1272 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1273 "(objectsid=%s)", sidstr);
1274 TALLOC_FREE(sidstr);
1275 if (rc != TLDAP_SUCCESS) {
1276 DEBUG(10, ("ldap_search failed %s\n",
1277 tldap_errstr(debug_ctx(), state->ld, rc)));
1278 return NT_STATUS_LDAP(rc);
1280 switch talloc_array_length(msg) {
1282 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1287 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1291 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1292 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1295 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1296 if (members == NULL) {
1297 return NT_STATUS_NO_MEMORY;
1300 for (i=0; i<num_members; i++) {
1301 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1302 TALLOC_FREE(members);
1303 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1307 *pmembers = members;
1308 *pnum_members = num_members;
1309 return NT_STATUS_OK;
1312 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1313 TALLOC_CTX *mem_ctx,
1314 const DOM_SID *domain_sid,
1315 const DOM_SID *members,
1317 uint32 **pp_alias_rids,
1318 size_t *p_num_alias_rids)
1320 return NT_STATUS_NOT_IMPLEMENTED;
1323 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1324 const DOM_SID *domain_sid,
1327 const char **pp_names,
1328 enum lsa_SidType *attrs)
1330 return NT_STATUS_NOT_IMPLEMENTED;
1333 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1334 const DOM_SID *domain_sid,
1336 const char **pp_names,
1338 enum lsa_SidType *attrs)
1340 return NT_STATUS_NOT_IMPLEMENTED;
1343 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1344 int policy_index, uint32 *value)
1346 return account_policy_get(policy_index, value)
1347 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1350 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1351 int policy_index, uint32 value)
1353 return account_policy_set(policy_index, value)
1354 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1357 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1360 return NT_STATUS_NOT_IMPLEMENTED;
1363 struct pdb_ads_search_state {
1364 uint32_t acct_flags;
1365 struct samr_displayentry *entries;
1366 uint32_t num_entries;
1371 static bool pdb_ads_next_entry(struct pdb_search *search,
1372 struct samr_displayentry *entry)
1374 struct pdb_ads_search_state *state = talloc_get_type_abort(
1375 search->private_data, struct pdb_ads_search_state);
1377 if (state->current == state->num_entries) {
1381 entry->idx = state->entries[state->current].idx;
1382 entry->rid = state->entries[state->current].rid;
1383 entry->acct_flags = state->entries[state->current].acct_flags;
1385 entry->account_name = talloc_strdup(
1386 search, state->entries[state->current].account_name);
1387 entry->fullname = talloc_strdup(
1388 search, state->entries[state->current].fullname);
1389 entry->description = talloc_strdup(
1390 search, state->entries[state->current].description);
1392 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1393 || (entry->description == NULL)) {
1394 DEBUG(0, ("talloc_strdup failed\n"));
1398 state->current += 1;
1402 static void pdb_ads_search_end(struct pdb_search *search)
1404 struct pdb_ads_search_state *state = talloc_get_type_abort(
1405 search->private_data, struct pdb_ads_search_state);
1409 static bool pdb_ads_search_filter(struct pdb_methods *m,
1410 struct pdb_search *search,
1412 struct pdb_ads_search_state **pstate)
1414 struct pdb_ads_state *state = talloc_get_type_abort(
1415 m->private_data, struct pdb_ads_state);
1416 struct pdb_ads_search_state *sstate;
1417 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1418 "userAccountControl", "description" };
1419 struct tldap_message **users;
1420 int i, rc, num_users;
1422 sstate = talloc_zero(search, struct pdb_ads_search_state);
1423 if (sstate == NULL) {
1427 rc = tldap_search_fmt(
1428 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1429 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1431 if (rc != TLDAP_SUCCESS) {
1432 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1433 tldap_errstr(debug_ctx(), state->ld, rc)));
1437 num_users = talloc_array_length(users);
1439 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1441 if (sstate->entries == NULL) {
1442 DEBUG(10, ("talloc failed\n"));
1446 sstate->num_entries = 0;
1448 for (i=0; i<num_users; i++) {
1449 struct samr_displayentry *e;
1452 e = &sstate->entries[sstate->num_entries];
1454 e->idx = sstate->num_entries;
1455 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1456 DEBUG(10, ("Could not pull sid\n"));
1459 sid_peek_rid(&sid, &e->rid);
1460 e->acct_flags = ACB_NORMAL;
1461 e->account_name = tldap_talloc_single_attribute(
1462 users[i], "samAccountName", sstate->entries);
1463 if (e->account_name == NULL) {
1466 e->fullname = tldap_talloc_single_attribute(
1467 users[i], "displayName", sstate->entries);
1468 if (e->fullname == NULL) {
1471 e->description = tldap_talloc_single_attribute(
1472 users[i], "description", sstate->entries);
1473 if (e->description == NULL) {
1474 e->description = "";
1477 sstate->num_entries += 1;
1478 if (sstate->num_entries >= num_users) {
1483 search->private_data = sstate;
1484 search->next_entry = pdb_ads_next_entry;
1485 search->search_end = pdb_ads_search_end;
1490 static bool pdb_ads_search_users(struct pdb_methods *m,
1491 struct pdb_search *search,
1494 struct pdb_ads_search_state *sstate;
1497 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1501 sstate->acct_flags = acct_flags;
1505 static bool pdb_ads_search_groups(struct pdb_methods *m,
1506 struct pdb_search *search)
1508 struct pdb_ads_search_state *sstate;
1512 filter = talloc_asprintf(talloc_tos(),
1513 "(&(grouptype=%d)(objectclass=group))",
1514 GTYPE_SECURITY_GLOBAL_GROUP);
1515 if (filter == NULL) {
1518 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1519 TALLOC_FREE(filter);
1523 sstate->acct_flags = 0;
1527 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1528 struct pdb_search *search,
1531 struct pdb_ads_search_state *sstate;
1535 filter = talloc_asprintf(
1536 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1537 sid_check_is_builtin(sid)
1538 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1539 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1541 if (filter == NULL) {
1544 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1545 TALLOC_FREE(filter);
1549 sstate->acct_flags = 0;
1553 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1559 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1562 struct pdb_ads_state *state = talloc_get_type_abort(
1563 m->private_data, struct pdb_ads_state);
1564 sid_compose(sid, &state->domainsid, uid);
1568 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1571 struct pdb_ads_state *state = talloc_get_type_abort(
1572 m->private_data, struct pdb_ads_state);
1573 sid_compose(sid, &state->domainsid, gid);
1577 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1578 union unid_t *id, enum lsa_SidType *type)
1580 struct pdb_ads_state *state = talloc_get_type_abort(
1581 m->private_data, struct pdb_ads_state);
1582 struct tldap_message **msg;
1588 * This is a big, big hack: Just hard-code the rid as uid/gid.
1591 sid_peek_rid(sid, &rid);
1593 sidstr = sid_binstring(talloc_tos(), sid);
1594 if (sidstr == NULL) {
1598 rc = tldap_search_fmt(
1599 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1600 NULL, 0, 0, talloc_tos(), &msg,
1601 "(&(objectsid=%s)(objectclass=user))", sidstr);
1602 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1604 *type = SID_NAME_USER;
1605 TALLOC_FREE(sidstr);
1609 rc = tldap_search_fmt(
1610 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1611 NULL, 0, 0, talloc_tos(), &msg,
1612 "(&(objectsid=%s)(objectclass=group))", sidstr);
1613 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1615 *type = SID_NAME_DOM_GRP;
1616 TALLOC_FREE(sidstr);
1620 TALLOC_FREE(sidstr);
1624 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1629 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1634 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1635 const char *domain, char** pwd,
1637 time_t *pass_last_set_time)
1642 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1643 const char* domain, const char* pwd,
1649 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1655 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1656 TALLOC_CTX *mem_ctx,
1657 uint32 *num_domains,
1658 struct trustdom_info ***domains)
1660 return NT_STATUS_NOT_IMPLEMENTED;
1663 static void pdb_ads_init_methods(struct pdb_methods *m)
1666 m->getsampwnam = pdb_ads_getsampwnam;
1667 m->getsampwsid = pdb_ads_getsampwsid;
1668 m->create_user = pdb_ads_create_user;
1669 m->delete_user = pdb_ads_delete_user;
1670 m->add_sam_account = pdb_ads_add_sam_account;
1671 m->update_sam_account = pdb_ads_update_sam_account;
1672 m->delete_sam_account = pdb_ads_delete_sam_account;
1673 m->rename_sam_account = pdb_ads_rename_sam_account;
1674 m->update_login_attempts = pdb_ads_update_login_attempts;
1675 m->getgrsid = pdb_ads_getgrsid;
1676 m->getgrgid = pdb_ads_getgrgid;
1677 m->getgrnam = pdb_ads_getgrnam;
1678 m->create_dom_group = pdb_ads_create_dom_group;
1679 m->delete_dom_group = pdb_ads_delete_dom_group;
1680 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1681 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1682 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1683 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1684 m->enum_group_members = pdb_ads_enum_group_members;
1685 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1686 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1687 m->add_groupmem = pdb_ads_add_groupmem;
1688 m->del_groupmem = pdb_ads_del_groupmem;
1689 m->create_alias = pdb_ads_create_alias;
1690 m->delete_alias = pdb_ads_delete_alias;
1691 m->get_aliasinfo = pdb_ads_get_aliasinfo;
1692 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1693 m->add_aliasmem = pdb_ads_add_aliasmem;
1694 m->del_aliasmem = pdb_ads_del_aliasmem;
1695 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1696 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1697 m->lookup_rids = pdb_ads_lookup_rids;
1698 m->lookup_names = pdb_ads_lookup_names;
1699 m->get_account_policy = pdb_ads_get_account_policy;
1700 m->set_account_policy = pdb_ads_set_account_policy;
1701 m->get_seq_num = pdb_ads_get_seq_num;
1702 m->search_users = pdb_ads_search_users;
1703 m->search_groups = pdb_ads_search_groups;
1704 m->search_aliases = pdb_ads_search_aliases;
1705 m->uid_to_rid = pdb_ads_uid_to_rid;
1706 m->uid_to_sid = pdb_ads_uid_to_sid;
1707 m->gid_to_sid = pdb_ads_gid_to_sid;
1708 m->sid_to_id = pdb_ads_sid_to_id;
1709 m->rid_algorithm = pdb_ads_rid_algorithm;
1710 m->new_rid = pdb_ads_new_rid;
1711 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1712 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1713 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1714 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1717 static void free_private_data(void **vp)
1719 struct pdb_ads_state *state = talloc_get_type_abort(
1720 *vp, struct pdb_ads_state);
1722 TALLOC_FREE(state->ld);
1726 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1727 const char *location)
1729 const char *rootdse_attrs[2] = {
1730 "defaultNamingContext", "configurationNamingContext" };
1731 const char *domain_attrs[1] = { "objectSid" };
1732 const char *ncname_attrs[1] = { "netbiosname" };
1733 struct tldap_message **rootdse, **domain, **ncname;
1734 TALLOC_CTX *frame = talloc_stackframe();
1735 struct sockaddr_un sunaddr;
1740 ZERO_STRUCT(sunaddr);
1741 sunaddr.sun_family = AF_UNIX;
1742 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1744 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1746 if (!NT_STATUS_IS_OK(status)) {
1747 DEBUG(10, ("Could not connect to %s: %s\n", location,
1748 nt_errstr(status)));
1752 state->ld = tldap_context_create(state, fd);
1753 if (state->ld == NULL) {
1755 status = NT_STATUS_NO_MEMORY;
1759 rc = tldap_search_fmt(
1760 state->ld, "", TLDAP_SCOPE_BASE,
1761 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1762 talloc_tos(), &rootdse, "(objectclass=*)");
1763 if (rc != TLDAP_SUCCESS) {
1764 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1765 tldap_errstr(debug_ctx(), state->ld, rc)));
1766 status = NT_STATUS_LDAP(rc);
1769 if (talloc_array_length(rootdse) != 1) {
1770 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1774 state->domaindn = tldap_talloc_single_attribute(
1775 rootdse[0], "defaultNamingContext", state);
1776 if (state->domaindn == NULL) {
1777 DEBUG(10, ("Could not get defaultNamingContext\n"));
1778 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1781 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1783 state->configdn = tldap_talloc_single_attribute(
1784 rootdse[0], "configurationNamingContext", state);
1785 if (state->domaindn == NULL) {
1786 DEBUG(10, ("Could not get configurationNamingContext\n"));
1787 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1790 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1793 * Figure out our domain's SID
1795 rc = tldap_search_fmt(
1796 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1797 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1798 talloc_tos(), &domain, "(objectclass=*)");
1799 if (rc != TLDAP_SUCCESS) {
1800 DEBUG(10, ("Could not retrieve domain: %s\n",
1801 tldap_errstr(debug_ctx(), state->ld, rc)));
1802 status = NT_STATUS_LDAP(rc);
1806 num_domains = talloc_array_length(domain);
1807 if (num_domains != 1) {
1808 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1809 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1812 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1813 DEBUG(10, ("Could not retrieve domain SID\n"));
1814 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1817 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1820 * Figure out our domain's short name
1822 rc = tldap_search_fmt(
1823 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1824 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1825 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1826 if (rc != TLDAP_SUCCESS) {
1827 DEBUG(10, ("Could not retrieve ncname: %s\n",
1828 tldap_errstr(debug_ctx(), state->ld, rc)));
1829 status = NT_STATUS_LDAP(rc);
1832 if (talloc_array_length(ncname) != 1) {
1833 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1837 state->netbiosname = tldap_talloc_single_attribute(
1838 ncname[0], "netbiosname", state);
1839 if (state->netbiosname == NULL) {
1840 DEBUG(10, ("Could not get netbiosname\n"));
1841 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1844 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1846 if (!strequal(lp_workgroup(), state->netbiosname)) {
1847 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1848 state->netbiosname, lp_workgroup()));
1849 status = NT_STATUS_NO_SUCH_DOMAIN;
1853 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1855 status = NT_STATUS_OK;
1861 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1862 const char *location)
1864 struct pdb_methods *m;
1865 struct pdb_ads_state *state;
1869 m = talloc(talloc_autofree_context(), struct pdb_methods);
1871 return NT_STATUS_NO_MEMORY;
1873 state = talloc(m, struct pdb_ads_state);
1874 if (state == NULL) {
1877 m->private_data = state;
1878 m->free_private_data = free_private_data;
1879 pdb_ads_init_methods(m);
1881 if (location == NULL) {
1882 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1886 if (location == NULL) {
1890 status = pdb_ads_connect(state, location);
1891 if (!NT_STATUS_IS_OK(status)) {
1892 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1897 return NT_STATUS_OK;
1899 status = NT_STATUS_NO_MEMORY;
1905 NTSTATUS pdb_ads_init(void);
1906 NTSTATUS pdb_ads_init(void)
1908 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",