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 #include "tldap_util.h"
23 #include "../libds/common/flags.h"
25 #include "../librpc/gen_ndr/samr.h"
27 struct pdb_ads_state
{
28 struct sockaddr_un socket_address
;
29 struct tldap_context
*ld
;
30 struct dom_sid domainsid
;
31 struct GUID domainguid
;
37 struct pdb_ads_samu_private
{
39 struct tldap_message
*ldapmsg
;
42 static NTSTATUS
pdb_ads_getsampwsid(struct pdb_methods
*m
,
43 struct samu
*sam_acct
,
44 const struct dom_sid
*sid
);
45 static bool pdb_ads_gid_to_sid(struct pdb_methods
*m
, gid_t gid
,
47 static bool pdb_ads_dnblob2sid(struct pdb_ads_state
*state
, DATA_BLOB
*dnblob
,
48 struct dom_sid
*psid
);
49 static NTSTATUS
pdb_ads_sid2dn(struct pdb_ads_state
*state
,
50 const struct dom_sid
*sid
,
51 TALLOC_CTX
*mem_ctx
, char **pdn
);
52 static struct tldap_context
*pdb_ads_ld(struct pdb_ads_state
*state
);
53 static int pdb_ads_search_fmt(struct pdb_ads_state
*state
, const char *base
,
54 int scope
, const char *attrs
[], int num_attrs
,
56 TALLOC_CTX
*mem_ctx
, struct tldap_message
***res
,
57 const char *fmt
, ...);
58 static NTSTATUS
pdb_ads_getsamupriv(struct pdb_ads_state
*state
,
61 struct pdb_ads_samu_private
**presult
);
63 static bool pdb_ads_pull_time(struct tldap_message
*msg
, const char *attr
,
68 if (!tldap_pull_uint64(msg
, attr
, &tmp
)) {
71 *ptime
= uint64s_nt_time_to_unix_abs(&tmp
);
75 static gid_t
pdb_ads_sid2gid(const struct dom_sid
*sid
)
78 sid_peek_rid(sid
, &rid
);
82 static char *pdb_ads_domaindn2dns(TALLOC_CTX
*mem_ctx
, char *dn
)
86 result
= talloc_string_sub2(mem_ctx
, dn
, "DC=", "", false, false,
92 while ((p
= strchr_m(result
, ',')) != NULL
) {
99 static struct pdb_domain_info
*pdb_ads_get_domain_info(
100 struct pdb_methods
*m
, TALLOC_CTX
*mem_ctx
)
102 struct pdb_ads_state
*state
= talloc_get_type_abort(
103 m
->private_data
, struct pdb_ads_state
);
104 struct pdb_domain_info
*info
;
105 struct tldap_message
*rootdse
;
108 info
= talloc(mem_ctx
, struct pdb_domain_info
);
112 info
->name
= talloc_strdup(info
, state
->netbiosname
);
113 if (info
->name
== NULL
) {
116 info
->dns_domain
= pdb_ads_domaindn2dns(info
, state
->domaindn
);
117 if (info
->dns_domain
== NULL
) {
121 rootdse
= tldap_rootdse(state
->ld
);
122 tmp
= tldap_talloc_single_attribute(rootdse
, "rootDomainNamingContext",
127 info
->dns_forest
= pdb_ads_domaindn2dns(info
, tmp
);
129 if (info
->dns_forest
== NULL
) {
132 info
->sid
= state
->domainsid
;
133 info
->guid
= state
->domainguid
;
141 static struct pdb_ads_samu_private
*pdb_ads_get_samu_private(
142 struct pdb_methods
*m
, struct samu
*sam
)
144 struct pdb_ads_state
*state
= talloc_get_type_abort(
145 m
->private_data
, struct pdb_ads_state
);
146 struct pdb_ads_samu_private
*result
;
147 char *sidstr
, *filter
;
150 result
= (struct pdb_ads_samu_private
*)
151 pdb_get_backend_private_data(sam
, m
);
153 if (result
!= NULL
) {
154 return talloc_get_type_abort(
155 result
, struct pdb_ads_samu_private
);
158 sidstr
= sid_binstring(talloc_tos(), pdb_get_user_sid(sam
));
159 if (sidstr
== NULL
) {
163 filter
= talloc_asprintf(
164 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr
);
166 if (filter
== NULL
) {
170 status
= pdb_ads_getsamupriv(state
, filter
, sam
, &result
);
172 if (!NT_STATUS_IS_OK(status
)) {
179 static NTSTATUS
pdb_ads_init_sam_from_priv(struct pdb_methods
*m
,
181 struct pdb_ads_samu_private
*priv
)
183 struct pdb_ads_state
*state
= talloc_get_type_abort(
184 m
->private_data
, struct pdb_ads_state
);
185 TALLOC_CTX
*frame
= talloc_stackframe();
186 NTSTATUS status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
187 struct tldap_message
*entry
= priv
->ldapmsg
;
194 str
= tldap_talloc_single_attribute(entry
, "samAccountName", sam
);
196 DEBUG(10, ("no samAccountName\n"));
199 pdb_set_username(sam
, str
, PDB_SET
);
201 if (pdb_ads_pull_time(entry
, "lastLogon", &tmp_time
)) {
202 pdb_set_logon_time(sam
, tmp_time
, PDB_SET
);
204 if (pdb_ads_pull_time(entry
, "lastLogoff", &tmp_time
)) {
205 pdb_set_logoff_time(sam
, tmp_time
, PDB_SET
);
207 if (pdb_ads_pull_time(entry
, "pwdLastSet", &tmp_time
)) {
208 pdb_set_pass_last_set_time(sam
, tmp_time
, PDB_SET
);
210 if (pdb_ads_pull_time(entry
, "accountExpires", &tmp_time
)) {
211 pdb_set_kickoff_time(sam
, tmp_time
, PDB_SET
);
214 str
= tldap_talloc_single_attribute(entry
, "displayName",
217 pdb_set_fullname(sam
, str
, PDB_SET
);
220 str
= tldap_talloc_single_attribute(entry
, "homeDirectory",
223 pdb_set_homedir(sam
, str
, PDB_SET
);
226 str
= tldap_talloc_single_attribute(entry
, "homeDrive", talloc_tos());
228 pdb_set_dir_drive(sam
, str
, PDB_SET
);
231 str
= tldap_talloc_single_attribute(entry
, "scriptPath", talloc_tos());
233 pdb_set_logon_script(sam
, str
, PDB_SET
);
236 str
= tldap_talloc_single_attribute(entry
, "profilePath",
239 pdb_set_profile_path(sam
, str
, PDB_SET
);
242 str
= tldap_talloc_single_attribute(entry
, "profilePath",
245 pdb_set_profile_path(sam
, str
, PDB_SET
);
248 if (!tldap_pull_binsid(entry
, "objectSid", &sid
)) {
249 DEBUG(10, ("Could not pull SID\n"));
252 pdb_set_user_sid(sam
, &sid
, PDB_SET
);
254 if (!tldap_pull_uint64(entry
, "userAccountControl", &n
)) {
255 DEBUG(10, ("Could not pull userAccountControl\n"));
258 pdb_set_acct_ctrl(sam
, ds_uf2acb(n
), PDB_SET
);
260 if (tldap_get_single_valueblob(entry
, "unicodePwd", &blob
)) {
261 if (blob
.length
!= NT_HASH_LEN
) {
262 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
263 (int)blob
.length
, NT_HASH_LEN
));
266 pdb_set_nt_passwd(sam
, blob
.data
, PDB_SET
);
269 if (tldap_get_single_valueblob(entry
, "dBCSPwd", &blob
)) {
270 if (blob
.length
!= LM_HASH_LEN
) {
271 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
272 (int)blob
.length
, LM_HASH_LEN
));
275 pdb_set_lanman_passwd(sam
, blob
.data
, PDB_SET
);
278 if (tldap_pull_uint64(entry
, "primaryGroupID", &n
)) {
279 sid_compose(&sid
, &state
->domainsid
, n
);
280 pdb_set_group_sid(sam
, &sid
, PDB_SET
);
283 status
= NT_STATUS_OK
;
289 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state
*state
,
290 struct tldap_message
*existing
,
292 int *pnum_mods
, struct tldap_mod
**pmods
,
298 /* TODO: All fields :-) */
300 ret
&= tldap_make_mod_fmt(
301 existing
, mem_ctx
, pnum_mods
, pmods
, "displayName",
302 "%s", pdb_get_fullname(sam
));
304 blob
= data_blob_const(pdb_get_nt_passwd(sam
), NT_HASH_LEN
);
305 if (blob
.data
!= NULL
) {
306 ret
&= tldap_add_mod_blobs(mem_ctx
, pmods
, TLDAP_MOD_REPLACE
,
307 "unicodePwd", 1, &blob
);
310 blob
= data_blob_const(pdb_get_lanman_passwd(sam
), NT_HASH_LEN
);
311 if (blob
.data
!= NULL
) {
312 ret
&= tldap_add_mod_blobs(mem_ctx
, pmods
, TLDAP_MOD_REPLACE
,
313 "dBCSPwd", 1, &blob
);
316 ret
&= tldap_make_mod_fmt(
317 existing
, mem_ctx
, pnum_mods
, pmods
, "userAccountControl",
318 "%d", ds_acb2uf(pdb_get_acct_ctrl(sam
)));
320 ret
&= tldap_make_mod_fmt(
321 existing
, mem_ctx
, pnum_mods
, pmods
, "homeDirectory",
322 "%s", pdb_get_homedir(sam
));
324 ret
&= tldap_make_mod_fmt(
325 existing
, mem_ctx
, pnum_mods
, pmods
, "homeDrive",
326 "%s", pdb_get_dir_drive(sam
));
328 ret
&= tldap_make_mod_fmt(
329 existing
, mem_ctx
, pnum_mods
, pmods
, "scriptPath",
330 "%s", pdb_get_logon_script(sam
));
332 ret
&= tldap_make_mod_fmt(
333 existing
, mem_ctx
, pnum_mods
, pmods
, "profilePath",
334 "%s", pdb_get_profile_path(sam
));
339 static NTSTATUS
pdb_ads_getsamupriv(struct pdb_ads_state
*state
,
342 struct pdb_ads_samu_private
**presult
)
344 const char * attrs
[] = {
345 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
346 "sAMAccountName", "displayName", "homeDirectory",
347 "homeDrive", "scriptPath", "profilePath", "description",
348 "userWorkstations", "comment", "userParameters", "objectSid",
349 "primaryGroupID", "userAccountControl", "logonHours",
350 "badPwdCount", "logonCount", "countryCode", "codePage",
351 "unicodePwd", "dBCSPwd" };
352 struct tldap_message
**users
;
354 struct pdb_ads_samu_private
*result
;
356 result
= talloc(mem_ctx
, struct pdb_ads_samu_private
);
357 if (result
== NULL
) {
358 return NT_STATUS_NO_MEMORY
;
361 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
362 attrs
, ARRAY_SIZE(attrs
), 0, result
,
363 &users
, "%s", filter
);
364 if (rc
!= TLDAP_SUCCESS
) {
365 DEBUG(10, ("ldap_search failed %s\n",
366 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
368 return NT_STATUS_LDAP(rc
);
371 count
= talloc_array_length(users
);
373 DEBUG(10, ("Expected 1 user, got %d\n", count
));
375 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
378 result
->ldapmsg
= users
[0];
379 if (!tldap_entry_dn(result
->ldapmsg
, &result
->dn
)) {
380 DEBUG(10, ("Could not extract dn\n"));
382 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
389 static NTSTATUS
pdb_ads_getsampwfilter(struct pdb_methods
*m
,
390 struct pdb_ads_state
*state
,
391 struct samu
*sam_acct
,
394 struct pdb_ads_samu_private
*priv
;
397 status
= pdb_ads_getsamupriv(state
, filter
, sam_acct
, &priv
);
398 if (!NT_STATUS_IS_OK(status
)) {
399 DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n",
404 status
= pdb_ads_init_sam_from_priv(m
, sam_acct
, priv
);
405 if (!NT_STATUS_IS_OK(status
)) {
406 DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n",
412 pdb_set_backend_private_data(sam_acct
, priv
, NULL
, m
, PDB_SET
);
416 static NTSTATUS
pdb_ads_getsampwnam(struct pdb_methods
*m
,
417 struct samu
*sam_acct
,
418 const char *username
)
420 struct pdb_ads_state
*state
= talloc_get_type_abort(
421 m
->private_data
, struct pdb_ads_state
);
424 filter
= talloc_asprintf(
425 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
427 NT_STATUS_HAVE_NO_MEMORY(filter
);
429 return pdb_ads_getsampwfilter(m
, state
, sam_acct
, filter
);
432 static NTSTATUS
pdb_ads_getsampwsid(struct pdb_methods
*m
,
433 struct samu
*sam_acct
,
434 const struct dom_sid
*sid
)
436 struct pdb_ads_state
*state
= talloc_get_type_abort(
437 m
->private_data
, struct pdb_ads_state
);
438 char *sidstr
, *filter
;
440 sidstr
= sid_binstring(talloc_tos(), sid
);
441 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
443 filter
= talloc_asprintf(
444 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr
);
446 NT_STATUS_HAVE_NO_MEMORY(filter
);
448 return pdb_ads_getsampwfilter(m
, state
, sam_acct
, filter
);
451 static NTSTATUS
pdb_ads_create_user(struct pdb_methods
*m
,
453 const char *name
, uint32 acct_flags
,
456 struct pdb_ads_state
*state
= talloc_get_type_abort(
457 m
->private_data
, struct pdb_ads_state
);
458 struct tldap_context
*ld
;
459 const char *attrs
[1] = { "objectSid" };
460 struct tldap_mod
*mods
= NULL
;
462 struct tldap_message
**user
;
468 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
471 return NT_STATUS_NO_MEMORY
;
474 ld
= pdb_ads_ld(state
);
476 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
479 /* TODO: Create machines etc */
482 ok
&= tldap_make_mod_fmt(
483 NULL
, talloc_tos(), &num_mods
, &mods
, "objectClass", "user");
484 ok
&= tldap_make_mod_fmt(
485 NULL
, talloc_tos(), &num_mods
, &mods
, "samAccountName", "%s",
488 return NT_STATUS_NO_MEMORY
;
492 rc
= tldap_add(ld
, dn
, num_mods
, mods
, NULL
, 0, NULL
, 0);
493 if (rc
!= TLDAP_SUCCESS
) {
494 DEBUG(10, ("ldap_add failed %s\n",
495 tldap_errstr(talloc_tos(), ld
, rc
)));
497 return NT_STATUS_LDAP(rc
);
500 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
501 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
503 "(&(objectclass=user)(samaccountname=%s))",
505 if (rc
!= TLDAP_SUCCESS
) {
506 DEBUG(10, ("Could not find just created user %s: %s\n",
507 name
, tldap_errstr(talloc_tos(), state
->ld
, rc
)));
509 return NT_STATUS_LDAP(rc
);
512 if (talloc_array_length(user
) != 1) {
513 DEBUG(10, ("Got %d users, expected one\n",
514 (int)talloc_array_length(user
)));
516 return NT_STATUS_LDAP(rc
);
519 if (!tldap_pull_binsid(user
[0], "objectSid", &sid
)) {
520 DEBUG(10, ("Could not fetch objectSid from user %s\n",
523 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
526 sid_peek_rid(&sid
, rid
);
531 static NTSTATUS
pdb_ads_delete_user(struct pdb_methods
*m
,
535 struct pdb_ads_state
*state
= talloc_get_type_abort(
536 m
->private_data
, struct pdb_ads_state
);
538 struct tldap_context
*ld
;
542 ld
= pdb_ads_ld(state
);
544 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
547 status
= pdb_ads_sid2dn(state
, pdb_get_user_sid(sam
), talloc_tos(),
549 if (!NT_STATUS_IS_OK(status
)) {
553 rc
= tldap_delete(ld
, dn
, NULL
, 0, NULL
, 0);
555 if (rc
!= TLDAP_SUCCESS
) {
556 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn
,
557 tldap_errstr(talloc_tos(), ld
, rc
)));
558 return NT_STATUS_LDAP(rc
);
563 static NTSTATUS
pdb_ads_add_sam_account(struct pdb_methods
*m
,
564 struct samu
*sampass
)
566 return NT_STATUS_NOT_IMPLEMENTED
;
569 static NTSTATUS
pdb_ads_update_sam_account(struct pdb_methods
*m
,
572 struct pdb_ads_state
*state
= talloc_get_type_abort(
573 m
->private_data
, struct pdb_ads_state
);
574 struct pdb_ads_samu_private
*priv
= pdb_ads_get_samu_private(m
, sam
);
575 struct tldap_context
*ld
;
576 struct tldap_mod
*mods
= NULL
;
577 int rc
, num_mods
= 0;
579 ld
= pdb_ads_ld(state
);
581 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
584 if (!pdb_ads_init_ads_from_sam(state
, priv
->ldapmsg
, talloc_tos(),
585 &num_mods
, &mods
, sam
)) {
586 return NT_STATUS_NO_MEMORY
;
590 /* Nothing to do, just return success */
594 rc
= tldap_modify(ld
, priv
->dn
, num_mods
, mods
, NULL
, 0,
597 if (rc
!= TLDAP_SUCCESS
) {
598 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv
->dn
,
599 tldap_errstr(talloc_tos(), ld
, rc
)));
600 return NT_STATUS_LDAP(rc
);
606 static NTSTATUS
pdb_ads_delete_sam_account(struct pdb_methods
*m
,
607 struct samu
*username
)
609 return NT_STATUS_NOT_IMPLEMENTED
;
612 static NTSTATUS
pdb_ads_rename_sam_account(struct pdb_methods
*m
,
613 struct samu
*oldname
,
616 return NT_STATUS_NOT_IMPLEMENTED
;
619 static NTSTATUS
pdb_ads_update_login_attempts(struct pdb_methods
*m
,
620 struct samu
*sam_acct
,
623 return NT_STATUS_NOT_IMPLEMENTED
;
626 static NTSTATUS
pdb_ads_getgrfilter(struct pdb_methods
*m
, GROUP_MAP
*map
,
629 struct pdb_ads_state
*state
= talloc_get_type_abort(
630 m
->private_data
, struct pdb_ads_state
);
631 const char *attrs
[4] = { "objectSid", "description", "samAccountName",
634 struct tldap_message
**group
;
638 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
639 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
640 &group
, "%s", filter
);
641 if (rc
!= TLDAP_SUCCESS
) {
642 DEBUG(10, ("ldap_search failed %s\n",
643 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
644 return NT_STATUS_LDAP(rc
);
646 if (talloc_array_length(group
) != 1) {
647 DEBUG(10, ("Expected 1 user, got %d\n",
648 (int)talloc_array_length(group
)));
649 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
652 if (!tldap_pull_binsid(group
[0], "objectSid", &map
->sid
)) {
653 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
655 map
->gid
= pdb_ads_sid2gid(&map
->sid
);
657 if (!tldap_pull_uint32(group
[0], "groupType", &grouptype
)) {
658 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
661 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
:
662 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
:
663 map
->sid_name_use
= SID_NAME_ALIAS
;
665 case GTYPE_SECURITY_GLOBAL_GROUP
:
666 map
->sid_name_use
= SID_NAME_DOM_GRP
;
669 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
672 str
= tldap_talloc_single_attribute(group
[0], "samAccountName",
675 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
677 fstrcpy(map
->nt_name
, str
);
680 str
= tldap_talloc_single_attribute(group
[0], "description",
683 fstrcpy(map
->comment
, str
);
686 map
->comment
[0] = '\0';
693 static NTSTATUS
pdb_ads_getgrsid(struct pdb_methods
*m
, GROUP_MAP
*map
,
699 filter
= talloc_asprintf(talloc_tos(),
700 "(&(objectsid=%s)(objectclass=group))",
701 sid_string_talloc(talloc_tos(), &sid
));
702 if (filter
== NULL
) {
703 return NT_STATUS_NO_MEMORY
;
706 status
= pdb_ads_getgrfilter(m
, map
, filter
);
711 static NTSTATUS
pdb_ads_getgrgid(struct pdb_methods
*m
, GROUP_MAP
*map
,
715 pdb_ads_gid_to_sid(m
, gid
, &sid
);
716 return pdb_ads_getgrsid(m
, map
, sid
);
719 static NTSTATUS
pdb_ads_getgrnam(struct pdb_methods
*m
, GROUP_MAP
*map
,
725 filter
= talloc_asprintf(talloc_tos(),
726 "(&(samaccountname=%s)(objectclass=group))",
728 if (filter
== NULL
) {
729 return NT_STATUS_NO_MEMORY
;
732 status
= pdb_ads_getgrfilter(m
, map
, filter
);
737 static NTSTATUS
pdb_ads_create_dom_group(struct pdb_methods
*m
,
738 TALLOC_CTX
*mem_ctx
, const char *name
,
741 TALLOC_CTX
*frame
= talloc_stackframe();
742 struct pdb_ads_state
*state
= talloc_get_type_abort(
743 m
->private_data
, struct pdb_ads_state
);
744 struct tldap_context
*ld
;
745 const char *attrs
[1] = { "objectSid" };
747 struct tldap_mod
*mods
= NULL
;
748 struct tldap_message
**alias
;
754 ld
= pdb_ads_ld(state
);
756 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
759 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
763 return NT_STATUS_NO_MEMORY
;
766 ok
&= tldap_make_mod_fmt(
767 NULL
, talloc_tos(), &num_mods
, &mods
, "samAccountName", "%s",
769 ok
&= tldap_make_mod_fmt(
770 NULL
, talloc_tos(), &num_mods
, &mods
, "objectClass", "group");
771 ok
&= tldap_make_mod_fmt(
772 NULL
, talloc_tos(), &num_mods
, &mods
, "groupType",
773 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP
);
777 return NT_STATUS_NO_MEMORY
;
780 rc
= tldap_add(ld
, dn
, num_mods
, mods
, NULL
, 0, NULL
, 0);
781 if (rc
!= TLDAP_SUCCESS
) {
782 DEBUG(10, ("ldap_add failed %s\n",
783 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
785 return NT_STATUS_LDAP(rc
);
788 rc
= pdb_ads_search_fmt(
789 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
790 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &alias
,
791 "(&(objectclass=group)(samaccountname=%s))", name
);
792 if (rc
!= TLDAP_SUCCESS
) {
793 DEBUG(10, ("Could not find just created alias %s: %s\n",
794 name
, tldap_errstr(talloc_tos(), state
->ld
, rc
)));
796 return NT_STATUS_LDAP(rc
);
799 if (talloc_array_length(alias
) != 1) {
800 DEBUG(10, ("Got %d alias, expected one\n",
801 (int)talloc_array_length(alias
)));
803 return NT_STATUS_LDAP(rc
);
806 if (!tldap_pull_binsid(alias
[0], "objectSid", &sid
)) {
807 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
810 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
813 sid_peek_rid(&sid
, rid
);
818 static NTSTATUS
pdb_ads_delete_dom_group(struct pdb_methods
*m
,
819 TALLOC_CTX
*mem_ctx
, uint32 rid
)
821 struct pdb_ads_state
*state
= talloc_get_type_abort(
822 m
->private_data
, struct pdb_ads_state
);
823 struct tldap_context
*ld
;
826 struct tldap_message
**msg
;
830 sid_compose(&sid
, &state
->domainsid
, rid
);
832 sidstr
= sid_binstring(talloc_tos(), &sid
);
833 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
835 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
836 NULL
, 0, 0, talloc_tos(), &msg
,
837 ("(&(objectSid=%s)(objectClass=group))"),
840 if (rc
!= TLDAP_SUCCESS
) {
841 DEBUG(10, ("ldap_search failed %s\n",
842 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
843 return NT_STATUS_LDAP(rc
);
846 switch talloc_array_length(msg
) {
848 return NT_STATUS_NO_SUCH_GROUP
;
852 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
855 if (!tldap_entry_dn(msg
[0], &dn
)) {
857 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
860 ld
= pdb_ads_ld(state
);
863 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
866 rc
= tldap_delete(ld
, dn
, NULL
, 0, NULL
, 0);
868 if (rc
!= TLDAP_SUCCESS
) {
869 DEBUG(10, ("ldap_delete failed: %s\n",
870 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
871 return NT_STATUS_LDAP(rc
);
877 static NTSTATUS
pdb_ads_add_group_mapping_entry(struct pdb_methods
*m
,
880 return NT_STATUS_NOT_IMPLEMENTED
;
883 static NTSTATUS
pdb_ads_update_group_mapping_entry(struct pdb_methods
*m
,
886 return NT_STATUS_NOT_IMPLEMENTED
;
889 static NTSTATUS
pdb_ads_delete_group_mapping_entry(struct pdb_methods
*m
,
892 return NT_STATUS_NOT_IMPLEMENTED
;
895 static NTSTATUS
pdb_ads_enum_group_mapping(struct pdb_methods
*m
,
896 const struct dom_sid
*sid
,
897 enum lsa_SidType sid_name_use
,
899 size_t *p_num_entries
,
902 return NT_STATUS_NOT_IMPLEMENTED
;
905 static NTSTATUS
pdb_ads_enum_group_members(struct pdb_methods
*m
,
907 const struct dom_sid
*group
,
909 size_t *pnum_members
)
911 struct pdb_ads_state
*state
= talloc_get_type_abort(
912 m
->private_data
, struct pdb_ads_state
);
913 const char *attrs
[1] = { "member" };
915 struct tldap_message
**msg
;
916 int i
, rc
, num_members
;
920 sidstr
= sid_binstring(talloc_tos(), group
);
921 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
923 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
924 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
925 &msg
, "(objectsid=%s)", sidstr
);
927 if (rc
!= TLDAP_SUCCESS
) {
928 DEBUG(10, ("ldap_search failed %s\n",
929 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
930 return NT_STATUS_LDAP(rc
);
932 switch talloc_array_length(msg
) {
934 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
939 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
943 if (!tldap_entry_values(msg
[0], "member", &num_members
, &blobs
)) {
944 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
947 members
= talloc_array(mem_ctx
, uint32_t, num_members
);
948 if (members
== NULL
) {
949 return NT_STATUS_NO_MEMORY
;
952 for (i
=0; i
<num_members
; i
++) {
954 if (!pdb_ads_dnblob2sid(state
, &blobs
[i
], &sid
)
955 || !sid_peek_rid(&sid
, &members
[i
])) {
956 TALLOC_FREE(members
);
957 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
962 *pnum_members
= num_members
;
966 static NTSTATUS
pdb_ads_enum_group_memberships(struct pdb_methods
*m
,
969 struct dom_sid
**pp_sids
,
971 size_t *p_num_groups
)
973 struct pdb_ads_state
*state
= talloc_get_type_abort(
974 m
->private_data
, struct pdb_ads_state
);
975 struct pdb_ads_samu_private
*priv
= pdb_ads_get_samu_private(
977 const char *attrs
[1] = { "objectSid" };
978 struct tldap_message
**groups
;
981 struct dom_sid
*group_sids
;
984 rc
= pdb_ads_search_fmt(
985 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
986 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &groups
,
987 "(&(member=%s)(grouptype=%d)(objectclass=group))",
988 priv
->dn
, GTYPE_SECURITY_GLOBAL_GROUP
);
989 if (rc
!= TLDAP_SUCCESS
) {
990 DEBUG(10, ("ldap_search failed %s\n",
991 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
992 return NT_STATUS_LDAP(rc
);
995 count
= talloc_array_length(groups
);
997 group_sids
= talloc_array(mem_ctx
, struct dom_sid
, count
);
998 if (group_sids
== NULL
) {
999 return NT_STATUS_NO_MEMORY
;
1001 gids
= talloc_array(mem_ctx
, gid_t
, count
);
1003 TALLOC_FREE(group_sids
);
1004 return NT_STATUS_NO_MEMORY
;
1008 for (i
=0; i
<count
; i
++) {
1009 if (!tldap_pull_binsid(groups
[i
], "objectSid",
1010 &group_sids
[num_groups
])) {
1013 gids
[num_groups
] = pdb_ads_sid2gid(&group_sids
[num_groups
]);
1016 if (num_groups
== count
) {
1021 *pp_sids
= group_sids
;
1023 *p_num_groups
= num_groups
;
1024 return NT_STATUS_OK
;
1027 static NTSTATUS
pdb_ads_set_unix_primary_group(struct pdb_methods
*m
,
1028 TALLOC_CTX
*mem_ctx
,
1031 return NT_STATUS_NOT_IMPLEMENTED
;
1034 static NTSTATUS
pdb_ads_mod_groupmem(struct pdb_methods
*m
,
1035 TALLOC_CTX
*mem_ctx
,
1036 uint32 grouprid
, uint32 memberrid
,
1039 struct pdb_ads_state
*state
= talloc_get_type_abort(
1040 m
->private_data
, struct pdb_ads_state
);
1041 TALLOC_CTX
*frame
= talloc_stackframe();
1042 struct tldap_context
*ld
;
1043 struct dom_sid groupsid
, membersid
;
1044 char *groupdn
, *memberdn
;
1045 struct tldap_mod
*mods
;
1049 ld
= pdb_ads_ld(state
);
1051 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1054 sid_compose(&groupsid
, &state
->domainsid
, grouprid
);
1055 sid_compose(&membersid
, &state
->domainsid
, memberrid
);
1057 status
= pdb_ads_sid2dn(state
, &groupsid
, talloc_tos(), &groupdn
);
1058 if (!NT_STATUS_IS_OK(status
)) {
1060 return NT_STATUS_NO_SUCH_GROUP
;
1062 status
= pdb_ads_sid2dn(state
, &membersid
, talloc_tos(), &memberdn
);
1063 if (!NT_STATUS_IS_OK(status
)) {
1065 return NT_STATUS_NO_SUCH_USER
;
1070 if (!tldap_add_mod_str(talloc_tos(), &mods
, mod_op
,
1071 "member", memberdn
)) {
1073 return NT_STATUS_NO_MEMORY
;
1076 rc
= tldap_modify(ld
, groupdn
, 1, mods
, NULL
, 0, NULL
, 0);
1078 if (rc
!= TLDAP_SUCCESS
) {
1079 DEBUG(10, ("ldap_modify failed: %s\n",
1080 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1081 if (rc
== TLDAP_TYPE_OR_VALUE_EXISTS
) {
1082 return NT_STATUS_MEMBER_IN_GROUP
;
1084 if (rc
== TLDAP_NO_SUCH_ATTRIBUTE
) {
1085 return NT_STATUS_MEMBER_NOT_IN_GROUP
;
1087 return NT_STATUS_LDAP(rc
);
1090 return NT_STATUS_OK
;
1093 static NTSTATUS
pdb_ads_add_groupmem(struct pdb_methods
*m
,
1094 TALLOC_CTX
*mem_ctx
,
1095 uint32 group_rid
, uint32 member_rid
)
1097 return pdb_ads_mod_groupmem(m
, mem_ctx
, group_rid
, member_rid
,
1101 static NTSTATUS
pdb_ads_del_groupmem(struct pdb_methods
*m
,
1102 TALLOC_CTX
*mem_ctx
,
1103 uint32 group_rid
, uint32 member_rid
)
1105 return pdb_ads_mod_groupmem(m
, mem_ctx
, group_rid
, member_rid
,
1109 static NTSTATUS
pdb_ads_create_alias(struct pdb_methods
*m
,
1110 const char *name
, uint32
*rid
)
1112 TALLOC_CTX
*frame
= talloc_stackframe();
1113 struct pdb_ads_state
*state
= talloc_get_type_abort(
1114 m
->private_data
, struct pdb_ads_state
);
1115 struct tldap_context
*ld
;
1116 const char *attrs
[1] = { "objectSid" };
1118 struct tldap_mod
*mods
= NULL
;
1119 struct tldap_message
**alias
;
1125 ld
= pdb_ads_ld(state
);
1127 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1130 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
1134 return NT_STATUS_NO_MEMORY
;
1137 ok
&= tldap_make_mod_fmt(
1138 NULL
, talloc_tos(), &num_mods
, &mods
, "samAccountName", "%s",
1140 ok
&= tldap_make_mod_fmt(
1141 NULL
, talloc_tos(), &num_mods
, &mods
, "objectClass", "group");
1142 ok
&= tldap_make_mod_fmt(
1143 NULL
, talloc_tos(), &num_mods
, &mods
, "groupType",
1144 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1148 return NT_STATUS_NO_MEMORY
;
1151 rc
= tldap_add(ld
, dn
, num_mods
, mods
, NULL
, 0, NULL
, 0);
1152 if (rc
!= TLDAP_SUCCESS
) {
1153 DEBUG(10, ("ldap_add failed %s\n",
1154 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1156 return NT_STATUS_LDAP(rc
);
1159 rc
= pdb_ads_search_fmt(
1160 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1161 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &alias
,
1162 "(&(objectclass=group)(samaccountname=%s))", name
);
1163 if (rc
!= TLDAP_SUCCESS
) {
1164 DEBUG(10, ("Could not find just created alias %s: %s\n",
1165 name
, tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1167 return NT_STATUS_LDAP(rc
);
1170 if (talloc_array_length(alias
) != 1) {
1171 DEBUG(10, ("Got %d alias, expected one\n",
1172 (int)talloc_array_length(alias
)));
1174 return NT_STATUS_LDAP(rc
);
1177 if (!tldap_pull_binsid(alias
[0], "objectSid", &sid
)) {
1178 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1181 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1184 sid_peek_rid(&sid
, rid
);
1186 return NT_STATUS_OK
;
1189 static NTSTATUS
pdb_ads_delete_alias(struct pdb_methods
*m
,
1190 const struct dom_sid
*sid
)
1192 struct pdb_ads_state
*state
= talloc_get_type_abort(
1193 m
->private_data
, struct pdb_ads_state
);
1194 struct tldap_context
*ld
;
1195 struct tldap_message
**alias
;
1196 char *sidstr
, *dn
= NULL
;
1199 ld
= pdb_ads_ld(state
);
1201 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1204 sidstr
= sid_binstring(talloc_tos(), sid
);
1205 if (sidstr
== NULL
) {
1206 return NT_STATUS_NO_MEMORY
;
1209 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1210 NULL
, 0, 0, talloc_tos(), &alias
,
1211 "(&(objectSid=%s)(objectclass=group)"
1212 "(|(grouptype=%d)(grouptype=%d)))",
1213 sidstr
, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1214 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1215 TALLOC_FREE(sidstr
);
1216 if (rc
!= TLDAP_SUCCESS
) {
1217 DEBUG(10, ("ldap_search failed: %s\n",
1218 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1219 return NT_STATUS_LDAP(rc
);
1221 if (talloc_array_length(alias
) != 1) {
1222 DEBUG(10, ("Expected 1 alias, got %d\n",
1223 (int)talloc_array_length(alias
)));
1224 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1226 if (!tldap_entry_dn(alias
[0], &dn
)) {
1227 DEBUG(10, ("Could not get DN for alias %s\n",
1228 sid_string_dbg(sid
)));
1229 return NT_STATUS_INTERNAL_ERROR
;
1232 rc
= tldap_delete(ld
, dn
, NULL
, 0, NULL
, 0);
1233 if (rc
!= TLDAP_SUCCESS
) {
1234 DEBUG(10, ("ldap_delete failed: %s\n",
1235 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1236 return NT_STATUS_LDAP(rc
);
1239 return NT_STATUS_OK
;
1242 static NTSTATUS
pdb_ads_set_aliasinfo(struct pdb_methods
*m
,
1243 const struct dom_sid
*sid
,
1244 struct acct_info
*info
)
1246 struct pdb_ads_state
*state
= talloc_get_type_abort(
1247 m
->private_data
, struct pdb_ads_state
);
1248 struct tldap_context
*ld
;
1249 const char *attrs
[3] = { "objectSid", "description",
1251 struct tldap_message
**msg
;
1254 struct tldap_mod
*mods
;
1258 ld
= pdb_ads_ld(state
);
1260 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1263 sidstr
= sid_binstring(talloc_tos(), sid
);
1264 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1266 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1267 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1268 &msg
, "(&(objectSid=%s)(objectclass=group)"
1269 "(|(grouptype=%d)(grouptype=%d)))",
1270 sidstr
, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1271 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1272 TALLOC_FREE(sidstr
);
1273 if (rc
!= TLDAP_SUCCESS
) {
1274 DEBUG(10, ("ldap_search failed %s\n",
1275 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1276 return NT_STATUS_LDAP(rc
);
1278 switch talloc_array_length(msg
) {
1280 return NT_STATUS_NO_SUCH_ALIAS
;
1284 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1287 if (!tldap_entry_dn(msg
[0], &dn
)) {
1289 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1296 ok
&= tldap_make_mod_fmt(
1297 msg
[0], msg
, &num_mods
, &mods
, "description",
1298 "%s", info
->acct_desc
);
1299 ok
&= tldap_make_mod_fmt(
1300 msg
[0], msg
, &num_mods
, &mods
, "samAccountName",
1301 "%s", info
->acct_name
);
1304 return NT_STATUS_NO_MEMORY
;
1306 if (num_mods
== 0) {
1309 return NT_STATUS_OK
;
1312 rc
= tldap_modify(ld
, dn
, num_mods
, mods
, NULL
, 0, NULL
, 0);
1314 if (rc
!= TLDAP_SUCCESS
) {
1315 DEBUG(10, ("ldap_modify failed: %s\n",
1316 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1317 return NT_STATUS_LDAP(rc
);
1319 return NT_STATUS_OK
;
1322 static NTSTATUS
pdb_ads_sid2dn(struct pdb_ads_state
*state
,
1323 const struct dom_sid
*sid
,
1324 TALLOC_CTX
*mem_ctx
, char **pdn
)
1326 struct tldap_message
**msg
;
1330 sidstr
= sid_binstring(talloc_tos(), sid
);
1331 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1333 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1334 NULL
, 0, 0, talloc_tos(), &msg
,
1335 "(objectsid=%s)", sidstr
);
1336 TALLOC_FREE(sidstr
);
1337 if (rc
!= TLDAP_SUCCESS
) {
1338 DEBUG(10, ("ldap_search failed %s\n",
1339 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1340 return NT_STATUS_LDAP(rc
);
1343 switch talloc_array_length(msg
) {
1345 return NT_STATUS_NOT_FOUND
;
1349 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1352 if (!tldap_entry_dn(msg
[0], &dn
)) {
1353 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1356 dn
= talloc_strdup(mem_ctx
, dn
);
1358 return NT_STATUS_NO_MEMORY
;
1363 return NT_STATUS_OK
;
1366 static NTSTATUS
pdb_ads_mod_aliasmem(struct pdb_methods
*m
,
1367 const struct dom_sid
*alias
,
1368 const struct dom_sid
*member
,
1371 struct pdb_ads_state
*state
= talloc_get_type_abort(
1372 m
->private_data
, struct pdb_ads_state
);
1373 struct tldap_context
*ld
;
1374 TALLOC_CTX
*frame
= talloc_stackframe();
1375 struct tldap_mod
*mods
;
1377 char *aliasdn
, *memberdn
;
1380 ld
= pdb_ads_ld(state
);
1382 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1385 status
= pdb_ads_sid2dn(state
, alias
, talloc_tos(), &aliasdn
);
1386 if (!NT_STATUS_IS_OK(status
)) {
1387 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1388 sid_string_dbg(alias
), nt_errstr(status
)));
1390 return NT_STATUS_NO_SUCH_ALIAS
;
1392 status
= pdb_ads_sid2dn(state
, member
, talloc_tos(), &memberdn
);
1393 if (!NT_STATUS_IS_OK(status
)) {
1394 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1395 sid_string_dbg(member
), nt_errstr(status
)));
1402 if (!tldap_add_mod_str(talloc_tos(), &mods
, mod_op
,
1403 "member", memberdn
)) {
1405 return NT_STATUS_NO_MEMORY
;
1408 rc
= tldap_modify(ld
, aliasdn
, 1, mods
, NULL
, 0, NULL
, 0);
1410 if (rc
!= TLDAP_SUCCESS
) {
1411 DEBUG(10, ("ldap_modify failed: %s\n",
1412 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1413 if (rc
== TLDAP_TYPE_OR_VALUE_EXISTS
) {
1414 return NT_STATUS_MEMBER_IN_ALIAS
;
1416 if (rc
== TLDAP_NO_SUCH_ATTRIBUTE
) {
1417 return NT_STATUS_MEMBER_NOT_IN_ALIAS
;
1419 return NT_STATUS_LDAP(rc
);
1422 return NT_STATUS_OK
;
1425 static NTSTATUS
pdb_ads_add_aliasmem(struct pdb_methods
*m
,
1426 const struct dom_sid
*alias
,
1427 const struct dom_sid
*member
)
1429 return pdb_ads_mod_aliasmem(m
, alias
, member
, TLDAP_MOD_ADD
);
1432 static NTSTATUS
pdb_ads_del_aliasmem(struct pdb_methods
*m
,
1433 const struct dom_sid
*alias
,
1434 const struct dom_sid
*member
)
1436 return pdb_ads_mod_aliasmem(m
, alias
, member
, TLDAP_MOD_DELETE
);
1439 static bool pdb_ads_dnblob2sid(struct pdb_ads_state
*state
, DATA_BLOB
*dnblob
,
1440 struct dom_sid
*psid
)
1442 const char *attrs
[1] = { "objectSid" };
1443 struct tldap_message
**msg
;
1449 if (!convert_string_talloc(talloc_tos(), CH_UTF8
, CH_UNIX
,
1450 dnblob
->data
, dnblob
->length
, &dn
, &len
,
1454 rc
= pdb_ads_search_fmt(state
, dn
, TLDAP_SCOPE_BASE
,
1455 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1456 &msg
, "(objectclass=*)");
1458 if (talloc_array_length(msg
) != 1) {
1459 DEBUG(10, ("Got %d objects, expected one\n",
1460 (int)talloc_array_length(msg
)));
1465 ret
= tldap_pull_binsid(msg
[0], "objectSid", psid
);
1470 static NTSTATUS
pdb_ads_enum_aliasmem(struct pdb_methods
*m
,
1471 const struct dom_sid
*alias
,
1472 TALLOC_CTX
*mem_ctx
,
1473 struct dom_sid
**pmembers
,
1474 size_t *pnum_members
)
1476 struct pdb_ads_state
*state
= talloc_get_type_abort(
1477 m
->private_data
, struct pdb_ads_state
);
1478 const char *attrs
[1] = { "member" };
1480 struct tldap_message
**msg
;
1481 int i
, rc
, num_members
;
1483 struct dom_sid
*members
;
1485 sidstr
= sid_binstring(talloc_tos(), alias
);
1486 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1488 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1489 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1490 &msg
, "(objectsid=%s)", sidstr
);
1491 TALLOC_FREE(sidstr
);
1492 if (rc
!= TLDAP_SUCCESS
) {
1493 DEBUG(10, ("ldap_search failed %s\n",
1494 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1495 return NT_STATUS_LDAP(rc
);
1497 switch talloc_array_length(msg
) {
1499 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1504 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1508 if (!tldap_entry_values(msg
[0], "member", &num_members
, &blobs
)) {
1509 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1512 members
= talloc_array(mem_ctx
, struct dom_sid
, num_members
);
1513 if (members
== NULL
) {
1514 return NT_STATUS_NO_MEMORY
;
1517 for (i
=0; i
<num_members
; i
++) {
1518 if (!pdb_ads_dnblob2sid(state
, &blobs
[i
], &members
[i
])) {
1519 TALLOC_FREE(members
);
1520 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1524 *pmembers
= members
;
1525 *pnum_members
= num_members
;
1526 return NT_STATUS_OK
;
1529 static NTSTATUS
pdb_ads_enum_alias_memberships(struct pdb_methods
*m
,
1530 TALLOC_CTX
*mem_ctx
,
1531 const struct dom_sid
*domain_sid
,
1532 const struct dom_sid
*members
,
1534 uint32_t **palias_rids
,
1535 size_t *pnum_alias_rids
)
1537 struct pdb_ads_state
*state
= talloc_get_type_abort(
1538 m
->private_data
, struct pdb_ads_state
);
1539 const char *attrs
[1] = { "objectSid" };
1540 struct tldap_message
**msg
= NULL
;
1541 uint32_t *alias_rids
= NULL
;
1542 size_t num_alias_rids
= 0;
1544 bool got_members
= false;
1549 * TODO: Get the filter right so that we only get the aliases from
1550 * either the SAM or BUILTIN
1553 filter
= talloc_asprintf(talloc_tos(),
1554 "(&(|(grouptype=%d)(grouptype=%d))"
1555 "(objectclass=group)(|",
1556 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1557 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1558 if (filter
== NULL
) {
1559 return NT_STATUS_NO_MEMORY
;
1562 for (i
=0; i
<num_members
; i
++) {
1565 status
= pdb_ads_sid2dn(state
, &members
[i
], talloc_tos(), &dn
);
1566 if (!NT_STATUS_IS_OK(status
)) {
1567 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1568 sid_string_dbg(&members
[i
]),
1569 nt_errstr(status
)));
1572 filter
= talloc_asprintf_append_buffer(
1573 filter
, "(member=%s)", dn
);
1575 if (filter
== NULL
) {
1576 return NT_STATUS_NO_MEMORY
;
1585 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1586 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1587 &msg
, "%s))", filter
);
1588 TALLOC_FREE(filter
);
1589 if (rc
!= TLDAP_SUCCESS
) {
1590 DEBUG(10, ("tldap_search failed %s\n",
1591 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1592 return NT_STATUS_LDAP(rc
);
1595 count
= talloc_array_length(msg
);
1600 alias_rids
= talloc_array(mem_ctx
, uint32_t, count
);
1601 if (alias_rids
== NULL
) {
1603 return NT_STATUS_NO_MEMORY
;
1606 for (i
=0; i
<count
; i
++) {
1609 if (!tldap_pull_binsid(msg
[i
], "objectSid", &sid
)) {
1610 DEBUG(10, ("Could not pull SID for member %d\n", i
));
1613 if (sid_peek_check_rid(domain_sid
, &sid
,
1614 &alias_rids
[num_alias_rids
])) {
1615 num_alias_rids
+= 1;
1620 *palias_rids
= alias_rids
;
1621 *pnum_alias_rids
= 0;
1622 return NT_STATUS_OK
;
1625 static NTSTATUS
pdb_ads_lookup_rids(struct pdb_methods
*m
,
1626 const struct dom_sid
*domain_sid
,
1630 enum lsa_SidType
*lsa_attrs
)
1632 struct pdb_ads_state
*state
= talloc_get_type_abort(
1633 m
->private_data
, struct pdb_ads_state
);
1634 const char *attrs
[2] = { "sAMAccountType", "sAMAccountName" };
1637 if (num_rids
== 0) {
1638 return NT_STATUS_NONE_MAPPED
;
1643 for (i
=0; i
<num_rids
; i
++) {
1645 struct tldap_message
**msg
;
1650 lsa_attrs
[i
] = SID_NAME_UNKNOWN
;
1652 sid_compose(&sid
, domain_sid
, rids
[i
]);
1654 sidstr
= sid_binstring(talloc_tos(), &sid
);
1655 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1657 rc
= pdb_ads_search_fmt(state
, state
->domaindn
,
1658 TLDAP_SCOPE_SUB
, attrs
,
1659 ARRAY_SIZE(attrs
), 0, talloc_tos(),
1660 &msg
, "(objectsid=%s)", sidstr
);
1661 TALLOC_FREE(sidstr
);
1662 if (rc
!= TLDAP_SUCCESS
) {
1663 DEBUG(10, ("ldap_search failed %s\n",
1664 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1668 switch talloc_array_length(msg
) {
1670 DEBUG(10, ("rid %d not found\n", (int)rids
[i
]));
1675 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1678 names
[i
] = tldap_talloc_single_attribute(
1679 msg
[0], "samAccountName", talloc_tos());
1680 if (names
[i
] == NULL
) {
1681 DEBUG(10, ("no samAccountName\n"));
1684 if (!tldap_pull_uint32(msg
[0], "samAccountType", &attr
)) {
1685 DEBUG(10, ("no samAccountType"));
1688 lsa_attrs
[i
] = ds_atype_map(attr
);
1692 if (num_mapped
== 0) {
1693 return NT_STATUS_NONE_MAPPED
;
1695 if (num_mapped
< num_rids
) {
1696 return STATUS_SOME_UNMAPPED
;
1698 return NT_STATUS_OK
;
1701 static NTSTATUS
pdb_ads_lookup_names(struct pdb_methods
*m
,
1702 const struct dom_sid
*domain_sid
,
1704 const char **pp_names
,
1706 enum lsa_SidType
*attrs
)
1708 return NT_STATUS_NOT_IMPLEMENTED
;
1711 static NTSTATUS
pdb_ads_get_account_policy(struct pdb_methods
*m
,
1712 enum pdb_policy_type type
,
1715 return account_policy_get(type
, value
)
1716 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1719 static NTSTATUS
pdb_ads_set_account_policy(struct pdb_methods
*m
,
1720 enum pdb_policy_type type
,
1723 return account_policy_set(type
, value
)
1724 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1727 static NTSTATUS
pdb_ads_get_seq_num(struct pdb_methods
*m
,
1730 return NT_STATUS_NOT_IMPLEMENTED
;
1733 struct pdb_ads_search_state
{
1734 uint32_t acct_flags
;
1735 struct samr_displayentry
*entries
;
1736 uint32_t num_entries
;
1741 static bool pdb_ads_next_entry(struct pdb_search
*search
,
1742 struct samr_displayentry
*entry
)
1744 struct pdb_ads_search_state
*state
= talloc_get_type_abort(
1745 search
->private_data
, struct pdb_ads_search_state
);
1747 if (state
->current
== state
->num_entries
) {
1751 entry
->idx
= state
->entries
[state
->current
].idx
;
1752 entry
->rid
= state
->entries
[state
->current
].rid
;
1753 entry
->acct_flags
= state
->entries
[state
->current
].acct_flags
;
1755 entry
->account_name
= talloc_strdup(
1756 search
, state
->entries
[state
->current
].account_name
);
1757 entry
->fullname
= talloc_strdup(
1758 search
, state
->entries
[state
->current
].fullname
);
1759 entry
->description
= talloc_strdup(
1760 search
, state
->entries
[state
->current
].description
);
1762 if ((entry
->account_name
== NULL
) || (entry
->fullname
== NULL
)
1763 || (entry
->description
== NULL
)) {
1764 DEBUG(0, ("talloc_strdup failed\n"));
1768 state
->current
+= 1;
1772 static void pdb_ads_search_end(struct pdb_search
*search
)
1774 struct pdb_ads_search_state
*state
= talloc_get_type_abort(
1775 search
->private_data
, struct pdb_ads_search_state
);
1779 static bool pdb_ads_search_filter(struct pdb_methods
*m
,
1780 struct pdb_search
*search
,
1782 struct pdb_ads_search_state
**pstate
)
1784 struct pdb_ads_state
*state
= talloc_get_type_abort(
1785 m
->private_data
, struct pdb_ads_state
);
1786 struct pdb_ads_search_state
*sstate
;
1787 const char * attrs
[] = { "objectSid", "sAMAccountName", "displayName",
1788 "userAccountControl", "description" };
1789 struct tldap_message
**users
;
1790 int i
, rc
, num_users
;
1792 sstate
= talloc_zero(search
, struct pdb_ads_search_state
);
1793 if (sstate
== NULL
) {
1797 rc
= pdb_ads_search_fmt(
1798 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1799 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &users
,
1801 if (rc
!= TLDAP_SUCCESS
) {
1802 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1803 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1807 num_users
= talloc_array_length(users
);
1809 sstate
->entries
= talloc_array(sstate
, struct samr_displayentry
,
1811 if (sstate
->entries
== NULL
) {
1812 DEBUG(10, ("talloc failed\n"));
1816 sstate
->num_entries
= 0;
1818 for (i
=0; i
<num_users
; i
++) {
1819 struct samr_displayentry
*e
;
1822 e
= &sstate
->entries
[sstate
->num_entries
];
1824 e
->idx
= sstate
->num_entries
;
1825 if (!tldap_pull_binsid(users
[i
], "objectSid", &sid
)) {
1826 DEBUG(10, ("Could not pull sid\n"));
1829 sid_peek_rid(&sid
, &e
->rid
);
1830 e
->acct_flags
= ACB_NORMAL
;
1831 e
->account_name
= tldap_talloc_single_attribute(
1832 users
[i
], "samAccountName", sstate
->entries
);
1833 if (e
->account_name
== NULL
) {
1836 e
->fullname
= tldap_talloc_single_attribute(
1837 users
[i
], "displayName", sstate
->entries
);
1838 if (e
->fullname
== NULL
) {
1841 e
->description
= tldap_talloc_single_attribute(
1842 users
[i
], "description", sstate
->entries
);
1843 if (e
->description
== NULL
) {
1844 e
->description
= "";
1847 sstate
->num_entries
+= 1;
1848 if (sstate
->num_entries
>= num_users
) {
1853 search
->private_data
= sstate
;
1854 search
->next_entry
= pdb_ads_next_entry
;
1855 search
->search_end
= pdb_ads_search_end
;
1860 static bool pdb_ads_search_users(struct pdb_methods
*m
,
1861 struct pdb_search
*search
,
1864 struct pdb_ads_search_state
*sstate
;
1867 ret
= pdb_ads_search_filter(m
, search
, "(objectclass=user)", &sstate
);
1871 sstate
->acct_flags
= acct_flags
;
1875 static bool pdb_ads_search_groups(struct pdb_methods
*m
,
1876 struct pdb_search
*search
)
1878 struct pdb_ads_search_state
*sstate
;
1882 filter
= talloc_asprintf(talloc_tos(),
1883 "(&(grouptype=%d)(objectclass=group))",
1884 GTYPE_SECURITY_GLOBAL_GROUP
);
1885 if (filter
== NULL
) {
1888 ret
= pdb_ads_search_filter(m
, search
, filter
, &sstate
);
1889 TALLOC_FREE(filter
);
1893 sstate
->acct_flags
= 0;
1897 static bool pdb_ads_search_aliases(struct pdb_methods
*m
,
1898 struct pdb_search
*search
,
1899 const struct dom_sid
*sid
)
1901 struct pdb_ads_search_state
*sstate
;
1905 filter
= talloc_asprintf(
1906 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1907 sid_check_is_builtin(sid
)
1908 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1909 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1911 if (filter
== NULL
) {
1914 ret
= pdb_ads_search_filter(m
, search
, filter
, &sstate
);
1915 TALLOC_FREE(filter
);
1919 sstate
->acct_flags
= 0;
1923 static bool pdb_ads_uid_to_sid(struct pdb_methods
*m
, uid_t uid
,
1924 struct dom_sid
*sid
)
1926 struct pdb_ads_state
*state
= talloc_get_type_abort(
1927 m
->private_data
, struct pdb_ads_state
);
1928 sid_compose(sid
, &state
->domainsid
, uid
);
1932 static bool pdb_ads_gid_to_sid(struct pdb_methods
*m
, gid_t gid
,
1933 struct dom_sid
*sid
)
1935 struct pdb_ads_state
*state
= talloc_get_type_abort(
1936 m
->private_data
, struct pdb_ads_state
);
1937 sid_compose(sid
, &state
->domainsid
, gid
);
1941 static bool pdb_ads_sid_to_id(struct pdb_methods
*m
, const struct dom_sid
*sid
,
1942 union unid_t
*id
, enum lsa_SidType
*type
)
1944 struct pdb_ads_state
*state
= talloc_get_type_abort(
1945 m
->private_data
, struct pdb_ads_state
);
1946 struct tldap_message
**msg
;
1952 * This is a big, big hack: Just hard-code the rid as uid/gid.
1955 sid_peek_rid(sid
, &rid
);
1957 sidstr
= sid_binstring(talloc_tos(), sid
);
1958 if (sidstr
== NULL
) {
1962 rc
= pdb_ads_search_fmt(
1963 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1964 NULL
, 0, 0, talloc_tos(), &msg
,
1965 "(&(objectsid=%s)(objectclass=user))", sidstr
);
1966 if ((rc
== TLDAP_SUCCESS
) && (talloc_array_length(msg
) > 0)) {
1968 *type
= SID_NAME_USER
;
1969 TALLOC_FREE(sidstr
);
1973 rc
= pdb_ads_search_fmt(
1974 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1975 NULL
, 0, 0, talloc_tos(), &msg
,
1976 "(&(objectsid=%s)(objectclass=group))", sidstr
);
1977 if ((rc
== TLDAP_SUCCESS
) && (talloc_array_length(msg
) > 0)) {
1979 *type
= SID_NAME_DOM_GRP
;
1980 TALLOC_FREE(sidstr
);
1984 TALLOC_FREE(sidstr
);
1988 static uint32_t pdb_ads_capabilities(struct pdb_methods
*m
)
1990 return PDB_CAP_STORE_RIDS
| PDB_CAP_ADS
;
1993 static bool pdb_ads_new_rid(struct pdb_methods
*m
, uint32
*rid
)
1998 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods
*m
,
1999 const char *domain
, char** pwd
,
2000 struct dom_sid
*sid
,
2001 time_t *pass_last_set_time
)
2006 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods
*m
,
2007 const char* domain
, const char* pwd
,
2008 const struct dom_sid
*sid
)
2013 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods
*m
,
2019 static NTSTATUS
pdb_ads_enum_trusteddoms(struct pdb_methods
*m
,
2020 TALLOC_CTX
*mem_ctx
,
2021 uint32
*num_domains
,
2022 struct trustdom_info
***domains
)
2026 return NT_STATUS_OK
;
2029 static void pdb_ads_init_methods(struct pdb_methods
*m
)
2032 m
->get_domain_info
= pdb_ads_get_domain_info
;
2033 m
->getsampwnam
= pdb_ads_getsampwnam
;
2034 m
->getsampwsid
= pdb_ads_getsampwsid
;
2035 m
->create_user
= pdb_ads_create_user
;
2036 m
->delete_user
= pdb_ads_delete_user
;
2037 m
->add_sam_account
= pdb_ads_add_sam_account
;
2038 m
->update_sam_account
= pdb_ads_update_sam_account
;
2039 m
->delete_sam_account
= pdb_ads_delete_sam_account
;
2040 m
->rename_sam_account
= pdb_ads_rename_sam_account
;
2041 m
->update_login_attempts
= pdb_ads_update_login_attempts
;
2042 m
->getgrsid
= pdb_ads_getgrsid
;
2043 m
->getgrgid
= pdb_ads_getgrgid
;
2044 m
->getgrnam
= pdb_ads_getgrnam
;
2045 m
->create_dom_group
= pdb_ads_create_dom_group
;
2046 m
->delete_dom_group
= pdb_ads_delete_dom_group
;
2047 m
->add_group_mapping_entry
= pdb_ads_add_group_mapping_entry
;
2048 m
->update_group_mapping_entry
= pdb_ads_update_group_mapping_entry
;
2049 m
->delete_group_mapping_entry
= pdb_ads_delete_group_mapping_entry
;
2050 m
->enum_group_mapping
= pdb_ads_enum_group_mapping
;
2051 m
->enum_group_members
= pdb_ads_enum_group_members
;
2052 m
->enum_group_memberships
= pdb_ads_enum_group_memberships
;
2053 m
->set_unix_primary_group
= pdb_ads_set_unix_primary_group
;
2054 m
->add_groupmem
= pdb_ads_add_groupmem
;
2055 m
->del_groupmem
= pdb_ads_del_groupmem
;
2056 m
->create_alias
= pdb_ads_create_alias
;
2057 m
->delete_alias
= pdb_ads_delete_alias
;
2058 m
->get_aliasinfo
= pdb_default_get_aliasinfo
;
2059 m
->set_aliasinfo
= pdb_ads_set_aliasinfo
;
2060 m
->add_aliasmem
= pdb_ads_add_aliasmem
;
2061 m
->del_aliasmem
= pdb_ads_del_aliasmem
;
2062 m
->enum_aliasmem
= pdb_ads_enum_aliasmem
;
2063 m
->enum_alias_memberships
= pdb_ads_enum_alias_memberships
;
2064 m
->lookup_rids
= pdb_ads_lookup_rids
;
2065 m
->lookup_names
= pdb_ads_lookup_names
;
2066 m
->get_account_policy
= pdb_ads_get_account_policy
;
2067 m
->set_account_policy
= pdb_ads_set_account_policy
;
2068 m
->get_seq_num
= pdb_ads_get_seq_num
;
2069 m
->search_users
= pdb_ads_search_users
;
2070 m
->search_groups
= pdb_ads_search_groups
;
2071 m
->search_aliases
= pdb_ads_search_aliases
;
2072 m
->uid_to_sid
= pdb_ads_uid_to_sid
;
2073 m
->gid_to_sid
= pdb_ads_gid_to_sid
;
2074 m
->sid_to_id
= pdb_ads_sid_to_id
;
2075 m
->capabilities
= pdb_ads_capabilities
;
2076 m
->new_rid
= pdb_ads_new_rid
;
2077 m
->get_trusteddom_pw
= pdb_ads_get_trusteddom_pw
;
2078 m
->set_trusteddom_pw
= pdb_ads_set_trusteddom_pw
;
2079 m
->del_trusteddom_pw
= pdb_ads_del_trusteddom_pw
;
2080 m
->enum_trusteddoms
= pdb_ads_enum_trusteddoms
;
2083 static void free_private_data(void **vp
)
2085 struct pdb_ads_state
*state
= talloc_get_type_abort(
2086 *vp
, struct pdb_ads_state
);
2088 TALLOC_FREE(state
->ld
);
2093 this is used to catch debug messages from events
2095 static void s3_tldap_debug(void *context
, enum tldap_debug_level level
,
2096 const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(3,0);
2098 static void s3_tldap_debug(void *context
, enum tldap_debug_level level
,
2099 const char *fmt
, va_list ap
)
2101 int samba_level
= -1;
2104 case TLDAP_DEBUG_FATAL
:
2107 case TLDAP_DEBUG_ERROR
:
2110 case TLDAP_DEBUG_WARNING
:
2113 case TLDAP_DEBUG_TRACE
:
2118 if (vasprintf(&s
, fmt
, ap
) == -1) {
2121 DEBUG(samba_level
, ("tldap: %s", s
));
2125 static struct tldap_context
*pdb_ads_ld(struct pdb_ads_state
*state
)
2130 if (tldap_connection_ok(state
->ld
)) {
2133 TALLOC_FREE(state
->ld
);
2135 status
= open_socket_out(
2136 (struct sockaddr_storage
*)(void *)&state
->socket_address
,
2138 if (!NT_STATUS_IS_OK(status
)) {
2139 DEBUG(10, ("Could not connect to %s: %s\n",
2140 state
->socket_address
.sun_path
, nt_errstr(status
)));
2144 set_blocking(fd
, false);
2146 state
->ld
= tldap_context_create(state
, fd
);
2147 if (state
->ld
== NULL
) {
2151 tldap_set_debug(state
->ld
, s3_tldap_debug
, NULL
);
2156 int pdb_ads_search_fmt(struct pdb_ads_state
*state
, const char *base
,
2157 int scope
, const char *attrs
[], int num_attrs
,
2159 TALLOC_CTX
*mem_ctx
, struct tldap_message
***res
,
2160 const char *fmt
, ...)
2162 struct tldap_context
*ld
;
2166 ld
= pdb_ads_ld(state
);
2168 return TLDAP_SERVER_DOWN
;
2172 ret
= tldap_search_va(ld
, base
, scope
, attrs
, num_attrs
, attrsonly
,
2173 mem_ctx
, res
, fmt
, ap
);
2176 if (ret
!= TLDAP_SERVER_DOWN
) {
2181 ld
= pdb_ads_ld(state
);
2183 return TLDAP_SERVER_DOWN
;
2187 ret
= tldap_search_va(ld
, base
, scope
, attrs
, num_attrs
, attrsonly
,
2188 mem_ctx
, res
, fmt
, ap
);
2193 static NTSTATUS
pdb_ads_connect(struct pdb_ads_state
*state
,
2194 const char *location
)
2196 const char *domain_attrs
[2] = { "objectSid", "objectGUID" };
2197 const char *ncname_attrs
[1] = { "netbiosname" };
2198 struct tldap_context
*ld
;
2199 struct tldap_message
*rootdse
, **domain
, **ncname
;
2200 TALLOC_CTX
*frame
= talloc_stackframe();
2205 ZERO_STRUCT(state
->socket_address
);
2206 state
->socket_address
.sun_family
= AF_UNIX
;
2207 strncpy(state
->socket_address
.sun_path
, location
,
2208 sizeof(state
->socket_address
.sun_path
) - 1);
2210 ld
= pdb_ads_ld(state
);
2212 status
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2216 rc
= tldap_fetch_rootdse(ld
);
2217 if (rc
!= TLDAP_SUCCESS
) {
2218 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2219 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2220 status
= NT_STATUS_LDAP(rc
);
2223 rootdse
= tldap_rootdse(state
->ld
);
2225 state
->domaindn
= tldap_talloc_single_attribute(
2226 rootdse
, "defaultNamingContext", state
);
2227 if (state
->domaindn
== NULL
) {
2228 DEBUG(10, ("Could not get defaultNamingContext\n"));
2229 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2232 DEBUG(10, ("defaultNamingContext = %s\n", state
->domaindn
));
2234 state
->configdn
= tldap_talloc_single_attribute(
2235 rootdse
, "configurationNamingContext", state
);
2236 if (state
->domaindn
== NULL
) {
2237 DEBUG(10, ("Could not get configurationNamingContext\n"));
2238 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2241 DEBUG(10, ("configurationNamingContext = %s\n", state
->configdn
));
2244 * Figure out our domain's SID
2246 rc
= pdb_ads_search_fmt(
2247 state
, state
->domaindn
, TLDAP_SCOPE_BASE
,
2248 domain_attrs
, ARRAY_SIZE(domain_attrs
), 0,
2249 talloc_tos(), &domain
, "(objectclass=*)");
2250 if (rc
!= TLDAP_SUCCESS
) {
2251 DEBUG(10, ("Could not retrieve domain: %s\n",
2252 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2253 status
= NT_STATUS_LDAP(rc
);
2257 num_domains
= talloc_array_length(domain
);
2258 if (num_domains
!= 1) {
2259 DEBUG(10, ("Got %d domains, expected one\n", num_domains
));
2260 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2263 if (!tldap_pull_binsid(domain
[0], "objectSid", &state
->domainsid
)) {
2264 DEBUG(10, ("Could not retrieve domain SID\n"));
2265 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2268 if (!tldap_pull_guid(domain
[0], "objectGUID", &state
->domainguid
)) {
2269 DEBUG(10, ("Could not retrieve domain GUID\n"));
2270 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2273 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state
->domainsid
)));
2276 * Figure out our domain's short name
2278 rc
= pdb_ads_search_fmt(
2279 state
, state
->configdn
, TLDAP_SCOPE_SUB
,
2280 ncname_attrs
, ARRAY_SIZE(ncname_attrs
), 0,
2281 talloc_tos(), &ncname
, "(ncname=%s)", state
->domaindn
);
2282 if (rc
!= TLDAP_SUCCESS
) {
2283 DEBUG(10, ("Could not retrieve ncname: %s\n",
2284 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2285 status
= NT_STATUS_LDAP(rc
);
2288 if (talloc_array_length(ncname
) != 1) {
2289 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2293 state
->netbiosname
= tldap_talloc_single_attribute(
2294 ncname
[0], "netbiosname", state
);
2295 if (state
->netbiosname
== NULL
) {
2296 DEBUG(10, ("Could not get netbiosname\n"));
2297 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2300 DEBUG(10, ("netbiosname: %s\n", state
->netbiosname
));
2302 if (!strequal(lp_workgroup(), state
->netbiosname
)) {
2303 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2304 state
->netbiosname
, lp_workgroup()));
2305 status
= NT_STATUS_NO_SUCH_DOMAIN
;
2309 secrets_store_domain_sid(state
->netbiosname
, &state
->domainsid
);
2311 status
= NT_STATUS_OK
;
2317 static NTSTATUS
pdb_init_ads(struct pdb_methods
**pdb_method
,
2318 const char *location
)
2320 struct pdb_methods
*m
;
2321 struct pdb_ads_state
*state
;
2325 m
= talloc(talloc_autofree_context(), struct pdb_methods
);
2327 return NT_STATUS_NO_MEMORY
;
2329 state
= talloc_zero(m
, struct pdb_ads_state
);
2330 if (state
== NULL
) {
2333 m
->private_data
= state
;
2334 m
->free_private_data
= free_private_data
;
2335 pdb_ads_init_methods(m
);
2337 if (location
== NULL
) {
2338 tmp
= talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2342 if (location
== NULL
) {
2346 status
= pdb_ads_connect(state
, location
);
2347 if (!NT_STATUS_IS_OK(status
)) {
2348 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status
)));
2353 return NT_STATUS_OK
;
2355 status
= NT_STATUS_NO_MEMORY
;
2361 NTSTATUS
pdb_ads_init(void);
2362 NTSTATUS
pdb_ads_init(void)
2364 return smb_register_passdb(PASSDB_INTERFACE_VERSION
, "ads",