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 static NTSTATUS
pdb_ads_getsampwsid(struct pdb_methods
*m
,
23 struct samu
*sam_acct
,
25 static bool pdb_ads_gid_to_sid(struct pdb_methods
*m
, gid_t gid
,
29 struct pdb_ads_state
{
30 struct tldap_context
*ld
;
31 struct dom_sid domainsid
;
37 static bool pdb_ads_pull_time(struct tldap_message
*msg
, const char *attr
,
42 if (!tldap_pull_uint64(msg
, attr
, &tmp
)) {
45 *ptime
= uint64s_nt_time_to_unix_abs(&tmp
);
49 static gid_t
pdb_ads_sid2gid(const struct dom_sid
*sid
)
52 sid_peek_rid(sid
, &rid
);
56 struct pdb_ads_samu_private
{
58 struct tldap_message
*ldapmsg
;
61 static struct samu
*pdb_ads_init_guest(TALLOC_CTX
*mem_ctx
,
62 struct pdb_methods
*m
)
64 struct pdb_ads_state
*state
= talloc_get_type_abort(
65 m
->private_data
, struct pdb_ads_state
);
66 struct dom_sid guest_sid
;
70 sid_compose(&guest_sid
, &state
->domainsid
, DOMAIN_USER_RID_GUEST
);
72 guest
= samu_new(mem_ctx
);
77 status
= pdb_ads_getsampwsid(m
, guest
, &guest_sid
);
78 if (!NT_STATUS_IS_OK(status
)) {
79 DEBUG(10, ("Could not init guest account: %s\n",
87 static struct pdb_ads_samu_private
*pdb_ads_get_samu_private(
88 struct pdb_methods
*m
, struct samu
*sam
)
90 struct pdb_ads_samu_private
*result
;
93 result
= (struct pdb_ads_samu_private
*)
94 pdb_get_backend_private_data(sam
, m
);
97 return talloc_get_type_abort(
98 result
, struct pdb_ads_samu_private
);
102 * This is now a weirdness of the passdb API. For the guest user we
103 * are not asked first.
105 sid_peek_rid(pdb_get_user_sid(sam
), &rid
);
107 if (rid
== DOMAIN_USER_RID_GUEST
) {
108 struct samu
*guest
= pdb_ads_init_guest(talloc_tos(), m
);
113 result
= talloc_get_type_abort(
114 pdb_get_backend_private_data(guest
, m
),
115 struct pdb_ads_samu_private
);
116 pdb_set_backend_private_data(
117 sam
, talloc_move(sam
, &result
), NULL
, m
, PDB_SET
);
119 return talloc_get_type_abort(
120 pdb_get_backend_private_data(sam
, m
),
121 struct pdb_ads_samu_private
);
127 static NTSTATUS
pdb_ads_init_sam_from_ads(struct pdb_methods
*m
,
129 struct tldap_message
*entry
)
131 struct pdb_ads_state
*state
= talloc_get_type_abort(
132 m
->private_data
, struct pdb_ads_state
);
133 TALLOC_CTX
*frame
= talloc_stackframe();
134 struct pdb_ads_samu_private
*priv
;
135 NTSTATUS status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
142 priv
= talloc(sam
, struct pdb_ads_samu_private
);
144 return NT_STATUS_NO_MEMORY
;
146 if (!tldap_entry_dn(entry
, &priv
->dn
)) {
148 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
151 str
= tldap_talloc_single_attribute(entry
, "samAccountName", sam
);
153 DEBUG(10, ("no samAccountName\n"));
156 pdb_set_username(sam
, str
, PDB_SET
);
159 if (pdb_ads_pull_time(entry
, "lastLogon", &tmp_time
)) {
160 pdb_set_logon_time(sam
, tmp_time
, PDB_SET
);
162 if (pdb_ads_pull_time(entry
, "lastLogoff", &tmp_time
)) {
163 pdb_set_logoff_time(sam
, tmp_time
, PDB_SET
);
165 if (pdb_ads_pull_time(entry
, "pwdLastSet", &tmp_time
)) {
166 pdb_set_pass_last_set_time(sam
, tmp_time
, PDB_SET
);
168 if (pdb_ads_pull_time(entry
, "accountExpires", &tmp_time
)) {
169 pdb_set_pass_last_set_time(sam
, tmp_time
, PDB_SET
);
172 str
= tldap_talloc_single_attribute(entry
, "samAccoutName",
175 pdb_set_username(sam
, str
, PDB_SET
);
178 str
= tldap_talloc_single_attribute(entry
, "displayName",
181 pdb_set_fullname(sam
, str
, PDB_SET
);
184 str
= tldap_talloc_single_attribute(entry
, "homeDirectory",
187 pdb_set_homedir(sam
, str
, PDB_SET
);
190 str
= tldap_talloc_single_attribute(entry
, "homeDrive", talloc_tos());
192 pdb_set_dir_drive(sam
, str
, PDB_SET
);
195 str
= tldap_talloc_single_attribute(entry
, "scriptPath", talloc_tos());
197 pdb_set_logon_script(sam
, str
, PDB_SET
);
200 str
= tldap_talloc_single_attribute(entry
, "profilePath",
203 pdb_set_profile_path(sam
, str
, PDB_SET
);
206 str
= tldap_talloc_single_attribute(entry
, "profilePath",
209 pdb_set_profile_path(sam
, str
, PDB_SET
);
212 if (!tldap_pull_binsid(entry
, "objectSid", &sid
)) {
213 DEBUG(10, ("Could not pull SID\n"));
216 pdb_set_user_sid(sam
, &sid
, PDB_SET
);
218 if (!tldap_pull_uint64(entry
, "userAccountControl", &n
)) {
219 DEBUG(10, ("Could not pull userAccountControl\n"));
222 pdb_set_acct_ctrl(sam
, ads_uf2acb(n
), PDB_SET
);
224 if (tldap_get_single_valueblob(entry
, "unicodePwd", &blob
)) {
225 if (blob
.length
!= NT_HASH_LEN
) {
226 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
227 (int)blob
.length
, NT_HASH_LEN
));
230 pdb_set_nt_passwd(sam
, blob
.data
, PDB_SET
);
233 if (tldap_get_single_valueblob(entry
, "dBCSPwd", &blob
)) {
234 if (blob
.length
!= LM_HASH_LEN
) {
235 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
236 (int)blob
.length
, LM_HASH_LEN
));
239 pdb_set_lanman_passwd(sam
, blob
.data
, PDB_SET
);
242 if (tldap_pull_uint64(entry
, "primaryGroupID", &n
)) {
243 sid_compose(&sid
, &state
->domainsid
, n
);
244 pdb_set_group_sid(sam
, &sid
, PDB_SET
);
248 priv
->ldapmsg
= talloc_move(priv
, &entry
);
249 pdb_set_backend_private_data(sam
, priv
, NULL
, m
, PDB_SET
);
251 status
= NT_STATUS_OK
;
257 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state
*state
,
258 struct tldap_message
*existing
,
260 int *pnum_mods
, struct tldap_mod
**pmods
,
265 /* TODO: All fields :-) */
267 ret
&= tldap_make_mod_fmt(
268 existing
, mem_ctx
, pnum_mods
, pmods
, "displayName",
269 pdb_get_fullname(sam
));
271 ret
&= tldap_make_mod_blob(
272 existing
, mem_ctx
, pnum_mods
, pmods
, "unicodePwd",
273 data_blob_const(pdb_get_nt_passwd(sam
), NT_HASH_LEN
));
275 ret
&= tldap_make_mod_blob(
276 existing
, mem_ctx
, pnum_mods
, pmods
, "dBCSPwd",
277 data_blob_const(pdb_get_lanman_passwd(sam
), NT_HASH_LEN
));
282 static NTSTATUS
pdb_ads_getsampwfilter(struct pdb_methods
*m
,
283 struct pdb_ads_state
*state
,
284 struct samu
*sam_acct
,
287 const char * attrs
[] = {
288 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
289 "sAMAccountName", "displayName", "homeDirectory",
290 "homeDrive", "scriptPath", "profilePath", "description",
291 "userWorkstations", "comment", "userParameters", "objectSid",
292 "primaryGroupID", "userAccountControl", "logonHours",
293 "badPwdCount", "logonCount", "countryCode", "codePage",
294 "unicodePwd", "dBCSPwd" };
295 struct tldap_message
**users
;
298 rc
= tldap_search_fmt(state
->ld
, state
->domaindn
, TLDAP_SCOPE_SUB
,
299 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
300 &users
, "%s", filter
);
301 if (rc
!= TLDAP_SUCCESS
) {
302 DEBUG(10, ("ldap_search failed %s\n",
303 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
304 return NT_STATUS_LDAP(rc
);
307 count
= talloc_array_length(users
);
309 DEBUG(10, ("Expected 1 user, got %d\n", count
));
310 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
313 return pdb_ads_init_sam_from_ads(m
, sam_acct
, users
[0]);
316 static NTSTATUS
pdb_ads_getsampwnam(struct pdb_methods
*m
,
317 struct samu
*sam_acct
,
318 const char *username
)
320 struct pdb_ads_state
*state
= talloc_get_type_abort(
321 m
->private_data
, struct pdb_ads_state
);
324 filter
= talloc_asprintf(
325 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
327 NT_STATUS_HAVE_NO_MEMORY(filter
);
329 return pdb_ads_getsampwfilter(m
, state
, sam_acct
, filter
);
332 static NTSTATUS
pdb_ads_getsampwsid(struct pdb_methods
*m
,
333 struct samu
*sam_acct
,
336 struct pdb_ads_state
*state
= talloc_get_type_abort(
337 m
->private_data
, struct pdb_ads_state
);
338 char *sidstr
, *filter
;
340 sidstr
= sid_binstring(talloc_tos(), sid
);
341 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
343 filter
= talloc_asprintf(
344 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr
);
346 NT_STATUS_HAVE_NO_MEMORY(filter
);
348 return pdb_ads_getsampwfilter(m
, state
, sam_acct
, filter
);
351 static NTSTATUS
pdb_ads_create_user(struct pdb_methods
*m
,
353 const char *name
, uint32 acct_flags
,
356 struct pdb_ads_state
*state
= talloc_get_type_abort(
357 m
->private_data
, struct pdb_ads_state
);
358 const char *attrs
[1] = { "objectSid" };
359 struct tldap_mod
*mods
= NULL
;
361 struct tldap_message
**user
;
367 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
370 return NT_STATUS_NO_MEMORY
;
373 /* TODO: Create machines etc */
376 ok
&= tldap_make_mod_fmt(
377 NULL
, talloc_tos(), &num_mods
, &mods
, "objectClass", "user");
378 ok
&= tldap_make_mod_fmt(
379 NULL
, talloc_tos(), &num_mods
, &mods
, "samAccountName", "%s",
382 return NT_STATUS_NO_MEMORY
;
385 rc
= tldap_add(state
->ld
, dn
, num_mods
, mods
, NULL
, NULL
);
386 if (rc
!= TLDAP_SUCCESS
) {
387 DEBUG(10, ("ldap_add failed %s\n",
388 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
390 return NT_STATUS_LDAP(rc
);
393 rc
= tldap_search_fmt(state
->ld
, state
->domaindn
, TLDAP_SCOPE_SUB
,
394 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &user
,
395 "(&(objectclass=user)(samaccountname=%s))",
397 if (rc
!= TLDAP_SUCCESS
) {
398 DEBUG(10, ("Could not find just created user %s: %s\n",
399 name
, tldap_errstr(debug_ctx(), state
->ld
, rc
)));
401 return NT_STATUS_LDAP(rc
);
404 if (talloc_array_length(user
) != 1) {
405 DEBUG(10, ("Got %d users, expected one\n",
406 (int)talloc_array_length(user
)));
408 return NT_STATUS_LDAP(rc
);
411 if (!tldap_pull_binsid(user
[0], "objectSid", &sid
)) {
412 DEBUG(10, ("Could not fetch objectSid from user %s\n",
415 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
418 sid_peek_rid(&sid
, rid
);
423 static NTSTATUS
pdb_ads_delete_user(struct pdb_methods
*m
,
427 struct pdb_ads_state
*state
= talloc_get_type_abort(
428 m
->private_data
, struct pdb_ads_state
);
429 struct pdb_ads_samu_private
*priv
= pdb_ads_get_samu_private(m
, sam
);
432 rc
= tldap_delete(state
->ld
, priv
->dn
, NULL
, NULL
);
433 if (rc
!= TLDAP_SUCCESS
) {
434 DEBUG(10, ("ldap_delete for %s failed: %s\n", priv
->dn
,
435 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
436 return NT_STATUS_LDAP(rc
);
441 static NTSTATUS
pdb_ads_add_sam_account(struct pdb_methods
*m
,
442 struct samu
*sampass
)
444 return NT_STATUS_NOT_IMPLEMENTED
;
447 static NTSTATUS
pdb_ads_update_sam_account(struct pdb_methods
*m
,
450 struct pdb_ads_state
*state
= talloc_get_type_abort(
451 m
->private_data
, struct pdb_ads_state
);
452 struct pdb_ads_samu_private
*priv
= pdb_ads_get_samu_private(m
, sam
);
453 struct tldap_mod
*mods
= NULL
;
454 int rc
, num_mods
= 0;
456 if (!pdb_ads_init_ads_from_sam(state
, priv
->ldapmsg
, talloc_tos(),
457 &num_mods
, &mods
, sam
)) {
458 return NT_STATUS_NO_MEMORY
;
461 rc
= tldap_modify(state
->ld
, priv
->dn
, num_mods
, mods
, NULL
, NULL
);
462 if (rc
!= TLDAP_SUCCESS
) {
463 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv
->dn
,
464 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
465 return NT_STATUS_LDAP(rc
);
473 static NTSTATUS
pdb_ads_delete_sam_account(struct pdb_methods
*m
,
474 struct samu
*username
)
476 return NT_STATUS_NOT_IMPLEMENTED
;
479 static NTSTATUS
pdb_ads_rename_sam_account(struct pdb_methods
*m
,
480 struct samu
*oldname
,
483 return NT_STATUS_NOT_IMPLEMENTED
;
486 static NTSTATUS
pdb_ads_update_login_attempts(struct pdb_methods
*m
,
487 struct samu
*sam_acct
,
490 return NT_STATUS_NOT_IMPLEMENTED
;
493 static NTSTATUS
pdb_ads_getgrfilter(struct pdb_methods
*m
, GROUP_MAP
*map
,
496 struct pdb_ads_state
*state
= talloc_get_type_abort(
497 m
->private_data
, struct pdb_ads_state
);
498 const char *attrs
[4] = { "objectSid", "description", "samAccountName",
501 struct tldap_message
**group
;
505 rc
= tldap_search_fmt(state
->ld
, state
->domaindn
, TLDAP_SCOPE_SUB
,
506 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
507 &group
, "%s", filter
);
508 if (rc
!= TLDAP_SUCCESS
) {
509 DEBUG(10, ("ldap_search failed %s\n",
510 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
511 return NT_STATUS_LDAP(rc
);
513 if (talloc_array_length(group
) != 1) {
514 DEBUG(10, ("Expected 1 user, got %d\n",
515 talloc_array_length(group
)));
516 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
519 if (!tldap_pull_binsid(group
[0], "objectSid", &map
->sid
)) {
520 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
522 map
->gid
= pdb_ads_sid2gid(&map
->sid
);
524 if (!tldap_pull_uint32(group
[0], "groupType", &grouptype
)) {
525 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
528 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
:
529 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
:
530 map
->sid_name_use
= SID_NAME_ALIAS
;
532 case GTYPE_SECURITY_GLOBAL_GROUP
:
533 map
->sid_name_use
= SID_NAME_DOM_GRP
;
536 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
539 str
= tldap_talloc_single_attribute(group
[0], "samAccountName",
542 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
544 fstrcpy(map
->nt_name
, str
);
547 str
= tldap_talloc_single_attribute(group
[0], "description",
550 fstrcpy(map
->comment
, str
);
553 map
->comment
[0] = '\0';
560 static NTSTATUS
pdb_ads_getgrsid(struct pdb_methods
*m
, GROUP_MAP
*map
,
566 filter
= talloc_asprintf(talloc_tos(),
567 "(&(objectsid=%s)(objectclass=group))",
568 sid_string_talloc(talloc_tos(), &sid
));
569 if (filter
== NULL
) {
570 return NT_STATUS_NO_MEMORY
;
573 status
= pdb_ads_getgrfilter(m
, map
, filter
);
578 static NTSTATUS
pdb_ads_getgrgid(struct pdb_methods
*m
, GROUP_MAP
*map
,
582 pdb_ads_gid_to_sid(m
, gid
, &sid
);
583 return pdb_ads_getgrsid(m
, map
, sid
);
586 static NTSTATUS
pdb_ads_getgrnam(struct pdb_methods
*m
, GROUP_MAP
*map
,
592 filter
= talloc_asprintf(talloc_tos(),
593 "(&(samaccountname=%s)(objectclass=group))",
595 if (filter
== NULL
) {
596 return NT_STATUS_NO_MEMORY
;
599 status
= pdb_ads_getgrfilter(m
, map
, filter
);
604 static NTSTATUS
pdb_ads_create_dom_group(struct pdb_methods
*m
,
605 TALLOC_CTX
*mem_ctx
, const char *name
,
608 TALLOC_CTX
*frame
= talloc_stackframe();
609 struct pdb_ads_state
*state
= talloc_get_type_abort(
610 m
->private_data
, struct pdb_ads_state
);
611 const char *attrs
[1] = { "objectSid" };
613 struct tldap_mod
*mods
= NULL
;
614 struct tldap_message
**alias
;
620 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
624 return NT_STATUS_NO_MEMORY
;
627 ok
&= tldap_make_mod_fmt(
628 NULL
, talloc_tos(), &num_mods
, &mods
, "samAccountName", "%s",
630 ok
&= tldap_make_mod_fmt(
631 NULL
, talloc_tos(), &num_mods
, &mods
, "objectClass", "group");
632 ok
&= tldap_make_mod_fmt(
633 NULL
, talloc_tos(), &num_mods
, &mods
, "groupType",
634 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP
);
638 return NT_STATUS_NO_MEMORY
;
641 rc
= tldap_add(state
->ld
, dn
, num_mods
, mods
, NULL
, NULL
);
642 if (rc
!= TLDAP_SUCCESS
) {
643 DEBUG(10, ("ldap_add failed %s\n",
644 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
646 return NT_STATUS_LDAP(rc
);
649 rc
= tldap_search_fmt(
650 state
->ld
, state
->domaindn
, TLDAP_SCOPE_SUB
,
651 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &alias
,
652 "(&(objectclass=group)(samaccountname=%s))", name
);
653 if (rc
!= TLDAP_SUCCESS
) {
654 DEBUG(10, ("Could not find just created alias %s: %s\n",
655 name
, tldap_errstr(debug_ctx(), state
->ld
, rc
)));
657 return NT_STATUS_LDAP(rc
);
660 if (talloc_array_length(alias
) != 1) {
661 DEBUG(10, ("Got %d alias, expected one\n",
662 (int)talloc_array_length(alias
)));
664 return NT_STATUS_LDAP(rc
);
667 if (!tldap_pull_binsid(alias
[0], "objectSid", &sid
)) {
668 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
671 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
674 sid_peek_rid(&sid
, rid
);
679 static NTSTATUS
pdb_ads_delete_dom_group(struct pdb_methods
*m
,
680 TALLOC_CTX
*mem_ctx
, uint32 rid
)
682 return NT_STATUS_NOT_IMPLEMENTED
;
685 static NTSTATUS
pdb_ads_add_group_mapping_entry(struct pdb_methods
*m
,
688 return NT_STATUS_NOT_IMPLEMENTED
;
691 static NTSTATUS
pdb_ads_update_group_mapping_entry(struct pdb_methods
*m
,
694 return NT_STATUS_NOT_IMPLEMENTED
;
697 static NTSTATUS
pdb_ads_delete_group_mapping_entry(struct pdb_methods
*m
,
700 return NT_STATUS_NOT_IMPLEMENTED
;
703 static NTSTATUS
pdb_ads_enum_group_mapping(struct pdb_methods
*m
,
705 enum lsa_SidType sid_name_use
,
707 size_t *p_num_entries
,
710 return NT_STATUS_NOT_IMPLEMENTED
;
713 static NTSTATUS
pdb_ads_enum_group_members(struct pdb_methods
*m
,
715 const DOM_SID
*group
,
716 uint32
**pp_member_rids
,
717 size_t *p_num_members
)
719 return NT_STATUS_NOT_IMPLEMENTED
;
722 static NTSTATUS
pdb_ads_enum_group_memberships(struct pdb_methods
*m
,
727 size_t *p_num_groups
)
729 struct pdb_ads_state
*state
= talloc_get_type_abort(
730 m
->private_data
, struct pdb_ads_state
);
731 struct pdb_ads_samu_private
*priv
= pdb_ads_get_samu_private(
733 const char *attrs
[1] = { "objectSid" };
734 struct tldap_message
**groups
;
737 struct dom_sid
*group_sids
;
740 rc
= tldap_search_fmt(
741 state
->ld
, state
->domaindn
, TLDAP_SCOPE_SUB
,
742 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &groups
,
743 "(&(member=%s)(grouptype=%d)(objectclass=group))",
744 priv
->dn
, GTYPE_SECURITY_GLOBAL_GROUP
);
745 if (rc
!= TLDAP_SUCCESS
) {
746 DEBUG(10, ("ldap_search failed %s\n",
747 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
748 return NT_STATUS_LDAP(rc
);
751 count
= talloc_array_length(groups
);
753 group_sids
= talloc_array(mem_ctx
, struct dom_sid
, count
);
754 if (group_sids
== NULL
) {
755 return NT_STATUS_NO_MEMORY
;
757 gids
= talloc_array(mem_ctx
, gid_t
, count
);
759 TALLOC_FREE(group_sids
);
760 return NT_STATUS_NO_MEMORY
;
764 for (i
=0; i
<count
; i
++) {
765 if (!tldap_pull_binsid(groups
[i
], "objectSid",
766 &group_sids
[num_groups
])) {
769 gids
[num_groups
] = pdb_ads_sid2gid(&group_sids
[num_groups
]);
772 if (num_groups
== count
) {
777 *pp_sids
= group_sids
;
779 *p_num_groups
= num_groups
;
783 static NTSTATUS
pdb_ads_set_unix_primary_group(struct pdb_methods
*m
,
787 return NT_STATUS_NOT_IMPLEMENTED
;
790 static NTSTATUS
pdb_ads_add_groupmem(struct pdb_methods
*m
,
792 uint32 group_rid
, uint32 member_rid
)
794 return NT_STATUS_NOT_IMPLEMENTED
;
797 static NTSTATUS
pdb_ads_del_groupmem(struct pdb_methods
*m
,
799 uint32 group_rid
, uint32 member_rid
)
801 return NT_STATUS_NOT_IMPLEMENTED
;
804 static NTSTATUS
pdb_ads_create_alias(struct pdb_methods
*m
,
805 const char *name
, uint32
*rid
)
807 TALLOC_CTX
*frame
= talloc_stackframe();
808 struct pdb_ads_state
*state
= talloc_get_type_abort(
809 m
->private_data
, struct pdb_ads_state
);
810 const char *attrs
[1] = { "objectSid" };
812 struct tldap_mod
*mods
= NULL
;
813 struct tldap_message
**alias
;
819 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
823 return NT_STATUS_NO_MEMORY
;
826 ok
&= tldap_make_mod_fmt(
827 NULL
, talloc_tos(), &num_mods
, &mods
, "samAccountName", "%s",
829 ok
&= tldap_make_mod_fmt(
830 NULL
, talloc_tos(), &num_mods
, &mods
, "objectClass", "group");
831 ok
&= tldap_make_mod_fmt(
832 NULL
, talloc_tos(), &num_mods
, &mods
, "groupType",
833 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
837 return NT_STATUS_NO_MEMORY
;
840 rc
= tldap_add(state
->ld
, dn
, num_mods
, mods
, NULL
, NULL
);
841 if (rc
!= TLDAP_SUCCESS
) {
842 DEBUG(10, ("ldap_add failed %s\n",
843 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
845 return NT_STATUS_LDAP(rc
);
848 rc
= tldap_search_fmt(
849 state
->ld
, state
->domaindn
, TLDAP_SCOPE_SUB
,
850 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &alias
,
851 "(&(objectclass=group)(samaccountname=%s))", name
);
852 if (rc
!= TLDAP_SUCCESS
) {
853 DEBUG(10, ("Could not find just created alias %s: %s\n",
854 name
, tldap_errstr(debug_ctx(), state
->ld
, rc
)));
856 return NT_STATUS_LDAP(rc
);
859 if (talloc_array_length(alias
) != 1) {
860 DEBUG(10, ("Got %d alias, expected one\n",
861 (int)talloc_array_length(alias
)));
863 return NT_STATUS_LDAP(rc
);
866 if (!tldap_pull_binsid(alias
[0], "objectSid", &sid
)) {
867 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
870 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
873 sid_peek_rid(&sid
, rid
);
878 static NTSTATUS
pdb_ads_delete_alias(struct pdb_methods
*m
,
881 struct pdb_ads_state
*state
= talloc_get_type_abort(
882 m
->private_data
, struct pdb_ads_state
);
883 struct tldap_message
**alias
;
887 sidstr
= sid_binstring(talloc_tos(), sid
);
888 if (sidstr
== NULL
) {
889 return NT_STATUS_NO_MEMORY
;
892 rc
= tldap_search_fmt(state
->ld
, state
->domaindn
, TLDAP_SCOPE_SUB
,
893 NULL
, 0, 0, talloc_tos(), &alias
,
894 "(&(objectSid=%s)(objectclass=group)"
895 "(|(grouptype=%d)(grouptype=%d)))",
896 sidstr
, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
897 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
899 if (rc
!= TLDAP_SUCCESS
) {
900 DEBUG(10, ("ldap_search failed: %s\n",
901 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
903 return NT_STATUS_LDAP(rc
);
905 if (talloc_array_length(alias
) != 1) {
906 DEBUG(10, ("Expected 1 alias, got %d\n",
907 talloc_array_length(alias
)));
908 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
910 if (!tldap_entry_dn(alias
[0], &dn
)) {
911 DEBUG(10, ("Could not get DN for alias %s\n",
912 sid_string_dbg(sid
)));
913 return NT_STATUS_INTERNAL_ERROR
;
916 rc
= tldap_delete(state
->ld
, dn
, NULL
, NULL
);
917 if (rc
!= TLDAP_SUCCESS
) {
918 DEBUG(10, ("ldap_delete failed: %s\n",
919 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
921 return NT_STATUS_LDAP(rc
);
927 static NTSTATUS
pdb_ads_get_aliasinfo(struct pdb_methods
*m
,
929 struct acct_info
*info
)
931 return NT_STATUS_NOT_IMPLEMENTED
;
934 static NTSTATUS
pdb_ads_set_aliasinfo(struct pdb_methods
*m
,
936 struct acct_info
*info
)
938 return NT_STATUS_NOT_IMPLEMENTED
;
941 static NTSTATUS
pdb_ads_add_aliasmem(struct pdb_methods
*m
,
942 const DOM_SID
*alias
,
943 const DOM_SID
*member
)
945 return NT_STATUS_NOT_IMPLEMENTED
;
948 static NTSTATUS
pdb_ads_del_aliasmem(struct pdb_methods
*m
,
949 const DOM_SID
*alias
,
950 const DOM_SID
*member
)
952 return NT_STATUS_NOT_IMPLEMENTED
;
955 static NTSTATUS
pdb_ads_enum_aliasmem(struct pdb_methods
*m
,
956 const DOM_SID
*alias
, DOM_SID
**members
,
957 size_t *p_num_members
)
959 return NT_STATUS_NOT_IMPLEMENTED
;
962 static NTSTATUS
pdb_ads_enum_alias_memberships(struct pdb_methods
*m
,
964 const DOM_SID
*domain_sid
,
965 const DOM_SID
*members
,
967 uint32
**pp_alias_rids
,
968 size_t *p_num_alias_rids
)
970 return NT_STATUS_NOT_IMPLEMENTED
;
973 static NTSTATUS
pdb_ads_lookup_rids(struct pdb_methods
*m
,
974 const DOM_SID
*domain_sid
,
977 const char **pp_names
,
978 enum lsa_SidType
*attrs
)
980 return NT_STATUS_NOT_IMPLEMENTED
;
983 static NTSTATUS
pdb_ads_lookup_names(struct pdb_methods
*m
,
984 const DOM_SID
*domain_sid
,
986 const char **pp_names
,
988 enum lsa_SidType
*attrs
)
990 return NT_STATUS_NOT_IMPLEMENTED
;
993 static NTSTATUS
pdb_ads_get_account_policy(struct pdb_methods
*m
,
994 int policy_index
, uint32
*value
)
996 return account_policy_get(policy_index
, value
)
997 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1000 static NTSTATUS
pdb_ads_set_account_policy(struct pdb_methods
*m
,
1001 int policy_index
, uint32 value
)
1003 return account_policy_set(policy_index
, value
)
1004 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1007 static NTSTATUS
pdb_ads_get_seq_num(struct pdb_methods
*m
,
1010 return NT_STATUS_NOT_IMPLEMENTED
;
1013 struct pdb_ads_search_state
{
1014 uint32_t acct_flags
;
1015 struct samr_displayentry
*entries
;
1016 uint32_t num_entries
;
1021 static bool pdb_ads_next_entry(struct pdb_search
*search
,
1022 struct samr_displayentry
*entry
)
1024 struct pdb_ads_search_state
*state
= talloc_get_type_abort(
1025 search
->private_data
, struct pdb_ads_search_state
);
1027 if (state
->current
== state
->num_entries
) {
1031 entry
->idx
= state
->entries
[state
->current
].idx
;
1032 entry
->rid
= state
->entries
[state
->current
].rid
;
1033 entry
->acct_flags
= state
->entries
[state
->current
].acct_flags
;
1035 entry
->account_name
= talloc_strdup(
1036 search
, state
->entries
[state
->current
].account_name
);
1037 entry
->fullname
= talloc_strdup(
1038 search
, state
->entries
[state
->current
].fullname
);
1039 entry
->description
= talloc_strdup(
1040 search
, state
->entries
[state
->current
].description
);
1042 if ((entry
->account_name
== NULL
) || (entry
->fullname
== NULL
)
1043 || (entry
->description
== NULL
)) {
1044 DEBUG(0, ("talloc_strdup failed\n"));
1048 state
->current
+= 1;
1052 static void pdb_ads_search_end(struct pdb_search
*search
)
1054 struct pdb_ads_search_state
*state
= talloc_get_type_abort(
1055 search
->private_data
, struct pdb_ads_search_state
);
1059 static bool pdb_ads_search_filter(struct pdb_methods
*m
,
1060 struct pdb_search
*search
,
1062 struct pdb_ads_search_state
**pstate
)
1064 struct pdb_ads_state
*state
= talloc_get_type_abort(
1065 m
->private_data
, struct pdb_ads_state
);
1066 struct pdb_ads_search_state
*sstate
;
1067 const char * attrs
[] = { "objectSid", "sAMAccountName", "displayName",
1068 "userAccountControl", "description" };
1069 struct tldap_message
**users
;
1070 int i
, rc
, num_users
;
1072 sstate
= talloc_zero(search
, struct pdb_ads_search_state
);
1073 if (sstate
== NULL
) {
1077 rc
= tldap_search_fmt(
1078 state
->ld
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1079 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &users
,
1081 if (rc
!= TLDAP_SUCCESS
) {
1082 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1083 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1087 num_users
= talloc_array_length(users
);
1089 sstate
->entries
= talloc_array(sstate
, struct samr_displayentry
,
1091 if (sstate
->entries
== NULL
) {
1092 DEBUG(10, ("talloc failed\n"));
1096 sstate
->num_entries
= 0;
1098 for (i
=0; i
<num_users
; i
++) {
1099 struct samr_displayentry
*e
;
1102 e
= &sstate
->entries
[sstate
->num_entries
];
1104 e
->idx
= sstate
->num_entries
;
1105 if (!tldap_pull_binsid(users
[i
], "objectSid", &sid
)) {
1106 DEBUG(10, ("Could not pull sid\n"));
1109 sid_peek_rid(&sid
, &e
->rid
);
1110 e
->acct_flags
= ACB_NORMAL
;
1111 e
->account_name
= tldap_talloc_single_attribute(
1112 users
[i
], "samAccountName", sstate
->entries
);
1113 if (e
->account_name
== NULL
) {
1116 e
->fullname
= tldap_talloc_single_attribute(
1117 users
[i
], "displayName", sstate
->entries
);
1118 if (e
->fullname
== NULL
) {
1121 e
->description
= tldap_talloc_single_attribute(
1122 users
[i
], "description", sstate
->entries
);
1123 if (e
->description
== NULL
) {
1124 e
->description
= "";
1127 sstate
->num_entries
+= 1;
1128 if (sstate
->num_entries
>= num_users
) {
1133 search
->private_data
= sstate
;
1134 search
->next_entry
= pdb_ads_next_entry
;
1135 search
->search_end
= pdb_ads_search_end
;
1140 static bool pdb_ads_search_users(struct pdb_methods
*m
,
1141 struct pdb_search
*search
,
1144 struct pdb_ads_search_state
*sstate
;
1147 ret
= pdb_ads_search_filter(m
, search
, "(objectclass=user)", &sstate
);
1151 sstate
->acct_flags
= acct_flags
;
1155 static bool pdb_ads_search_groups(struct pdb_methods
*m
,
1156 struct pdb_search
*search
)
1158 struct pdb_ads_search_state
*sstate
;
1162 filter
= talloc_asprintf(talloc_tos(),
1163 "(&(grouptype=%d)(objectclass=group))",
1164 GTYPE_SECURITY_GLOBAL_GROUP
);
1165 if (filter
== NULL
) {
1168 ret
= pdb_ads_search_filter(m
, search
, filter
, &sstate
);
1169 TALLOC_FREE(filter
);
1173 sstate
->acct_flags
= 0;
1177 static bool pdb_ads_search_aliases(struct pdb_methods
*m
,
1178 struct pdb_search
*search
,
1181 struct pdb_ads_search_state
*sstate
;
1185 filter
= talloc_asprintf(
1186 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1187 sid_check_is_builtin(sid
)
1188 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1189 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1191 if (filter
== NULL
) {
1194 ret
= pdb_ads_search_filter(m
, search
, filter
, &sstate
);
1195 TALLOC_FREE(filter
);
1199 sstate
->acct_flags
= 0;
1203 static bool pdb_ads_uid_to_rid(struct pdb_methods
*m
, uid_t uid
,
1209 static bool pdb_ads_uid_to_sid(struct pdb_methods
*m
, uid_t uid
,
1212 struct pdb_ads_state
*state
= talloc_get_type_abort(
1213 m
->private_data
, struct pdb_ads_state
);
1214 sid_compose(sid
, &state
->domainsid
, uid
);
1218 static bool pdb_ads_gid_to_sid(struct pdb_methods
*m
, gid_t gid
,
1221 struct pdb_ads_state
*state
= talloc_get_type_abort(
1222 m
->private_data
, struct pdb_ads_state
);
1223 sid_compose(sid
, &state
->domainsid
, gid
);
1227 static bool pdb_ads_sid_to_id(struct pdb_methods
*m
, const DOM_SID
*sid
,
1228 union unid_t
*id
, enum lsa_SidType
*type
)
1230 struct pdb_ads_state
*state
= talloc_get_type_abort(
1231 m
->private_data
, struct pdb_ads_state
);
1232 struct tldap_message
**msg
;
1238 * This is a big, big hack: Just hard-code the rid as uid/gid.
1241 sid_peek_rid(sid
, &rid
);
1243 sidstr
= sid_binstring(talloc_tos(), sid
);
1244 if (sidstr
== NULL
) {
1248 rc
= tldap_search_fmt(
1249 state
->ld
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1250 NULL
, 0, 0, talloc_tos(), &msg
,
1251 "(&(objectsid=%s)(objectclass=user))", sidstr
);
1252 if ((rc
== TLDAP_SUCCESS
) && (talloc_array_length(msg
) > 0)) {
1254 *type
= SID_NAME_USER
;
1255 TALLOC_FREE(sidstr
);
1259 rc
= tldap_search_fmt(
1260 state
->ld
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1261 NULL
, 0, 0, talloc_tos(), &msg
,
1262 "(&(objectsid=%s)(objectclass=group))", sidstr
);
1263 if ((rc
== TLDAP_SUCCESS
) && (talloc_array_length(msg
) > 0)) {
1265 *type
= SID_NAME_DOM_GRP
;
1266 TALLOC_FREE(sidstr
);
1270 TALLOC_FREE(sidstr
);
1274 static bool pdb_ads_rid_algorithm(struct pdb_methods
*m
)
1279 static bool pdb_ads_new_rid(struct pdb_methods
*m
, uint32
*rid
)
1284 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods
*m
,
1285 const char *domain
, char** pwd
,
1287 time_t *pass_last_set_time
)
1292 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods
*m
,
1293 const char* domain
, const char* pwd
,
1299 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods
*m
,
1305 static NTSTATUS
pdb_ads_enum_trusteddoms(struct pdb_methods
*m
,
1306 TALLOC_CTX
*mem_ctx
,
1307 uint32
*num_domains
,
1308 struct trustdom_info
***domains
)
1310 return NT_STATUS_NOT_IMPLEMENTED
;
1313 static void pdb_ads_init_methods(struct pdb_methods
*m
)
1316 m
->getsampwnam
= pdb_ads_getsampwnam
;
1317 m
->getsampwsid
= pdb_ads_getsampwsid
;
1318 m
->create_user
= pdb_ads_create_user
;
1319 m
->delete_user
= pdb_ads_delete_user
;
1320 m
->add_sam_account
= pdb_ads_add_sam_account
;
1321 m
->update_sam_account
= pdb_ads_update_sam_account
;
1322 m
->delete_sam_account
= pdb_ads_delete_sam_account
;
1323 m
->rename_sam_account
= pdb_ads_rename_sam_account
;
1324 m
->update_login_attempts
= pdb_ads_update_login_attempts
;
1325 m
->getgrsid
= pdb_ads_getgrsid
;
1326 m
->getgrgid
= pdb_ads_getgrgid
;
1327 m
->getgrnam
= pdb_ads_getgrnam
;
1328 m
->create_dom_group
= pdb_ads_create_dom_group
;
1329 m
->delete_dom_group
= pdb_ads_delete_dom_group
;
1330 m
->add_group_mapping_entry
= pdb_ads_add_group_mapping_entry
;
1331 m
->update_group_mapping_entry
= pdb_ads_update_group_mapping_entry
;
1332 m
->delete_group_mapping_entry
= pdb_ads_delete_group_mapping_entry
;
1333 m
->enum_group_mapping
= pdb_ads_enum_group_mapping
;
1334 m
->enum_group_members
= pdb_ads_enum_group_members
;
1335 m
->enum_group_memberships
= pdb_ads_enum_group_memberships
;
1336 m
->set_unix_primary_group
= pdb_ads_set_unix_primary_group
;
1337 m
->add_groupmem
= pdb_ads_add_groupmem
;
1338 m
->del_groupmem
= pdb_ads_del_groupmem
;
1339 m
->create_alias
= pdb_ads_create_alias
;
1340 m
->delete_alias
= pdb_ads_delete_alias
;
1341 m
->get_aliasinfo
= pdb_ads_get_aliasinfo
;
1342 m
->set_aliasinfo
= pdb_ads_set_aliasinfo
;
1343 m
->add_aliasmem
= pdb_ads_add_aliasmem
;
1344 m
->del_aliasmem
= pdb_ads_del_aliasmem
;
1345 m
->enum_aliasmem
= pdb_ads_enum_aliasmem
;
1346 m
->enum_alias_memberships
= pdb_ads_enum_alias_memberships
;
1347 m
->lookup_rids
= pdb_ads_lookup_rids
;
1348 m
->lookup_names
= pdb_ads_lookup_names
;
1349 m
->get_account_policy
= pdb_ads_get_account_policy
;
1350 m
->set_account_policy
= pdb_ads_set_account_policy
;
1351 m
->get_seq_num
= pdb_ads_get_seq_num
;
1352 m
->search_users
= pdb_ads_search_users
;
1353 m
->search_groups
= pdb_ads_search_groups
;
1354 m
->search_aliases
= pdb_ads_search_aliases
;
1355 m
->uid_to_rid
= pdb_ads_uid_to_rid
;
1356 m
->uid_to_sid
= pdb_ads_uid_to_sid
;
1357 m
->gid_to_sid
= pdb_ads_gid_to_sid
;
1358 m
->sid_to_id
= pdb_ads_sid_to_id
;
1359 m
->rid_algorithm
= pdb_ads_rid_algorithm
;
1360 m
->new_rid
= pdb_ads_new_rid
;
1361 m
->get_trusteddom_pw
= pdb_ads_get_trusteddom_pw
;
1362 m
->set_trusteddom_pw
= pdb_ads_set_trusteddom_pw
;
1363 m
->del_trusteddom_pw
= pdb_ads_del_trusteddom_pw
;
1364 m
->enum_trusteddoms
= pdb_ads_enum_trusteddoms
;
1367 static void free_private_data(void **vp
)
1369 struct pdb_ads_state
*state
= talloc_get_type_abort(
1370 *vp
, struct pdb_ads_state
);
1372 TALLOC_FREE(state
->ld
);
1376 static NTSTATUS
pdb_ads_connect(struct pdb_ads_state
*state
,
1377 const char *location
)
1379 const char *rootdse_attrs
[2] = {
1380 "defaultNamingContext", "configurationNamingContext" };
1381 const char *domain_attrs
[1] = { "objectSid" };
1382 const char *ncname_attrs
[1] = { "netbiosname" };
1383 struct tldap_message
**rootdse
, **domain
, **ncname
;
1384 TALLOC_CTX
*frame
= talloc_stackframe();
1385 struct sockaddr_un sunaddr
;
1390 ZERO_STRUCT(sunaddr
);
1391 sunaddr
.sun_family
= AF_UNIX
;
1392 strncpy(sunaddr
.sun_path
, location
, sizeof(sunaddr
.sun_path
) - 1);
1394 status
= open_socket_out((struct sockaddr_storage
*)(void *)&sunaddr
,
1396 if (!NT_STATUS_IS_OK(status
)) {
1397 DEBUG(10, ("Could not connect to %s: %s\n", location
,
1398 nt_errstr(status
)));
1402 state
->ld
= tldap_context_create(state
, fd
);
1403 if (state
->ld
== NULL
) {
1405 status
= NT_STATUS_NO_MEMORY
;
1409 rc
= tldap_search_fmt(
1410 state
->ld
, "", TLDAP_SCOPE_BASE
,
1411 rootdse_attrs
, ARRAY_SIZE(rootdse_attrs
), 0,
1412 talloc_tos(), &rootdse
, "(objectclass=*)");
1413 if (rc
!= TLDAP_SUCCESS
) {
1414 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1415 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1416 status
= NT_STATUS_LDAP(rc
);
1419 if (talloc_array_length(rootdse
) != 1) {
1420 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
1424 state
->domaindn
= tldap_talloc_single_attribute(
1425 rootdse
[0], "defaultNamingContext", state
);
1426 if (state
->domaindn
== NULL
) {
1427 DEBUG(10, ("Could not get defaultNamingContext\n"));
1428 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
1431 DEBUG(10, ("defaultNamingContext = %s\n", state
->domaindn
));
1433 state
->configdn
= tldap_talloc_single_attribute(
1434 rootdse
[0], "configurationNamingContext", state
);
1435 if (state
->domaindn
== NULL
) {
1436 DEBUG(10, ("Could not get configurationNamingContext\n"));
1437 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
1440 DEBUG(10, ("configurationNamingContext = %s\n", state
->configdn
));
1443 * Figure out our domain's SID
1445 rc
= tldap_search_fmt(
1446 state
->ld
, state
->domaindn
, TLDAP_SCOPE_BASE
,
1447 domain_attrs
, ARRAY_SIZE(domain_attrs
), 0,
1448 talloc_tos(), &domain
, "(objectclass=*)");
1449 if (rc
!= TLDAP_SUCCESS
) {
1450 DEBUG(10, ("Could not retrieve domain: %s\n",
1451 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1452 status
= NT_STATUS_LDAP(rc
);
1456 num_domains
= talloc_array_length(domain
);
1457 if (num_domains
!= 1) {
1458 DEBUG(10, ("Got %d domains, expected one\n", num_domains
));
1459 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
1462 if (!tldap_pull_binsid(domain
[0], "objectSid", &state
->domainsid
)) {
1463 DEBUG(10, ("Could not retrieve domain SID\n"));
1464 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
1467 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state
->domainsid
)));
1470 * Figure out our domain's short name
1472 rc
= tldap_search_fmt(
1473 state
->ld
, state
->configdn
, TLDAP_SCOPE_SUB
,
1474 ncname_attrs
, ARRAY_SIZE(ncname_attrs
), 0,
1475 talloc_tos(), &ncname
, "(ncname=%s)", state
->domaindn
);
1476 if (rc
!= TLDAP_SUCCESS
) {
1477 DEBUG(10, ("Could not retrieve ncname: %s\n",
1478 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1479 status
= NT_STATUS_LDAP(rc
);
1482 if (talloc_array_length(ncname
) != 1) {
1483 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
1487 state
->netbiosname
= tldap_talloc_single_attribute(
1488 ncname
[0], "netbiosname", state
);
1489 if (state
->netbiosname
== NULL
) {
1490 DEBUG(10, ("Could not get netbiosname\n"));
1491 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
1494 DEBUG(10, ("netbiosname: %s\n", state
->netbiosname
));
1496 if (!strequal(lp_workgroup(), state
->netbiosname
)) {
1497 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1498 state
->netbiosname
, lp_workgroup()));
1499 status
= NT_STATUS_NO_SUCH_DOMAIN
;
1503 secrets_store_domain_sid(state
->netbiosname
, &state
->domainsid
);
1505 status
= NT_STATUS_OK
;
1511 static NTSTATUS
pdb_init_ads(struct pdb_methods
**pdb_method
,
1512 const char *location
)
1514 struct pdb_methods
*m
;
1515 struct pdb_ads_state
*state
;
1519 m
= talloc(talloc_autofree_context(), struct pdb_methods
);
1521 return NT_STATUS_NO_MEMORY
;
1523 state
= talloc(m
, struct pdb_ads_state
);
1524 if (state
== NULL
) {
1527 m
->private_data
= state
;
1528 m
->free_private_data
= free_private_data
;
1529 pdb_ads_init_methods(m
);
1531 if (location
== NULL
) {
1532 tmp
= talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1536 if (location
== NULL
) {
1540 status
= pdb_ads_connect(state
, location
);
1541 if (!NT_STATUS_IS_OK(status
)) {
1542 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status
)));
1547 return NT_STATUS_OK
;
1549 status
= NT_STATUS_NO_MEMORY
;
1555 NTSTATUS
pdb_ads_init(void);
1556 NTSTATUS
pdb_ads_init(void)
1558 return smb_register_passdb(PASSDB_INTERFACE_VERSION
, "ads",