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 sockaddr_un socket_address
;
24 struct tldap_context
*ld
;
25 struct dom_sid domainsid
;
26 struct GUID domainguid
;
32 struct pdb_ads_samu_private
{
34 struct tldap_message
*ldapmsg
;
37 static NTSTATUS
pdb_ads_getsampwsid(struct pdb_methods
*m
,
38 struct samu
*sam_acct
,
40 static bool pdb_ads_gid_to_sid(struct pdb_methods
*m
, gid_t gid
,
42 static bool pdb_ads_dnblob2sid(struct pdb_ads_state
*state
, DATA_BLOB
*dnblob
,
43 struct dom_sid
*psid
);
44 static NTSTATUS
pdb_ads_sid2dn(struct pdb_ads_state
*state
,
45 const struct dom_sid
*sid
,
46 TALLOC_CTX
*mem_ctx
, char **pdn
);
47 static struct tldap_context
*pdb_ads_ld(struct pdb_ads_state
*state
);
48 static int pdb_ads_search_fmt(struct pdb_ads_state
*state
, const char *base
,
49 int scope
, const char *attrs
[], int num_attrs
,
51 TALLOC_CTX
*mem_ctx
, struct tldap_message
***res
,
52 const char *fmt
, ...);
53 static NTSTATUS
pdb_ads_getsamupriv(struct pdb_ads_state
*state
,
56 struct pdb_ads_samu_private
**presult
);
58 static bool pdb_ads_pull_time(struct tldap_message
*msg
, const char *attr
,
63 if (!tldap_pull_uint64(msg
, attr
, &tmp
)) {
66 *ptime
= uint64s_nt_time_to_unix_abs(&tmp
);
70 static gid_t
pdb_ads_sid2gid(const struct dom_sid
*sid
)
73 sid_peek_rid(sid
, &rid
);
77 static char *pdb_ads_domaindn2dns(TALLOC_CTX
*mem_ctx
, char *dn
)
81 result
= talloc_string_sub2(mem_ctx
, dn
, "DC=", "", false, false,
87 while ((p
= strchr_m(result
, ',')) != NULL
) {
94 static struct pdb_domain_info
*pdb_ads_get_domain_info(
95 struct pdb_methods
*m
, TALLOC_CTX
*mem_ctx
)
97 struct pdb_ads_state
*state
= talloc_get_type_abort(
98 m
->private_data
, struct pdb_ads_state
);
99 struct pdb_domain_info
*info
;
100 struct tldap_message
*rootdse
;
103 info
= talloc(mem_ctx
, struct pdb_domain_info
);
107 info
->name
= talloc_strdup(info
, state
->netbiosname
);
108 if (info
->name
== NULL
) {
111 info
->dns_domain
= pdb_ads_domaindn2dns(info
, state
->domaindn
);
112 if (info
->dns_domain
== NULL
) {
116 rootdse
= tldap_rootdse(state
->ld
);
117 tmp
= tldap_talloc_single_attribute(rootdse
, "rootDomainNamingContext",
122 info
->dns_forest
= pdb_ads_domaindn2dns(info
, tmp
);
124 if (info
->dns_forest
== NULL
) {
127 info
->sid
= state
->domainsid
;
128 info
->guid
= state
->domainguid
;
136 static struct pdb_ads_samu_private
*pdb_ads_get_samu_private(
137 struct pdb_methods
*m
, struct samu
*sam
)
139 struct pdb_ads_state
*state
= talloc_get_type_abort(
140 m
->private_data
, struct pdb_ads_state
);
141 struct pdb_ads_samu_private
*result
;
142 char *sidstr
, *filter
;
145 result
= (struct pdb_ads_samu_private
*)
146 pdb_get_backend_private_data(sam
, m
);
148 if (result
!= NULL
) {
149 return talloc_get_type_abort(
150 result
, struct pdb_ads_samu_private
);
153 sidstr
= sid_binstring(talloc_tos(), pdb_get_user_sid(sam
));
154 if (sidstr
== NULL
) {
158 filter
= talloc_asprintf(
159 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr
);
161 if (filter
== NULL
) {
165 status
= pdb_ads_getsamupriv(state
, filter
, sam
, &result
);
167 if (!NT_STATUS_IS_OK(status
)) {
174 static NTSTATUS
pdb_ads_init_sam_from_priv(struct pdb_methods
*m
,
176 struct pdb_ads_samu_private
*priv
)
178 struct pdb_ads_state
*state
= talloc_get_type_abort(
179 m
->private_data
, struct pdb_ads_state
);
180 TALLOC_CTX
*frame
= talloc_stackframe();
181 NTSTATUS status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
182 struct tldap_message
*entry
= priv
->ldapmsg
;
189 str
= tldap_talloc_single_attribute(entry
, "samAccountName", sam
);
191 DEBUG(10, ("no samAccountName\n"));
194 pdb_set_username(sam
, str
, PDB_SET
);
196 if (pdb_ads_pull_time(entry
, "lastLogon", &tmp_time
)) {
197 pdb_set_logon_time(sam
, tmp_time
, PDB_SET
);
199 if (pdb_ads_pull_time(entry
, "lastLogoff", &tmp_time
)) {
200 pdb_set_logoff_time(sam
, tmp_time
, PDB_SET
);
202 if (pdb_ads_pull_time(entry
, "pwdLastSet", &tmp_time
)) {
203 pdb_set_pass_last_set_time(sam
, tmp_time
, PDB_SET
);
205 if (pdb_ads_pull_time(entry
, "accountExpires", &tmp_time
)) {
206 pdb_set_kickoff_time(sam
, tmp_time
, PDB_SET
);
209 str
= tldap_talloc_single_attribute(entry
, "displayName",
212 pdb_set_fullname(sam
, str
, PDB_SET
);
215 str
= tldap_talloc_single_attribute(entry
, "homeDirectory",
218 pdb_set_homedir(sam
, str
, PDB_SET
);
221 str
= tldap_talloc_single_attribute(entry
, "homeDrive", talloc_tos());
223 pdb_set_dir_drive(sam
, str
, PDB_SET
);
226 str
= tldap_talloc_single_attribute(entry
, "scriptPath", talloc_tos());
228 pdb_set_logon_script(sam
, str
, PDB_SET
);
231 str
= tldap_talloc_single_attribute(entry
, "profilePath",
234 pdb_set_profile_path(sam
, str
, PDB_SET
);
237 str
= tldap_talloc_single_attribute(entry
, "profilePath",
240 pdb_set_profile_path(sam
, str
, PDB_SET
);
243 if (!tldap_pull_binsid(entry
, "objectSid", &sid
)) {
244 DEBUG(10, ("Could not pull SID\n"));
247 pdb_set_user_sid(sam
, &sid
, PDB_SET
);
249 if (!tldap_pull_uint64(entry
, "userAccountControl", &n
)) {
250 DEBUG(10, ("Could not pull userAccountControl\n"));
253 pdb_set_acct_ctrl(sam
, ds_uf2acb(n
), PDB_SET
);
255 if (tldap_get_single_valueblob(entry
, "unicodePwd", &blob
)) {
256 if (blob
.length
!= NT_HASH_LEN
) {
257 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
258 (int)blob
.length
, NT_HASH_LEN
));
261 pdb_set_nt_passwd(sam
, blob
.data
, PDB_SET
);
264 if (tldap_get_single_valueblob(entry
, "dBCSPwd", &blob
)) {
265 if (blob
.length
!= LM_HASH_LEN
) {
266 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
267 (int)blob
.length
, LM_HASH_LEN
));
270 pdb_set_lanman_passwd(sam
, blob
.data
, PDB_SET
);
273 if (tldap_pull_uint64(entry
, "primaryGroupID", &n
)) {
274 sid_compose(&sid
, &state
->domainsid
, n
);
275 pdb_set_group_sid(sam
, &sid
, PDB_SET
);
278 status
= NT_STATUS_OK
;
284 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state
*state
,
285 struct tldap_message
*existing
,
287 int *pnum_mods
, struct tldap_mod
**pmods
,
293 /* TODO: All fields :-) */
295 ret
&= tldap_make_mod_fmt(
296 existing
, mem_ctx
, pnum_mods
, pmods
, "displayName",
297 "%s", pdb_get_fullname(sam
));
299 blob
= data_blob_const(pdb_get_nt_passwd(sam
), NT_HASH_LEN
);
300 if (blob
.data
!= NULL
) {
301 ret
&= tldap_add_mod_blobs(mem_ctx
, pmods
, TLDAP_MOD_REPLACE
,
302 "unicodePwd", 1, &blob
);
305 blob
= data_blob_const(pdb_get_lanman_passwd(sam
), NT_HASH_LEN
);
306 if (blob
.data
!= NULL
) {
307 ret
&= tldap_add_mod_blobs(mem_ctx
, pmods
, TLDAP_MOD_REPLACE
,
308 "dBCSPwd", 1, &blob
);
311 ret
&= tldap_make_mod_fmt(
312 existing
, mem_ctx
, pnum_mods
, pmods
, "userAccountControl",
313 "%d", ds_acb2uf(pdb_get_acct_ctrl(sam
)));
315 ret
&= tldap_make_mod_fmt(
316 existing
, mem_ctx
, pnum_mods
, pmods
, "homeDirectory",
317 "%s", pdb_get_homedir(sam
));
319 ret
&= tldap_make_mod_fmt(
320 existing
, mem_ctx
, pnum_mods
, pmods
, "homeDrive",
321 "%s", pdb_get_dir_drive(sam
));
323 ret
&= tldap_make_mod_fmt(
324 existing
, mem_ctx
, pnum_mods
, pmods
, "scriptPath",
325 "%s", pdb_get_logon_script(sam
));
327 ret
&= tldap_make_mod_fmt(
328 existing
, mem_ctx
, pnum_mods
, pmods
, "profilePath",
329 "%s", pdb_get_profile_path(sam
));
334 static NTSTATUS
pdb_ads_getsamupriv(struct pdb_ads_state
*state
,
337 struct pdb_ads_samu_private
**presult
)
339 const char * attrs
[] = {
340 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
341 "sAMAccountName", "displayName", "homeDirectory",
342 "homeDrive", "scriptPath", "profilePath", "description",
343 "userWorkstations", "comment", "userParameters", "objectSid",
344 "primaryGroupID", "userAccountControl", "logonHours",
345 "badPwdCount", "logonCount", "countryCode", "codePage",
346 "unicodePwd", "dBCSPwd" };
347 struct tldap_message
**users
;
349 struct pdb_ads_samu_private
*result
;
351 result
= talloc(mem_ctx
, struct pdb_ads_samu_private
);
352 if (result
== NULL
) {
353 return NT_STATUS_NO_MEMORY
;
356 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
357 attrs
, ARRAY_SIZE(attrs
), 0, result
,
358 &users
, "%s", filter
);
359 if (rc
!= TLDAP_SUCCESS
) {
360 DEBUG(10, ("ldap_search failed %s\n",
361 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
363 return NT_STATUS_LDAP(rc
);
366 count
= talloc_array_length(users
);
368 DEBUG(10, ("Expected 1 user, got %d\n", count
));
370 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
373 result
->ldapmsg
= users
[0];
374 if (!tldap_entry_dn(result
->ldapmsg
, &result
->dn
)) {
375 DEBUG(10, ("Could not extract dn\n"));
377 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
384 static NTSTATUS
pdb_ads_getsampwfilter(struct pdb_methods
*m
,
385 struct pdb_ads_state
*state
,
386 struct samu
*sam_acct
,
389 struct pdb_ads_samu_private
*priv
;
392 status
= pdb_ads_getsamupriv(state
, filter
, sam_acct
, &priv
);
393 if (!NT_STATUS_IS_OK(status
)) {
394 DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n",
399 status
= pdb_ads_init_sam_from_priv(m
, sam_acct
, priv
);
400 if (!NT_STATUS_IS_OK(status
)) {
401 DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n",
407 pdb_set_backend_private_data(sam_acct
, priv
, NULL
, m
, PDB_SET
);
411 static NTSTATUS
pdb_ads_getsampwnam(struct pdb_methods
*m
,
412 struct samu
*sam_acct
,
413 const char *username
)
415 struct pdb_ads_state
*state
= talloc_get_type_abort(
416 m
->private_data
, struct pdb_ads_state
);
419 filter
= talloc_asprintf(
420 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
422 NT_STATUS_HAVE_NO_MEMORY(filter
);
424 return pdb_ads_getsampwfilter(m
, state
, sam_acct
, filter
);
427 static NTSTATUS
pdb_ads_getsampwsid(struct pdb_methods
*m
,
428 struct samu
*sam_acct
,
431 struct pdb_ads_state
*state
= talloc_get_type_abort(
432 m
->private_data
, struct pdb_ads_state
);
433 char *sidstr
, *filter
;
435 sidstr
= sid_binstring(talloc_tos(), sid
);
436 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
438 filter
= talloc_asprintf(
439 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr
);
441 NT_STATUS_HAVE_NO_MEMORY(filter
);
443 return pdb_ads_getsampwfilter(m
, state
, sam_acct
, filter
);
446 static NTSTATUS
pdb_ads_create_user(struct pdb_methods
*m
,
448 const char *name
, uint32 acct_flags
,
451 struct pdb_ads_state
*state
= talloc_get_type_abort(
452 m
->private_data
, struct pdb_ads_state
);
453 struct tldap_context
*ld
;
454 const char *attrs
[1] = { "objectSid" };
455 struct tldap_mod
*mods
= NULL
;
457 struct tldap_message
**user
;
463 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
466 return NT_STATUS_NO_MEMORY
;
469 ld
= pdb_ads_ld(state
);
471 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
474 /* TODO: Create machines etc */
477 ok
&= tldap_make_mod_fmt(
478 NULL
, talloc_tos(), &num_mods
, &mods
, "objectClass", "user");
479 ok
&= tldap_make_mod_fmt(
480 NULL
, talloc_tos(), &num_mods
, &mods
, "samAccountName", "%s",
483 return NT_STATUS_NO_MEMORY
;
487 rc
= tldap_add(ld
, dn
, num_mods
, mods
, NULL
, 0, NULL
, 0);
488 if (rc
!= TLDAP_SUCCESS
) {
489 DEBUG(10, ("ldap_add failed %s\n",
490 tldap_errstr(debug_ctx(), ld
, rc
)));
492 return NT_STATUS_LDAP(rc
);
495 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
496 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
498 "(&(objectclass=user)(samaccountname=%s))",
500 if (rc
!= TLDAP_SUCCESS
) {
501 DEBUG(10, ("Could not find just created user %s: %s\n",
502 name
, tldap_errstr(debug_ctx(), state
->ld
, rc
)));
504 return NT_STATUS_LDAP(rc
);
507 if (talloc_array_length(user
) != 1) {
508 DEBUG(10, ("Got %d users, expected one\n",
509 (int)talloc_array_length(user
)));
511 return NT_STATUS_LDAP(rc
);
514 if (!tldap_pull_binsid(user
[0], "objectSid", &sid
)) {
515 DEBUG(10, ("Could not fetch objectSid from user %s\n",
518 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
521 sid_peek_rid(&sid
, rid
);
526 static NTSTATUS
pdb_ads_delete_user(struct pdb_methods
*m
,
530 struct pdb_ads_state
*state
= talloc_get_type_abort(
531 m
->private_data
, struct pdb_ads_state
);
533 struct tldap_context
*ld
;
537 ld
= pdb_ads_ld(state
);
539 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
542 status
= pdb_ads_sid2dn(state
, pdb_get_user_sid(sam
), talloc_tos(),
544 if (!NT_STATUS_IS_OK(status
)) {
548 rc
= tldap_delete(ld
, dn
, NULL
, 0, NULL
, 0);
550 if (rc
!= TLDAP_SUCCESS
) {
551 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn
,
552 tldap_errstr(debug_ctx(), ld
, rc
)));
553 return NT_STATUS_LDAP(rc
);
558 static NTSTATUS
pdb_ads_add_sam_account(struct pdb_methods
*m
,
559 struct samu
*sampass
)
561 return NT_STATUS_NOT_IMPLEMENTED
;
564 static NTSTATUS
pdb_ads_update_sam_account(struct pdb_methods
*m
,
567 struct pdb_ads_state
*state
= talloc_get_type_abort(
568 m
->private_data
, struct pdb_ads_state
);
569 struct pdb_ads_samu_private
*priv
= pdb_ads_get_samu_private(m
, sam
);
570 struct tldap_context
*ld
;
571 struct tldap_mod
*mods
= NULL
;
572 int rc
, num_mods
= 0;
574 ld
= pdb_ads_ld(state
);
576 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
579 if (!pdb_ads_init_ads_from_sam(state
, priv
->ldapmsg
, talloc_tos(),
580 &num_mods
, &mods
, sam
)) {
581 return NT_STATUS_NO_MEMORY
;
585 /* Nothing to do, just return success */
589 rc
= tldap_modify(ld
, priv
->dn
, num_mods
, mods
, NULL
, 0,
592 if (rc
!= TLDAP_SUCCESS
) {
593 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv
->dn
,
594 tldap_errstr(debug_ctx(), ld
, rc
)));
595 return NT_STATUS_LDAP(rc
);
601 static NTSTATUS
pdb_ads_delete_sam_account(struct pdb_methods
*m
,
602 struct samu
*username
)
604 return NT_STATUS_NOT_IMPLEMENTED
;
607 static NTSTATUS
pdb_ads_rename_sam_account(struct pdb_methods
*m
,
608 struct samu
*oldname
,
611 return NT_STATUS_NOT_IMPLEMENTED
;
614 static NTSTATUS
pdb_ads_update_login_attempts(struct pdb_methods
*m
,
615 struct samu
*sam_acct
,
618 return NT_STATUS_NOT_IMPLEMENTED
;
621 static NTSTATUS
pdb_ads_getgrfilter(struct pdb_methods
*m
, GROUP_MAP
*map
,
624 struct pdb_ads_state
*state
= talloc_get_type_abort(
625 m
->private_data
, struct pdb_ads_state
);
626 const char *attrs
[4] = { "objectSid", "description", "samAccountName",
629 struct tldap_message
**group
;
633 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
634 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
635 &group
, "%s", filter
);
636 if (rc
!= TLDAP_SUCCESS
) {
637 DEBUG(10, ("ldap_search failed %s\n",
638 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
639 return NT_STATUS_LDAP(rc
);
641 if (talloc_array_length(group
) != 1) {
642 DEBUG(10, ("Expected 1 user, got %d\n",
643 (int)talloc_array_length(group
)));
644 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
647 if (!tldap_pull_binsid(group
[0], "objectSid", &map
->sid
)) {
648 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
650 map
->gid
= pdb_ads_sid2gid(&map
->sid
);
652 if (!tldap_pull_uint32(group
[0], "groupType", &grouptype
)) {
653 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
656 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
:
657 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
:
658 map
->sid_name_use
= SID_NAME_ALIAS
;
660 case GTYPE_SECURITY_GLOBAL_GROUP
:
661 map
->sid_name_use
= SID_NAME_DOM_GRP
;
664 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
667 str
= tldap_talloc_single_attribute(group
[0], "samAccountName",
670 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
672 fstrcpy(map
->nt_name
, str
);
675 str
= tldap_talloc_single_attribute(group
[0], "description",
678 fstrcpy(map
->comment
, str
);
681 map
->comment
[0] = '\0';
688 static NTSTATUS
pdb_ads_getgrsid(struct pdb_methods
*m
, GROUP_MAP
*map
,
694 filter
= talloc_asprintf(talloc_tos(),
695 "(&(objectsid=%s)(objectclass=group))",
696 sid_string_talloc(talloc_tos(), &sid
));
697 if (filter
== NULL
) {
698 return NT_STATUS_NO_MEMORY
;
701 status
= pdb_ads_getgrfilter(m
, map
, filter
);
706 static NTSTATUS
pdb_ads_getgrgid(struct pdb_methods
*m
, GROUP_MAP
*map
,
710 pdb_ads_gid_to_sid(m
, gid
, &sid
);
711 return pdb_ads_getgrsid(m
, map
, sid
);
714 static NTSTATUS
pdb_ads_getgrnam(struct pdb_methods
*m
, GROUP_MAP
*map
,
720 filter
= talloc_asprintf(talloc_tos(),
721 "(&(samaccountname=%s)(objectclass=group))",
723 if (filter
== NULL
) {
724 return NT_STATUS_NO_MEMORY
;
727 status
= pdb_ads_getgrfilter(m
, map
, filter
);
732 static NTSTATUS
pdb_ads_create_dom_group(struct pdb_methods
*m
,
733 TALLOC_CTX
*mem_ctx
, const char *name
,
736 TALLOC_CTX
*frame
= talloc_stackframe();
737 struct pdb_ads_state
*state
= talloc_get_type_abort(
738 m
->private_data
, struct pdb_ads_state
);
739 struct tldap_context
*ld
;
740 const char *attrs
[1] = { "objectSid" };
742 struct tldap_mod
*mods
= NULL
;
743 struct tldap_message
**alias
;
749 ld
= pdb_ads_ld(state
);
751 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
754 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
758 return NT_STATUS_NO_MEMORY
;
761 ok
&= tldap_make_mod_fmt(
762 NULL
, talloc_tos(), &num_mods
, &mods
, "samAccountName", "%s",
764 ok
&= tldap_make_mod_fmt(
765 NULL
, talloc_tos(), &num_mods
, &mods
, "objectClass", "group");
766 ok
&= tldap_make_mod_fmt(
767 NULL
, talloc_tos(), &num_mods
, &mods
, "groupType",
768 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP
);
772 return NT_STATUS_NO_MEMORY
;
775 rc
= tldap_add(ld
, dn
, num_mods
, mods
, NULL
, 0, NULL
, 0);
776 if (rc
!= TLDAP_SUCCESS
) {
777 DEBUG(10, ("ldap_add failed %s\n",
778 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
780 return NT_STATUS_LDAP(rc
);
783 rc
= pdb_ads_search_fmt(
784 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
785 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &alias
,
786 "(&(objectclass=group)(samaccountname=%s))", name
);
787 if (rc
!= TLDAP_SUCCESS
) {
788 DEBUG(10, ("Could not find just created alias %s: %s\n",
789 name
, tldap_errstr(debug_ctx(), state
->ld
, rc
)));
791 return NT_STATUS_LDAP(rc
);
794 if (talloc_array_length(alias
) != 1) {
795 DEBUG(10, ("Got %d alias, expected one\n",
796 (int)talloc_array_length(alias
)));
798 return NT_STATUS_LDAP(rc
);
801 if (!tldap_pull_binsid(alias
[0], "objectSid", &sid
)) {
802 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
805 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
808 sid_peek_rid(&sid
, rid
);
813 static NTSTATUS
pdb_ads_delete_dom_group(struct pdb_methods
*m
,
814 TALLOC_CTX
*mem_ctx
, uint32 rid
)
816 struct pdb_ads_state
*state
= talloc_get_type_abort(
817 m
->private_data
, struct pdb_ads_state
);
818 struct tldap_context
*ld
;
821 struct tldap_message
**msg
;
825 sid_compose(&sid
, &state
->domainsid
, rid
);
827 sidstr
= sid_binstring(talloc_tos(), &sid
);
828 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
830 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
831 NULL
, 0, 0, talloc_tos(), &msg
,
832 ("(&(objectSid=%s)(objectClass=group))"),
835 if (rc
!= TLDAP_SUCCESS
) {
836 DEBUG(10, ("ldap_search failed %s\n",
837 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
838 return NT_STATUS_LDAP(rc
);
841 switch talloc_array_length(msg
) {
843 return NT_STATUS_NO_SUCH_GROUP
;
847 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
850 if (!tldap_entry_dn(msg
[0], &dn
)) {
852 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
855 ld
= pdb_ads_ld(state
);
858 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
861 rc
= tldap_delete(ld
, dn
, NULL
, 0, NULL
, 0);
863 if (rc
!= TLDAP_SUCCESS
) {
864 DEBUG(10, ("ldap_delete failed: %s\n",
865 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
866 return NT_STATUS_LDAP(rc
);
872 static NTSTATUS
pdb_ads_add_group_mapping_entry(struct pdb_methods
*m
,
875 return NT_STATUS_NOT_IMPLEMENTED
;
878 static NTSTATUS
pdb_ads_update_group_mapping_entry(struct pdb_methods
*m
,
881 return NT_STATUS_NOT_IMPLEMENTED
;
884 static NTSTATUS
pdb_ads_delete_group_mapping_entry(struct pdb_methods
*m
,
887 return NT_STATUS_NOT_IMPLEMENTED
;
890 static NTSTATUS
pdb_ads_enum_group_mapping(struct pdb_methods
*m
,
892 enum lsa_SidType sid_name_use
,
894 size_t *p_num_entries
,
897 return NT_STATUS_NOT_IMPLEMENTED
;
900 static NTSTATUS
pdb_ads_enum_group_members(struct pdb_methods
*m
,
902 const DOM_SID
*group
,
904 size_t *pnum_members
)
906 struct pdb_ads_state
*state
= talloc_get_type_abort(
907 m
->private_data
, struct pdb_ads_state
);
908 const char *attrs
[1] = { "member" };
910 struct tldap_message
**msg
;
911 int i
, rc
, num_members
;
915 sidstr
= sid_binstring(talloc_tos(), group
);
916 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
918 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
919 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
920 &msg
, "(objectsid=%s)", sidstr
);
922 if (rc
!= TLDAP_SUCCESS
) {
923 DEBUG(10, ("ldap_search failed %s\n",
924 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
925 return NT_STATUS_LDAP(rc
);
927 switch talloc_array_length(msg
) {
929 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
934 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
938 if (!tldap_entry_values(msg
[0], "member", &num_members
, &blobs
)) {
939 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
942 members
= talloc_array(mem_ctx
, uint32_t, num_members
);
943 if (members
== NULL
) {
944 return NT_STATUS_NO_MEMORY
;
947 for (i
=0; i
<num_members
; i
++) {
949 if (!pdb_ads_dnblob2sid(state
, &blobs
[i
], &sid
)
950 || !sid_peek_rid(&sid
, &members
[i
])) {
951 TALLOC_FREE(members
);
952 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
957 *pnum_members
= num_members
;
961 static NTSTATUS
pdb_ads_enum_group_memberships(struct pdb_methods
*m
,
966 size_t *p_num_groups
)
968 struct pdb_ads_state
*state
= talloc_get_type_abort(
969 m
->private_data
, struct pdb_ads_state
);
970 struct pdb_ads_samu_private
*priv
= pdb_ads_get_samu_private(
972 const char *attrs
[1] = { "objectSid" };
973 struct tldap_message
**groups
;
976 struct dom_sid
*group_sids
;
979 rc
= pdb_ads_search_fmt(
980 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
981 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &groups
,
982 "(&(member=%s)(grouptype=%d)(objectclass=group))",
983 priv
->dn
, GTYPE_SECURITY_GLOBAL_GROUP
);
984 if (rc
!= TLDAP_SUCCESS
) {
985 DEBUG(10, ("ldap_search failed %s\n",
986 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
987 return NT_STATUS_LDAP(rc
);
990 count
= talloc_array_length(groups
);
992 group_sids
= talloc_array(mem_ctx
, struct dom_sid
, count
);
993 if (group_sids
== NULL
) {
994 return NT_STATUS_NO_MEMORY
;
996 gids
= talloc_array(mem_ctx
, gid_t
, count
);
998 TALLOC_FREE(group_sids
);
999 return NT_STATUS_NO_MEMORY
;
1003 for (i
=0; i
<count
; i
++) {
1004 if (!tldap_pull_binsid(groups
[i
], "objectSid",
1005 &group_sids
[num_groups
])) {
1008 gids
[num_groups
] = pdb_ads_sid2gid(&group_sids
[num_groups
]);
1011 if (num_groups
== count
) {
1016 *pp_sids
= group_sids
;
1018 *p_num_groups
= num_groups
;
1019 return NT_STATUS_OK
;
1022 static NTSTATUS
pdb_ads_set_unix_primary_group(struct pdb_methods
*m
,
1023 TALLOC_CTX
*mem_ctx
,
1026 return NT_STATUS_NOT_IMPLEMENTED
;
1029 static NTSTATUS
pdb_ads_mod_groupmem(struct pdb_methods
*m
,
1030 TALLOC_CTX
*mem_ctx
,
1031 uint32 grouprid
, uint32 memberrid
,
1034 struct pdb_ads_state
*state
= talloc_get_type_abort(
1035 m
->private_data
, struct pdb_ads_state
);
1036 TALLOC_CTX
*frame
= talloc_stackframe();
1037 struct tldap_context
*ld
;
1038 struct dom_sid groupsid
, membersid
;
1039 char *groupdn
, *memberdn
;
1040 struct tldap_mod
*mods
;
1044 ld
= pdb_ads_ld(state
);
1046 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1049 sid_compose(&groupsid
, &state
->domainsid
, grouprid
);
1050 sid_compose(&membersid
, &state
->domainsid
, memberrid
);
1052 status
= pdb_ads_sid2dn(state
, &groupsid
, talloc_tos(), &groupdn
);
1053 if (!NT_STATUS_IS_OK(status
)) {
1055 return NT_STATUS_NO_SUCH_GROUP
;
1057 status
= pdb_ads_sid2dn(state
, &membersid
, talloc_tos(), &memberdn
);
1058 if (!NT_STATUS_IS_OK(status
)) {
1060 return NT_STATUS_NO_SUCH_USER
;
1065 if (!tldap_add_mod_str(talloc_tos(), &mods
, mod_op
,
1066 "member", memberdn
)) {
1068 return NT_STATUS_NO_MEMORY
;
1071 rc
= tldap_modify(ld
, groupdn
, 1, mods
, NULL
, 0, NULL
, 0);
1073 if (rc
!= TLDAP_SUCCESS
) {
1074 DEBUG(10, ("ldap_modify failed: %s\n",
1075 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1076 if (rc
== TLDAP_TYPE_OR_VALUE_EXISTS
) {
1077 return NT_STATUS_MEMBER_IN_GROUP
;
1079 if (rc
== TLDAP_NO_SUCH_ATTRIBUTE
) {
1080 return NT_STATUS_MEMBER_NOT_IN_GROUP
;
1082 return NT_STATUS_LDAP(rc
);
1085 return NT_STATUS_OK
;
1088 static NTSTATUS
pdb_ads_add_groupmem(struct pdb_methods
*m
,
1089 TALLOC_CTX
*mem_ctx
,
1090 uint32 group_rid
, uint32 member_rid
)
1092 return pdb_ads_mod_groupmem(m
, mem_ctx
, group_rid
, member_rid
,
1096 static NTSTATUS
pdb_ads_del_groupmem(struct pdb_methods
*m
,
1097 TALLOC_CTX
*mem_ctx
,
1098 uint32 group_rid
, uint32 member_rid
)
1100 return pdb_ads_mod_groupmem(m
, mem_ctx
, group_rid
, member_rid
,
1104 static NTSTATUS
pdb_ads_create_alias(struct pdb_methods
*m
,
1105 const char *name
, uint32
*rid
)
1107 TALLOC_CTX
*frame
= talloc_stackframe();
1108 struct pdb_ads_state
*state
= talloc_get_type_abort(
1109 m
->private_data
, struct pdb_ads_state
);
1110 struct tldap_context
*ld
;
1111 const char *attrs
[1] = { "objectSid" };
1113 struct tldap_mod
*mods
= NULL
;
1114 struct tldap_message
**alias
;
1120 ld
= pdb_ads_ld(state
);
1122 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1125 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
1129 return NT_STATUS_NO_MEMORY
;
1132 ok
&= tldap_make_mod_fmt(
1133 NULL
, talloc_tos(), &num_mods
, &mods
, "samAccountName", "%s",
1135 ok
&= tldap_make_mod_fmt(
1136 NULL
, talloc_tos(), &num_mods
, &mods
, "objectClass", "group");
1137 ok
&= tldap_make_mod_fmt(
1138 NULL
, talloc_tos(), &num_mods
, &mods
, "groupType",
1139 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1143 return NT_STATUS_NO_MEMORY
;
1146 rc
= tldap_add(ld
, dn
, num_mods
, mods
, NULL
, 0, NULL
, 0);
1147 if (rc
!= TLDAP_SUCCESS
) {
1148 DEBUG(10, ("ldap_add failed %s\n",
1149 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1151 return NT_STATUS_LDAP(rc
);
1154 rc
= pdb_ads_search_fmt(
1155 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1156 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &alias
,
1157 "(&(objectclass=group)(samaccountname=%s))", name
);
1158 if (rc
!= TLDAP_SUCCESS
) {
1159 DEBUG(10, ("Could not find just created alias %s: %s\n",
1160 name
, tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1162 return NT_STATUS_LDAP(rc
);
1165 if (talloc_array_length(alias
) != 1) {
1166 DEBUG(10, ("Got %d alias, expected one\n",
1167 (int)talloc_array_length(alias
)));
1169 return NT_STATUS_LDAP(rc
);
1172 if (!tldap_pull_binsid(alias
[0], "objectSid", &sid
)) {
1173 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1176 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1179 sid_peek_rid(&sid
, rid
);
1181 return NT_STATUS_OK
;
1184 static NTSTATUS
pdb_ads_delete_alias(struct pdb_methods
*m
,
1187 struct pdb_ads_state
*state
= talloc_get_type_abort(
1188 m
->private_data
, struct pdb_ads_state
);
1189 struct tldap_context
*ld
;
1190 struct tldap_message
**alias
;
1194 ld
= pdb_ads_ld(state
);
1196 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1199 sidstr
= sid_binstring(talloc_tos(), sid
);
1200 if (sidstr
== NULL
) {
1201 return NT_STATUS_NO_MEMORY
;
1204 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1205 NULL
, 0, 0, talloc_tos(), &alias
,
1206 "(&(objectSid=%s)(objectclass=group)"
1207 "(|(grouptype=%d)(grouptype=%d)))",
1208 sidstr
, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1209 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1210 TALLOC_FREE(sidstr
);
1211 if (rc
!= TLDAP_SUCCESS
) {
1212 DEBUG(10, ("ldap_search failed: %s\n",
1213 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1215 return NT_STATUS_LDAP(rc
);
1217 if (talloc_array_length(alias
) != 1) {
1218 DEBUG(10, ("Expected 1 alias, got %d\n",
1219 (int)talloc_array_length(alias
)));
1220 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1222 if (!tldap_entry_dn(alias
[0], &dn
)) {
1223 DEBUG(10, ("Could not get DN for alias %s\n",
1224 sid_string_dbg(sid
)));
1225 return NT_STATUS_INTERNAL_ERROR
;
1228 rc
= tldap_delete(ld
, dn
, NULL
, 0, NULL
, 0);
1229 if (rc
!= TLDAP_SUCCESS
) {
1230 DEBUG(10, ("ldap_delete failed: %s\n",
1231 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1233 return NT_STATUS_LDAP(rc
);
1236 return NT_STATUS_OK
;
1239 static NTSTATUS
pdb_ads_set_aliasinfo(struct pdb_methods
*m
,
1241 struct acct_info
*info
)
1243 struct pdb_ads_state
*state
= talloc_get_type_abort(
1244 m
->private_data
, struct pdb_ads_state
);
1245 struct tldap_context
*ld
;
1246 const char *attrs
[3] = { "objectSid", "description",
1248 struct tldap_message
**msg
;
1251 struct tldap_mod
*mods
;
1255 ld
= pdb_ads_ld(state
);
1257 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1260 sidstr
= sid_binstring(talloc_tos(), sid
);
1261 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1263 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1264 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1265 &msg
, "(&(objectSid=%s)(objectclass=group)"
1266 "(|(grouptype=%d)(grouptype=%d)))",
1267 sidstr
, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1268 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1269 TALLOC_FREE(sidstr
);
1270 if (rc
!= TLDAP_SUCCESS
) {
1271 DEBUG(10, ("ldap_search failed %s\n",
1272 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1273 return NT_STATUS_LDAP(rc
);
1275 switch talloc_array_length(msg
) {
1277 return NT_STATUS_NO_SUCH_ALIAS
;
1281 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1284 if (!tldap_entry_dn(msg
[0], &dn
)) {
1286 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1293 ok
&= tldap_make_mod_fmt(
1294 msg
[0], msg
, &num_mods
, &mods
, "description",
1295 "%s", info
->acct_desc
);
1296 ok
&= tldap_make_mod_fmt(
1297 msg
[0], msg
, &num_mods
, &mods
, "samAccountName",
1298 "%s", info
->acct_name
);
1301 return NT_STATUS_NO_MEMORY
;
1303 if (num_mods
== 0) {
1306 return NT_STATUS_OK
;
1309 rc
= tldap_modify(ld
, dn
, num_mods
, mods
, NULL
, 0, NULL
, 0);
1311 if (rc
!= TLDAP_SUCCESS
) {
1312 DEBUG(10, ("ldap_modify failed: %s\n",
1313 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1314 return NT_STATUS_LDAP(rc
);
1316 return NT_STATUS_OK
;
1319 static NTSTATUS
pdb_ads_sid2dn(struct pdb_ads_state
*state
,
1320 const struct dom_sid
*sid
,
1321 TALLOC_CTX
*mem_ctx
, char **pdn
)
1323 struct tldap_message
**msg
;
1327 sidstr
= sid_binstring(talloc_tos(), sid
);
1328 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1330 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1331 NULL
, 0, 0, talloc_tos(), &msg
,
1332 "(objectsid=%s)", sidstr
);
1333 TALLOC_FREE(sidstr
);
1334 if (rc
!= TLDAP_SUCCESS
) {
1335 DEBUG(10, ("ldap_search failed %s\n",
1336 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1337 return NT_STATUS_LDAP(rc
);
1340 switch talloc_array_length(msg
) {
1342 return NT_STATUS_NOT_FOUND
;
1346 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1349 if (!tldap_entry_dn(msg
[0], &dn
)) {
1350 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1353 dn
= talloc_strdup(mem_ctx
, dn
);
1355 return NT_STATUS_NO_MEMORY
;
1360 return NT_STATUS_OK
;
1363 static NTSTATUS
pdb_ads_mod_aliasmem(struct pdb_methods
*m
,
1364 const DOM_SID
*alias
,
1365 const DOM_SID
*member
,
1368 struct pdb_ads_state
*state
= talloc_get_type_abort(
1369 m
->private_data
, struct pdb_ads_state
);
1370 struct tldap_context
*ld
;
1371 TALLOC_CTX
*frame
= talloc_stackframe();
1372 struct tldap_mod
*mods
;
1374 char *aliasdn
, *memberdn
;
1377 ld
= pdb_ads_ld(state
);
1379 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1382 status
= pdb_ads_sid2dn(state
, alias
, talloc_tos(), &aliasdn
);
1383 if (!NT_STATUS_IS_OK(status
)) {
1384 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1385 sid_string_dbg(alias
), nt_errstr(status
)));
1387 return NT_STATUS_NO_SUCH_ALIAS
;
1389 status
= pdb_ads_sid2dn(state
, member
, talloc_tos(), &memberdn
);
1390 if (!NT_STATUS_IS_OK(status
)) {
1391 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1392 sid_string_dbg(member
), nt_errstr(status
)));
1399 if (!tldap_add_mod_str(talloc_tos(), &mods
, mod_op
,
1400 "member", memberdn
)) {
1402 return NT_STATUS_NO_MEMORY
;
1405 rc
= tldap_modify(ld
, aliasdn
, 1, mods
, NULL
, 0, NULL
, 0);
1407 if (rc
!= TLDAP_SUCCESS
) {
1408 DEBUG(10, ("ldap_modify failed: %s\n",
1409 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1410 if (rc
== TLDAP_TYPE_OR_VALUE_EXISTS
) {
1411 return NT_STATUS_MEMBER_IN_ALIAS
;
1413 if (rc
== TLDAP_NO_SUCH_ATTRIBUTE
) {
1414 return NT_STATUS_MEMBER_NOT_IN_ALIAS
;
1416 return NT_STATUS_LDAP(rc
);
1419 return NT_STATUS_OK
;
1422 static NTSTATUS
pdb_ads_add_aliasmem(struct pdb_methods
*m
,
1423 const DOM_SID
*alias
,
1424 const DOM_SID
*member
)
1426 return pdb_ads_mod_aliasmem(m
, alias
, member
, TLDAP_MOD_ADD
);
1429 static NTSTATUS
pdb_ads_del_aliasmem(struct pdb_methods
*m
,
1430 const DOM_SID
*alias
,
1431 const DOM_SID
*member
)
1433 return pdb_ads_mod_aliasmem(m
, alias
, member
, TLDAP_MOD_DELETE
);
1436 static bool pdb_ads_dnblob2sid(struct pdb_ads_state
*state
, DATA_BLOB
*dnblob
,
1437 struct dom_sid
*psid
)
1439 const char *attrs
[1] = { "objectSid" };
1440 struct tldap_message
**msg
;
1446 if (!convert_string_talloc(talloc_tos(), CH_UTF8
, CH_UNIX
,
1447 dnblob
->data
, dnblob
->length
, &dn
, &len
,
1451 rc
= pdb_ads_search_fmt(state
, dn
, TLDAP_SCOPE_BASE
,
1452 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1453 &msg
, "(objectclass=*)");
1455 if (talloc_array_length(msg
) != 1) {
1456 DEBUG(10, ("Got %d objects, expected one\n",
1457 (int)talloc_array_length(msg
)));
1462 ret
= tldap_pull_binsid(msg
[0], "objectSid", psid
);
1467 static NTSTATUS
pdb_ads_enum_aliasmem(struct pdb_methods
*m
,
1468 const DOM_SID
*alias
,
1469 TALLOC_CTX
*mem_ctx
,
1471 size_t *pnum_members
)
1473 struct pdb_ads_state
*state
= talloc_get_type_abort(
1474 m
->private_data
, struct pdb_ads_state
);
1475 const char *attrs
[1] = { "member" };
1477 struct tldap_message
**msg
;
1478 int i
, rc
, num_members
;
1480 struct dom_sid
*members
;
1482 sidstr
= sid_binstring(talloc_tos(), alias
);
1483 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1485 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1486 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1487 &msg
, "(objectsid=%s)", sidstr
);
1488 TALLOC_FREE(sidstr
);
1489 if (rc
!= TLDAP_SUCCESS
) {
1490 DEBUG(10, ("ldap_search failed %s\n",
1491 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1492 return NT_STATUS_LDAP(rc
);
1494 switch talloc_array_length(msg
) {
1496 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1501 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1505 if (!tldap_entry_values(msg
[0], "member", &num_members
, &blobs
)) {
1506 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1509 members
= talloc_array(mem_ctx
, struct dom_sid
, num_members
);
1510 if (members
== NULL
) {
1511 return NT_STATUS_NO_MEMORY
;
1514 for (i
=0; i
<num_members
; i
++) {
1515 if (!pdb_ads_dnblob2sid(state
, &blobs
[i
], &members
[i
])) {
1516 TALLOC_FREE(members
);
1517 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1521 *pmembers
= members
;
1522 *pnum_members
= num_members
;
1523 return NT_STATUS_OK
;
1526 static NTSTATUS
pdb_ads_enum_alias_memberships(struct pdb_methods
*m
,
1527 TALLOC_CTX
*mem_ctx
,
1528 const DOM_SID
*domain_sid
,
1529 const DOM_SID
*members
,
1531 uint32_t **palias_rids
,
1532 size_t *pnum_alias_rids
)
1534 struct pdb_ads_state
*state
= talloc_get_type_abort(
1535 m
->private_data
, struct pdb_ads_state
);
1536 const char *attrs
[1] = { "objectSid" };
1537 struct tldap_message
**msg
;
1538 uint32_t *alias_rids
= NULL
;
1539 size_t num_alias_rids
= 0;
1541 bool got_members
= false;
1546 * TODO: Get the filter right so that we only get the aliases from
1547 * either the SAM or BUILTIN
1550 filter
= talloc_asprintf(talloc_tos(),
1551 "(&(|(grouptype=%d)(grouptype=%d))"
1552 "(objectclass=group)(|",
1553 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1554 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1555 if (filter
== NULL
) {
1556 return NT_STATUS_NO_MEMORY
;
1559 for (i
=0; i
<num_members
; i
++) {
1562 status
= pdb_ads_sid2dn(state
, &members
[i
], talloc_tos(), &dn
);
1563 if (!NT_STATUS_IS_OK(status
)) {
1564 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1565 sid_string_dbg(&members
[i
]),
1566 nt_errstr(status
)));
1569 filter
= talloc_asprintf_append_buffer(
1570 filter
, "(member=%s)", dn
);
1572 if (filter
== NULL
) {
1573 return NT_STATUS_NO_MEMORY
;
1582 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1583 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1584 &msg
, "%s))", filter
);
1585 TALLOC_FREE(filter
);
1586 if (rc
!= TLDAP_SUCCESS
) {
1587 DEBUG(10, ("tldap_search failed %s\n",
1588 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1589 return NT_STATUS_LDAP(rc
);
1592 count
= talloc_array_length(msg
);
1597 alias_rids
= talloc_array(mem_ctx
, uint32_t, count
);
1598 if (alias_rids
== NULL
) {
1600 return NT_STATUS_NO_MEMORY
;
1603 for (i
=0; i
<count
; i
++) {
1606 if (!tldap_pull_binsid(msg
[i
], "objectSid", &sid
)) {
1607 DEBUG(10, ("Could not pull SID for member %d\n", i
));
1610 if (sid_peek_check_rid(domain_sid
, &sid
,
1611 &alias_rids
[num_alias_rids
])) {
1612 num_alias_rids
+= 1;
1617 *palias_rids
= alias_rids
;
1618 *pnum_alias_rids
= 0;
1619 return NT_STATUS_OK
;
1622 static NTSTATUS
pdb_ads_lookup_rids(struct pdb_methods
*m
,
1623 const DOM_SID
*domain_sid
,
1627 enum lsa_SidType
*lsa_attrs
)
1629 struct pdb_ads_state
*state
= talloc_get_type_abort(
1630 m
->private_data
, struct pdb_ads_state
);
1631 const char *attrs
[2] = { "sAMAccountType", "sAMAccountName" };
1634 if (num_rids
== 0) {
1635 return NT_STATUS_NONE_MAPPED
;
1640 for (i
=0; i
<num_rids
; i
++) {
1642 struct tldap_message
**msg
;
1647 lsa_attrs
[i
] = SID_NAME_UNKNOWN
;
1649 sid_compose(&sid
, domain_sid
, rids
[i
]);
1651 sidstr
= sid_binstring(talloc_tos(), &sid
);
1652 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1654 rc
= pdb_ads_search_fmt(state
, state
->domaindn
,
1655 TLDAP_SCOPE_SUB
, attrs
,
1656 ARRAY_SIZE(attrs
), 0, talloc_tos(),
1657 &msg
, "(objectsid=%s)", sidstr
);
1658 TALLOC_FREE(sidstr
);
1659 if (rc
!= TLDAP_SUCCESS
) {
1660 DEBUG(10, ("ldap_search failed %s\n",
1661 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1665 switch talloc_array_length(msg
) {
1667 DEBUG(10, ("rid %d not found\n", (int)rids
[i
]));
1672 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1675 names
[i
] = tldap_talloc_single_attribute(
1676 msg
[0], "samAccountName", talloc_tos());
1677 if (names
[i
] == NULL
) {
1678 DEBUG(10, ("no samAccountName\n"));
1681 if (!tldap_pull_uint32(msg
[0], "samAccountType", &attr
)) {
1682 DEBUG(10, ("no samAccountType"));
1685 lsa_attrs
[i
] = ds_atype_map(attr
);
1689 if (num_mapped
== 0) {
1690 return NT_STATUS_NONE_MAPPED
;
1692 if (num_mapped
< num_rids
) {
1693 return STATUS_SOME_UNMAPPED
;
1695 return NT_STATUS_OK
;
1698 static NTSTATUS
pdb_ads_lookup_names(struct pdb_methods
*m
,
1699 const DOM_SID
*domain_sid
,
1701 const char **pp_names
,
1703 enum lsa_SidType
*attrs
)
1705 return NT_STATUS_NOT_IMPLEMENTED
;
1708 static NTSTATUS
pdb_ads_get_account_policy(struct pdb_methods
*m
,
1709 enum pdb_policy_type type
,
1712 return account_policy_get(type
, value
)
1713 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1716 static NTSTATUS
pdb_ads_set_account_policy(struct pdb_methods
*m
,
1717 enum pdb_policy_type type
,
1720 return account_policy_set(type
, value
)
1721 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1724 static NTSTATUS
pdb_ads_get_seq_num(struct pdb_methods
*m
,
1727 return NT_STATUS_NOT_IMPLEMENTED
;
1730 struct pdb_ads_search_state
{
1731 uint32_t acct_flags
;
1732 struct samr_displayentry
*entries
;
1733 uint32_t num_entries
;
1738 static bool pdb_ads_next_entry(struct pdb_search
*search
,
1739 struct samr_displayentry
*entry
)
1741 struct pdb_ads_search_state
*state
= talloc_get_type_abort(
1742 search
->private_data
, struct pdb_ads_search_state
);
1744 if (state
->current
== state
->num_entries
) {
1748 entry
->idx
= state
->entries
[state
->current
].idx
;
1749 entry
->rid
= state
->entries
[state
->current
].rid
;
1750 entry
->acct_flags
= state
->entries
[state
->current
].acct_flags
;
1752 entry
->account_name
= talloc_strdup(
1753 search
, state
->entries
[state
->current
].account_name
);
1754 entry
->fullname
= talloc_strdup(
1755 search
, state
->entries
[state
->current
].fullname
);
1756 entry
->description
= talloc_strdup(
1757 search
, state
->entries
[state
->current
].description
);
1759 if ((entry
->account_name
== NULL
) || (entry
->fullname
== NULL
)
1760 || (entry
->description
== NULL
)) {
1761 DEBUG(0, ("talloc_strdup failed\n"));
1765 state
->current
+= 1;
1769 static void pdb_ads_search_end(struct pdb_search
*search
)
1771 struct pdb_ads_search_state
*state
= talloc_get_type_abort(
1772 search
->private_data
, struct pdb_ads_search_state
);
1776 static bool pdb_ads_search_filter(struct pdb_methods
*m
,
1777 struct pdb_search
*search
,
1779 struct pdb_ads_search_state
**pstate
)
1781 struct pdb_ads_state
*state
= talloc_get_type_abort(
1782 m
->private_data
, struct pdb_ads_state
);
1783 struct pdb_ads_search_state
*sstate
;
1784 const char * attrs
[] = { "objectSid", "sAMAccountName", "displayName",
1785 "userAccountControl", "description" };
1786 struct tldap_message
**users
;
1787 int i
, rc
, num_users
;
1789 sstate
= talloc_zero(search
, struct pdb_ads_search_state
);
1790 if (sstate
== NULL
) {
1794 rc
= pdb_ads_search_fmt(
1795 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1796 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &users
,
1798 if (rc
!= TLDAP_SUCCESS
) {
1799 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1800 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
1804 num_users
= talloc_array_length(users
);
1806 sstate
->entries
= talloc_array(sstate
, struct samr_displayentry
,
1808 if (sstate
->entries
== NULL
) {
1809 DEBUG(10, ("talloc failed\n"));
1813 sstate
->num_entries
= 0;
1815 for (i
=0; i
<num_users
; i
++) {
1816 struct samr_displayentry
*e
;
1819 e
= &sstate
->entries
[sstate
->num_entries
];
1821 e
->idx
= sstate
->num_entries
;
1822 if (!tldap_pull_binsid(users
[i
], "objectSid", &sid
)) {
1823 DEBUG(10, ("Could not pull sid\n"));
1826 sid_peek_rid(&sid
, &e
->rid
);
1827 e
->acct_flags
= ACB_NORMAL
;
1828 e
->account_name
= tldap_talloc_single_attribute(
1829 users
[i
], "samAccountName", sstate
->entries
);
1830 if (e
->account_name
== NULL
) {
1833 e
->fullname
= tldap_talloc_single_attribute(
1834 users
[i
], "displayName", sstate
->entries
);
1835 if (e
->fullname
== NULL
) {
1838 e
->description
= tldap_talloc_single_attribute(
1839 users
[i
], "description", sstate
->entries
);
1840 if (e
->description
== NULL
) {
1841 e
->description
= "";
1844 sstate
->num_entries
+= 1;
1845 if (sstate
->num_entries
>= num_users
) {
1850 search
->private_data
= sstate
;
1851 search
->next_entry
= pdb_ads_next_entry
;
1852 search
->search_end
= pdb_ads_search_end
;
1857 static bool pdb_ads_search_users(struct pdb_methods
*m
,
1858 struct pdb_search
*search
,
1861 struct pdb_ads_search_state
*sstate
;
1864 ret
= pdb_ads_search_filter(m
, search
, "(objectclass=user)", &sstate
);
1868 sstate
->acct_flags
= acct_flags
;
1872 static bool pdb_ads_search_groups(struct pdb_methods
*m
,
1873 struct pdb_search
*search
)
1875 struct pdb_ads_search_state
*sstate
;
1879 filter
= talloc_asprintf(talloc_tos(),
1880 "(&(grouptype=%d)(objectclass=group))",
1881 GTYPE_SECURITY_GLOBAL_GROUP
);
1882 if (filter
== NULL
) {
1885 ret
= pdb_ads_search_filter(m
, search
, filter
, &sstate
);
1886 TALLOC_FREE(filter
);
1890 sstate
->acct_flags
= 0;
1894 static bool pdb_ads_search_aliases(struct pdb_methods
*m
,
1895 struct pdb_search
*search
,
1898 struct pdb_ads_search_state
*sstate
;
1902 filter
= talloc_asprintf(
1903 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1904 sid_check_is_builtin(sid
)
1905 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1906 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1908 if (filter
== NULL
) {
1911 ret
= pdb_ads_search_filter(m
, search
, filter
, &sstate
);
1912 TALLOC_FREE(filter
);
1916 sstate
->acct_flags
= 0;
1920 static bool pdb_ads_uid_to_rid(struct pdb_methods
*m
, uid_t uid
,
1926 static bool pdb_ads_uid_to_sid(struct pdb_methods
*m
, uid_t uid
,
1929 struct pdb_ads_state
*state
= talloc_get_type_abort(
1930 m
->private_data
, struct pdb_ads_state
);
1931 sid_compose(sid
, &state
->domainsid
, uid
);
1935 static bool pdb_ads_gid_to_sid(struct pdb_methods
*m
, gid_t gid
,
1938 struct pdb_ads_state
*state
= talloc_get_type_abort(
1939 m
->private_data
, struct pdb_ads_state
);
1940 sid_compose(sid
, &state
->domainsid
, gid
);
1944 static bool pdb_ads_sid_to_id(struct pdb_methods
*m
, const DOM_SID
*sid
,
1945 union unid_t
*id
, enum lsa_SidType
*type
)
1947 struct pdb_ads_state
*state
= talloc_get_type_abort(
1948 m
->private_data
, struct pdb_ads_state
);
1949 struct tldap_message
**msg
;
1955 * This is a big, big hack: Just hard-code the rid as uid/gid.
1958 sid_peek_rid(sid
, &rid
);
1960 sidstr
= sid_binstring(talloc_tos(), sid
);
1961 if (sidstr
== NULL
) {
1965 rc
= pdb_ads_search_fmt(
1966 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1967 NULL
, 0, 0, talloc_tos(), &msg
,
1968 "(&(objectsid=%s)(objectclass=user))", sidstr
);
1969 if ((rc
== TLDAP_SUCCESS
) && (talloc_array_length(msg
) > 0)) {
1971 *type
= SID_NAME_USER
;
1972 TALLOC_FREE(sidstr
);
1976 rc
= pdb_ads_search_fmt(
1977 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1978 NULL
, 0, 0, talloc_tos(), &msg
,
1979 "(&(objectsid=%s)(objectclass=group))", sidstr
);
1980 if ((rc
== TLDAP_SUCCESS
) && (talloc_array_length(msg
) > 0)) {
1982 *type
= SID_NAME_DOM_GRP
;
1983 TALLOC_FREE(sidstr
);
1987 TALLOC_FREE(sidstr
);
1991 static uint32_t pdb_ads_capabilities(struct pdb_methods
*m
)
1993 return PDB_CAP_STORE_RIDS
| PDB_CAP_ADS
;
1996 static bool pdb_ads_new_rid(struct pdb_methods
*m
, uint32
*rid
)
2001 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods
*m
,
2002 const char *domain
, char** pwd
,
2004 time_t *pass_last_set_time
)
2009 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods
*m
,
2010 const char* domain
, const char* pwd
,
2016 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods
*m
,
2022 static NTSTATUS
pdb_ads_enum_trusteddoms(struct pdb_methods
*m
,
2023 TALLOC_CTX
*mem_ctx
,
2024 uint32
*num_domains
,
2025 struct trustdom_info
***domains
)
2029 return NT_STATUS_OK
;
2032 static void pdb_ads_init_methods(struct pdb_methods
*m
)
2035 m
->get_domain_info
= pdb_ads_get_domain_info
;
2036 m
->getsampwnam
= pdb_ads_getsampwnam
;
2037 m
->getsampwsid
= pdb_ads_getsampwsid
;
2038 m
->create_user
= pdb_ads_create_user
;
2039 m
->delete_user
= pdb_ads_delete_user
;
2040 m
->add_sam_account
= pdb_ads_add_sam_account
;
2041 m
->update_sam_account
= pdb_ads_update_sam_account
;
2042 m
->delete_sam_account
= pdb_ads_delete_sam_account
;
2043 m
->rename_sam_account
= pdb_ads_rename_sam_account
;
2044 m
->update_login_attempts
= pdb_ads_update_login_attempts
;
2045 m
->getgrsid
= pdb_ads_getgrsid
;
2046 m
->getgrgid
= pdb_ads_getgrgid
;
2047 m
->getgrnam
= pdb_ads_getgrnam
;
2048 m
->create_dom_group
= pdb_ads_create_dom_group
;
2049 m
->delete_dom_group
= pdb_ads_delete_dom_group
;
2050 m
->add_group_mapping_entry
= pdb_ads_add_group_mapping_entry
;
2051 m
->update_group_mapping_entry
= pdb_ads_update_group_mapping_entry
;
2052 m
->delete_group_mapping_entry
= pdb_ads_delete_group_mapping_entry
;
2053 m
->enum_group_mapping
= pdb_ads_enum_group_mapping
;
2054 m
->enum_group_members
= pdb_ads_enum_group_members
;
2055 m
->enum_group_memberships
= pdb_ads_enum_group_memberships
;
2056 m
->set_unix_primary_group
= pdb_ads_set_unix_primary_group
;
2057 m
->add_groupmem
= pdb_ads_add_groupmem
;
2058 m
->del_groupmem
= pdb_ads_del_groupmem
;
2059 m
->create_alias
= pdb_ads_create_alias
;
2060 m
->delete_alias
= pdb_ads_delete_alias
;
2061 m
->get_aliasinfo
= pdb_default_get_aliasinfo
;
2062 m
->set_aliasinfo
= pdb_ads_set_aliasinfo
;
2063 m
->add_aliasmem
= pdb_ads_add_aliasmem
;
2064 m
->del_aliasmem
= pdb_ads_del_aliasmem
;
2065 m
->enum_aliasmem
= pdb_ads_enum_aliasmem
;
2066 m
->enum_alias_memberships
= pdb_ads_enum_alias_memberships
;
2067 m
->lookup_rids
= pdb_ads_lookup_rids
;
2068 m
->lookup_names
= pdb_ads_lookup_names
;
2069 m
->get_account_policy
= pdb_ads_get_account_policy
;
2070 m
->set_account_policy
= pdb_ads_set_account_policy
;
2071 m
->get_seq_num
= pdb_ads_get_seq_num
;
2072 m
->search_users
= pdb_ads_search_users
;
2073 m
->search_groups
= pdb_ads_search_groups
;
2074 m
->search_aliases
= pdb_ads_search_aliases
;
2075 m
->uid_to_rid
= pdb_ads_uid_to_rid
;
2076 m
->uid_to_sid
= pdb_ads_uid_to_sid
;
2077 m
->gid_to_sid
= pdb_ads_gid_to_sid
;
2078 m
->sid_to_id
= pdb_ads_sid_to_id
;
2079 m
->capabilities
= pdb_ads_capabilities
;
2080 m
->new_rid
= pdb_ads_new_rid
;
2081 m
->get_trusteddom_pw
= pdb_ads_get_trusteddom_pw
;
2082 m
->set_trusteddom_pw
= pdb_ads_set_trusteddom_pw
;
2083 m
->del_trusteddom_pw
= pdb_ads_del_trusteddom_pw
;
2084 m
->enum_trusteddoms
= pdb_ads_enum_trusteddoms
;
2087 static void free_private_data(void **vp
)
2089 struct pdb_ads_state
*state
= talloc_get_type_abort(
2090 *vp
, struct pdb_ads_state
);
2092 TALLOC_FREE(state
->ld
);
2097 this is used to catch debug messages from events
2099 static void s3_tldap_debug(void *context
, enum tldap_debug_level level
,
2100 const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(3,0);
2102 static void s3_tldap_debug(void *context
, enum tldap_debug_level level
,
2103 const char *fmt
, va_list ap
)
2105 int samba_level
= -1;
2108 case TLDAP_DEBUG_FATAL
:
2111 case TLDAP_DEBUG_ERROR
:
2114 case TLDAP_DEBUG_WARNING
:
2117 case TLDAP_DEBUG_TRACE
:
2122 if (vasprintf(&s
, fmt
, ap
) == -1) {
2125 DEBUG(samba_level
, ("tldap: %s", s
));
2129 static struct tldap_context
*pdb_ads_ld(struct pdb_ads_state
*state
)
2134 if (tldap_connection_ok(state
->ld
)) {
2137 TALLOC_FREE(state
->ld
);
2139 status
= open_socket_out(
2140 (struct sockaddr_storage
*)(void *)&state
->socket_address
,
2142 if (!NT_STATUS_IS_OK(status
)) {
2143 DEBUG(10, ("Could not connect to %s: %s\n",
2144 state
->socket_address
.sun_path
, nt_errstr(status
)));
2148 set_blocking(fd
, false);
2150 state
->ld
= tldap_context_create(state
, fd
);
2151 if (state
->ld
== NULL
) {
2155 tldap_set_debug(state
->ld
, s3_tldap_debug
, NULL
);
2160 int pdb_ads_search_fmt(struct pdb_ads_state
*state
, const char *base
,
2161 int scope
, const char *attrs
[], int num_attrs
,
2163 TALLOC_CTX
*mem_ctx
, struct tldap_message
***res
,
2164 const char *fmt
, ...)
2166 struct tldap_context
*ld
;
2170 ld
= pdb_ads_ld(state
);
2172 return TLDAP_SERVER_DOWN
;
2176 ret
= tldap_search_va(ld
, base
, scope
, attrs
, num_attrs
, attrsonly
,
2177 mem_ctx
, res
, fmt
, ap
);
2180 if (ret
!= TLDAP_SERVER_DOWN
) {
2185 ld
= pdb_ads_ld(state
);
2187 return TLDAP_SERVER_DOWN
;
2191 ret
= tldap_search_va(ld
, base
, scope
, attrs
, num_attrs
, attrsonly
,
2192 mem_ctx
, res
, fmt
, ap
);
2197 static NTSTATUS
pdb_ads_connect(struct pdb_ads_state
*state
,
2198 const char *location
)
2200 const char *domain_attrs
[2] = { "objectSid", "objectGUID" };
2201 const char *ncname_attrs
[1] = { "netbiosname" };
2202 struct tldap_context
*ld
;
2203 struct tldap_message
*rootdse
, **domain
, **ncname
;
2204 TALLOC_CTX
*frame
= talloc_stackframe();
2209 ZERO_STRUCT(state
->socket_address
);
2210 state
->socket_address
.sun_family
= AF_UNIX
;
2211 strncpy(state
->socket_address
.sun_path
, location
,
2212 sizeof(state
->socket_address
.sun_path
) - 1);
2214 ld
= pdb_ads_ld(state
);
2216 status
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2220 rc
= tldap_fetch_rootdse(ld
);
2221 if (rc
!= TLDAP_SUCCESS
) {
2222 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2223 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
2224 status
= NT_STATUS_LDAP(rc
);
2227 rootdse
= tldap_rootdse(state
->ld
);
2229 state
->domaindn
= tldap_talloc_single_attribute(
2230 rootdse
, "defaultNamingContext", state
);
2231 if (state
->domaindn
== NULL
) {
2232 DEBUG(10, ("Could not get defaultNamingContext\n"));
2233 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2236 DEBUG(10, ("defaultNamingContext = %s\n", state
->domaindn
));
2238 state
->configdn
= tldap_talloc_single_attribute(
2239 rootdse
, "configurationNamingContext", state
);
2240 if (state
->domaindn
== NULL
) {
2241 DEBUG(10, ("Could not get configurationNamingContext\n"));
2242 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2245 DEBUG(10, ("configurationNamingContext = %s\n", state
->configdn
));
2248 * Figure out our domain's SID
2250 rc
= pdb_ads_search_fmt(
2251 state
, state
->domaindn
, TLDAP_SCOPE_BASE
,
2252 domain_attrs
, ARRAY_SIZE(domain_attrs
), 0,
2253 talloc_tos(), &domain
, "(objectclass=*)");
2254 if (rc
!= TLDAP_SUCCESS
) {
2255 DEBUG(10, ("Could not retrieve domain: %s\n",
2256 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
2257 status
= NT_STATUS_LDAP(rc
);
2261 num_domains
= talloc_array_length(domain
);
2262 if (num_domains
!= 1) {
2263 DEBUG(10, ("Got %d domains, expected one\n", num_domains
));
2264 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2267 if (!tldap_pull_binsid(domain
[0], "objectSid", &state
->domainsid
)) {
2268 DEBUG(10, ("Could not retrieve domain SID\n"));
2269 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2272 if (!tldap_pull_guid(domain
[0], "objectGUID", &state
->domainguid
)) {
2273 DEBUG(10, ("Could not retrieve domain GUID\n"));
2274 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2277 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state
->domainsid
)));
2280 * Figure out our domain's short name
2282 rc
= pdb_ads_search_fmt(
2283 state
, state
->configdn
, TLDAP_SCOPE_SUB
,
2284 ncname_attrs
, ARRAY_SIZE(ncname_attrs
), 0,
2285 talloc_tos(), &ncname
, "(ncname=%s)", state
->domaindn
);
2286 if (rc
!= TLDAP_SUCCESS
) {
2287 DEBUG(10, ("Could not retrieve ncname: %s\n",
2288 tldap_errstr(debug_ctx(), state
->ld
, rc
)));
2289 status
= NT_STATUS_LDAP(rc
);
2292 if (talloc_array_length(ncname
) != 1) {
2293 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2297 state
->netbiosname
= tldap_talloc_single_attribute(
2298 ncname
[0], "netbiosname", state
);
2299 if (state
->netbiosname
== NULL
) {
2300 DEBUG(10, ("Could not get netbiosname\n"));
2301 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2304 DEBUG(10, ("netbiosname: %s\n", state
->netbiosname
));
2306 if (!strequal(lp_workgroup(), state
->netbiosname
)) {
2307 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2308 state
->netbiosname
, lp_workgroup()));
2309 status
= NT_STATUS_NO_SUCH_DOMAIN
;
2313 secrets_store_domain_sid(state
->netbiosname
, &state
->domainsid
);
2315 status
= NT_STATUS_OK
;
2321 static NTSTATUS
pdb_init_ads(struct pdb_methods
**pdb_method
,
2322 const char *location
)
2324 struct pdb_methods
*m
;
2325 struct pdb_ads_state
*state
;
2329 m
= talloc(talloc_autofree_context(), struct pdb_methods
);
2331 return NT_STATUS_NO_MEMORY
;
2333 state
= talloc_zero(m
, struct pdb_ads_state
);
2334 if (state
== NULL
) {
2337 m
->private_data
= state
;
2338 m
->free_private_data
= free_private_data
;
2339 pdb_ads_init_methods(m
);
2341 if (location
== NULL
) {
2342 tmp
= talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2346 if (location
== NULL
) {
2350 status
= pdb_ads_connect(state
, location
);
2351 if (!NT_STATUS_IS_OK(status
)) {
2352 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status
)));
2357 return NT_STATUS_OK
;
2359 status
= NT_STATUS_NO_MEMORY
;
2365 NTSTATUS
pdb_ads_init(void);
2366 NTSTATUS
pdb_ads_init(void)
2368 return smb_register_passdb(PASSDB_INTERFACE_VERSION
, "ads",