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/>.
23 #include "tldap_util.h"
24 #include "../libds/common/flags.h"
26 #include "../librpc/gen_ndr/samr.h"
27 #include "../libcli/ldap/ldap_ndr.h"
28 #include "../libcli/security/security.h"
29 #include "../libds/common/flag_mapping.h"
31 struct pdb_ads_state
{
32 struct sockaddr_un socket_address
;
33 struct tldap_context
*ld
;
34 struct dom_sid domainsid
;
35 struct GUID domainguid
;
41 struct pdb_ads_samu_private
{
43 struct tldap_message
*ldapmsg
;
46 static bool pdb_ads_gid_to_sid(struct pdb_methods
*m
, gid_t gid
,
48 static bool pdb_ads_dnblob2sid(struct pdb_ads_state
*state
, DATA_BLOB
*dnblob
,
49 struct dom_sid
*psid
);
50 static NTSTATUS
pdb_ads_sid2dn(struct pdb_ads_state
*state
,
51 const struct dom_sid
*sid
,
52 TALLOC_CTX
*mem_ctx
, char **pdn
);
53 static struct tldap_context
*pdb_ads_ld(struct pdb_ads_state
*state
);
54 static int pdb_ads_search_fmt(struct pdb_ads_state
*state
, const char *base
,
55 int scope
, const char *attrs
[], int num_attrs
,
57 TALLOC_CTX
*mem_ctx
, struct tldap_message
***res
,
58 const char *fmt
, ...);
59 static NTSTATUS
pdb_ads_getsamupriv(struct pdb_ads_state
*state
,
62 struct pdb_ads_samu_private
**presult
);
64 static bool pdb_ads_pull_time(struct tldap_message
*msg
, const char *attr
,
69 if (!tldap_pull_uint64(msg
, attr
, &tmp
)) {
72 *ptime
= nt_time_to_unix(tmp
);
76 static gid_t
pdb_ads_sid2gid(const struct dom_sid
*sid
)
79 sid_peek_rid(sid
, &rid
);
83 static char *pdb_ads_domaindn2dns(TALLOC_CTX
*mem_ctx
, char *dn
)
87 result
= talloc_string_sub2(mem_ctx
, dn
, "DC=", "", false, false,
93 while ((p
= strchr_m(result
, ',')) != NULL
) {
100 static struct pdb_domain_info
*pdb_ads_get_domain_info(
101 struct pdb_methods
*m
, TALLOC_CTX
*mem_ctx
)
103 struct pdb_ads_state
*state
= talloc_get_type_abort(
104 m
->private_data
, struct pdb_ads_state
);
105 struct pdb_domain_info
*info
;
106 struct tldap_message
*rootdse
;
109 info
= talloc(mem_ctx
, struct pdb_domain_info
);
113 info
->name
= talloc_strdup(info
, state
->netbiosname
);
114 if (info
->name
== NULL
) {
117 info
->dns_domain
= pdb_ads_domaindn2dns(info
, state
->domaindn
);
118 if (info
->dns_domain
== NULL
) {
122 rootdse
= tldap_rootdse(state
->ld
);
123 tmp
= tldap_talloc_single_attribute(rootdse
, "rootDomainNamingContext",
128 info
->dns_forest
= pdb_ads_domaindn2dns(info
, tmp
);
130 if (info
->dns_forest
== NULL
) {
133 info
->sid
= state
->domainsid
;
134 info
->guid
= state
->domainguid
;
142 static struct pdb_ads_samu_private
*pdb_ads_get_samu_private(
143 struct pdb_methods
*m
, struct samu
*sam
)
145 struct pdb_ads_state
*state
= talloc_get_type_abort(
146 m
->private_data
, struct pdb_ads_state
);
147 struct pdb_ads_samu_private
*result
;
148 char *sidstr
, *filter
;
151 result
= (struct pdb_ads_samu_private
*)
152 pdb_get_backend_private_data(sam
, m
);
154 if (result
!= NULL
) {
155 return talloc_get_type_abort(
156 result
, struct pdb_ads_samu_private
);
159 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), pdb_get_user_sid(sam
));
160 if (sidstr
== NULL
) {
164 filter
= talloc_asprintf(
165 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr
);
167 if (filter
== NULL
) {
171 status
= pdb_ads_getsamupriv(state
, filter
, sam
, &result
);
173 if (!NT_STATUS_IS_OK(status
)) {
180 static NTSTATUS
pdb_ads_init_sam_from_priv(struct pdb_methods
*m
,
182 struct pdb_ads_samu_private
*priv
)
184 struct pdb_ads_state
*state
= talloc_get_type_abort(
185 m
->private_data
, struct pdb_ads_state
);
186 TALLOC_CTX
*frame
= talloc_stackframe();
187 NTSTATUS status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
188 struct tldap_message
*entry
= priv
->ldapmsg
;
196 str
= tldap_talloc_single_attribute(entry
, "samAccountName", sam
);
198 DEBUG(10, ("no samAccountName\n"));
201 pdb_set_username(sam
, str
, PDB_SET
);
203 if (pdb_ads_pull_time(entry
, "lastLogon", &tmp_time
)) {
204 pdb_set_logon_time(sam
, tmp_time
, PDB_SET
);
206 if (pdb_ads_pull_time(entry
, "lastLogoff", &tmp_time
)) {
207 pdb_set_logoff_time(sam
, tmp_time
, PDB_SET
);
209 if (pdb_ads_pull_time(entry
, "pwdLastSet", &tmp_time
)) {
210 pdb_set_pass_last_set_time(sam
, tmp_time
, PDB_SET
);
212 if (pdb_ads_pull_time(entry
, "accountExpires", &tmp_time
)) {
213 pdb_set_kickoff_time(sam
, tmp_time
, PDB_SET
);
216 str
= tldap_talloc_single_attribute(entry
, "displayName",
219 pdb_set_fullname(sam
, str
, PDB_SET
);
222 str
= tldap_talloc_single_attribute(entry
, "homeDirectory",
225 pdb_set_homedir(sam
, str
, PDB_SET
);
228 str
= tldap_talloc_single_attribute(entry
, "homeDrive", talloc_tos());
230 pdb_set_dir_drive(sam
, str
, PDB_SET
);
233 str
= tldap_talloc_single_attribute(entry
, "scriptPath", talloc_tos());
235 pdb_set_logon_script(sam
, str
, PDB_SET
);
238 str
= tldap_talloc_single_attribute(entry
, "profilePath",
241 pdb_set_profile_path(sam
, str
, PDB_SET
);
244 str
= tldap_talloc_single_attribute(entry
, "profilePath",
247 pdb_set_profile_path(sam
, str
, PDB_SET
);
250 str
= tldap_talloc_single_attribute(entry
, "comment",
253 pdb_set_comment(sam
, str
, PDB_SET
);
256 str
= tldap_talloc_single_attribute(entry
, "description",
259 pdb_set_acct_desc(sam
, str
, PDB_SET
);
262 str
= tldap_talloc_single_attribute(entry
, "userWorkstations",
265 pdb_set_workstations(sam
, str
, PDB_SET
);
268 str
= tldap_talloc_single_attribute(entry
, "userParameters",
271 pdb_set_munged_dial(sam
, str
, PDB_SET
);
274 if (!tldap_pull_binsid(entry
, "objectSid", &sid
)) {
275 DEBUG(10, ("Could not pull SID\n"));
278 pdb_set_user_sid(sam
, &sid
, PDB_SET
);
280 if (!tldap_pull_uint64(entry
, "userAccountControl", &n
)) {
281 DEBUG(10, ("Could not pull userAccountControl\n"));
284 pdb_set_acct_ctrl(sam
, ds_uf2acb(n
), PDB_SET
);
286 if (tldap_get_single_valueblob(entry
, "unicodePwd", &blob
)) {
287 if (blob
.length
!= NT_HASH_LEN
) {
288 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
289 (int)blob
.length
, NT_HASH_LEN
));
292 pdb_set_nt_passwd(sam
, blob
.data
, PDB_SET
);
295 if (tldap_get_single_valueblob(entry
, "dBCSPwd", &blob
)) {
296 if (blob
.length
!= LM_HASH_LEN
) {
297 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
298 (int)blob
.length
, LM_HASH_LEN
));
301 pdb_set_lanman_passwd(sam
, blob
.data
, PDB_SET
);
304 if (tldap_pull_uint64(entry
, "primaryGroupID", &n
)) {
305 sid_compose(&sid
, &state
->domainsid
, n
);
306 pdb_set_group_sid(sam
, &sid
, PDB_SET
);
310 if (tldap_pull_uint32(entry
, "countryCode", &i
)) {
311 pdb_set_country_code(sam
, i
, PDB_SET
);
314 if (tldap_pull_uint32(entry
, "codePage", &i
)) {
315 pdb_set_code_page(sam
, i
, PDB_SET
);
318 if (tldap_get_single_valueblob(entry
, "logonHours", &blob
)) {
320 if (blob
.length
> MAX_HOURS_LEN
) {
321 status
= NT_STATUS_INVALID_PARAMETER
;
324 pdb_set_logon_divs(sam
, blob
.length
* 8, PDB_SET
);
325 pdb_set_hours_len(sam
, blob
.length
, PDB_SET
);
326 pdb_set_hours(sam
, blob
.data
, blob
.length
, PDB_SET
);
330 pdb_set_logon_divs(sam
, sizeof(hours
)/8, PDB_SET
);
331 pdb_set_hours_len(sam
, sizeof(hours
), PDB_SET
);
332 memset(hours
, 0xff, sizeof(hours
));
333 pdb_set_hours(sam
, hours
, sizeof(hours
), PDB_SET
);
336 status
= NT_STATUS_OK
;
342 static bool pdb_ads_make_time_mod(struct tldap_message
*existing
,
344 struct tldap_mod
**pmods
, int *pnum_mods
,
345 const char *attrib
, time_t t
)
349 unix_to_nt_time(&nt_time
, t
);
351 return tldap_make_mod_fmt(
352 existing
, mem_ctx
, pmods
, pnum_mods
, attrib
,
356 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state
*state
,
357 struct tldap_message
*existing
,
359 struct tldap_mod
**pmods
, int *pnum_mods
,
366 /* TODO: All fields :-) */
368 ret
&= tldap_make_mod_fmt(
369 existing
, mem_ctx
, pmods
, pnum_mods
, "displayName",
370 "%s", pdb_get_fullname(sam
));
372 pw
= pdb_get_plaintext_passwd(sam
);
375 * If we have the plain text pw, this is probably about to be
376 * set. Is this true always?
383 pw_quote
= talloc_asprintf(talloc_tos(), "\"%s\"", pw
);
384 if (pw_quote
== NULL
) {
389 ret
&= convert_string_talloc(talloc_tos(),
391 pw_quote
, strlen(pw_quote
),
392 &pw_utf16
, &pw_utf16_len
);
396 blob
= data_blob_const(pw_utf16
, pw_utf16_len
);
398 ret
&= tldap_add_mod_blobs(mem_ctx
, pmods
, pnum_mods
,
400 "unicodePwd", &blob
, 1);
401 TALLOC_FREE(pw_utf16
);
402 TALLOC_FREE(pw_quote
);
405 ret
&= tldap_make_mod_fmt(
406 existing
, mem_ctx
, pmods
, pnum_mods
, "userAccountControl",
407 "%d", ds_acb2uf(pdb_get_acct_ctrl(sam
)));
409 ret
&= tldap_make_mod_fmt(
410 existing
, mem_ctx
, pmods
, pnum_mods
, "homeDirectory",
411 "%s", pdb_get_homedir(sam
));
413 ret
&= tldap_make_mod_fmt(
414 existing
, mem_ctx
, pmods
, pnum_mods
, "homeDrive",
415 "%s", pdb_get_dir_drive(sam
));
417 ret
&= tldap_make_mod_fmt(
418 existing
, mem_ctx
, pmods
, pnum_mods
, "scriptPath",
419 "%s", pdb_get_logon_script(sam
));
421 ret
&= tldap_make_mod_fmt(
422 existing
, mem_ctx
, pmods
, pnum_mods
, "profilePath",
423 "%s", pdb_get_profile_path(sam
));
425 ret
&= tldap_make_mod_fmt(
426 existing
, mem_ctx
, pmods
, pnum_mods
, "comment",
427 "%s", pdb_get_comment(sam
));
429 ret
&= tldap_make_mod_fmt(
430 existing
, mem_ctx
, pmods
, pnum_mods
, "description",
431 "%s", pdb_get_acct_desc(sam
));
433 ret
&= tldap_make_mod_fmt(
434 existing
, mem_ctx
, pmods
, pnum_mods
, "userWorkstations",
435 "%s", pdb_get_workstations(sam
));
437 ret
&= tldap_make_mod_fmt(
438 existing
, mem_ctx
, pmods
, pnum_mods
, "userParameters",
439 "%s", pdb_get_munged_dial(sam
));
441 ret
&= tldap_make_mod_fmt(
442 existing
, mem_ctx
, pmods
, pnum_mods
, "countryCode",
443 "%i", (int)pdb_get_country_code(sam
));
445 ret
&= tldap_make_mod_fmt(
446 existing
, mem_ctx
, pmods
, pnum_mods
, "codePage",
447 "%i", (int)pdb_get_code_page(sam
));
449 ret
&= pdb_ads_make_time_mod(
450 existing
, mem_ctx
, pmods
, pnum_mods
, "accountExpires",
451 (int)pdb_get_kickoff_time(sam
));
453 ret
&= tldap_make_mod_blob(
454 existing
, mem_ctx
, pmods
, pnum_mods
, "logonHours",
455 data_blob_const(pdb_get_hours(sam
), pdb_get_hours_len(sam
)));
461 static NTSTATUS
pdb_ads_getsamupriv(struct pdb_ads_state
*state
,
464 struct pdb_ads_samu_private
**presult
)
466 const char * attrs
[] = {
467 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
468 "sAMAccountName", "displayName", "homeDirectory",
469 "homeDrive", "scriptPath", "profilePath", "description",
470 "userWorkstations", "comment", "userParameters", "objectSid",
471 "primaryGroupID", "userAccountControl", "logonHours",
472 "badPwdCount", "logonCount", "countryCode", "codePage",
473 "unicodePwd", "dBCSPwd" };
474 struct tldap_message
**users
;
476 struct pdb_ads_samu_private
*result
;
478 result
= talloc(mem_ctx
, struct pdb_ads_samu_private
);
479 if (result
== NULL
) {
480 return NT_STATUS_NO_MEMORY
;
483 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
484 attrs
, ARRAY_SIZE(attrs
), 0, result
,
485 &users
, "%s", filter
);
486 if (rc
!= TLDAP_SUCCESS
) {
487 DEBUG(10, ("ldap_search failed %s\n",
488 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
490 return NT_STATUS_LDAP(rc
);
493 count
= talloc_array_length(users
);
495 DEBUG(10, ("Expected 1 user, got %d\n", count
));
497 return NT_STATUS_NO_SUCH_USER
;
500 result
->ldapmsg
= users
[0];
501 if (!tldap_entry_dn(result
->ldapmsg
, &result
->dn
)) {
502 DEBUG(10, ("Could not extract dn\n"));
504 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
511 static NTSTATUS
pdb_ads_getsampwfilter(struct pdb_methods
*m
,
512 struct pdb_ads_state
*state
,
513 struct samu
*sam_acct
,
516 struct pdb_ads_samu_private
*priv
;
519 status
= pdb_ads_getsamupriv(state
, filter
, sam_acct
, &priv
);
520 if (!NT_STATUS_IS_OK(status
)) {
521 DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n",
526 status
= pdb_ads_init_sam_from_priv(m
, sam_acct
, priv
);
527 if (!NT_STATUS_IS_OK(status
)) {
528 DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n",
534 pdb_set_backend_private_data(sam_acct
, priv
, NULL
, m
, PDB_SET
);
538 static NTSTATUS
pdb_ads_getsampwnam(struct pdb_methods
*m
,
539 struct samu
*sam_acct
,
540 const char *username
)
542 struct pdb_ads_state
*state
= talloc_get_type_abort(
543 m
->private_data
, struct pdb_ads_state
);
546 filter
= talloc_asprintf(
547 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
549 NT_STATUS_HAVE_NO_MEMORY(filter
);
551 return pdb_ads_getsampwfilter(m
, state
, sam_acct
, filter
);
554 static NTSTATUS
pdb_ads_getsampwsid(struct pdb_methods
*m
,
555 struct samu
*sam_acct
,
556 const struct dom_sid
*sid
)
558 struct pdb_ads_state
*state
= talloc_get_type_abort(
559 m
->private_data
, struct pdb_ads_state
);
560 char *sidstr
, *filter
;
562 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), sid
);
563 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
565 filter
= talloc_asprintf(
566 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr
);
568 NT_STATUS_HAVE_NO_MEMORY(filter
);
570 return pdb_ads_getsampwfilter(m
, state
, sam_acct
, filter
);
573 static NTSTATUS
pdb_ads_create_user(struct pdb_methods
*m
,
575 const char *name
, uint32 acct_flags
,
578 struct pdb_ads_state
*state
= talloc_get_type_abort(
579 m
->private_data
, struct pdb_ads_state
);
580 struct tldap_context
*ld
;
581 const char *attrs
[1] = { "objectSid" };
582 struct tldap_mod
*mods
= NULL
;
584 struct tldap_message
**user
;
590 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
593 return NT_STATUS_NO_MEMORY
;
596 ld
= pdb_ads_ld(state
);
598 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
601 /* TODO: Create machines etc */
604 ok
&= tldap_make_mod_fmt(
605 NULL
, talloc_tos(), &mods
, &num_mods
, "objectClass", "user");
606 ok
&= tldap_make_mod_fmt(
607 NULL
, talloc_tos(), &mods
, &num_mods
, "samAccountName", "%s",
610 return NT_STATUS_NO_MEMORY
;
614 rc
= tldap_add(ld
, dn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
615 if (rc
!= TLDAP_SUCCESS
) {
616 DEBUG(10, ("ldap_add failed %s\n",
617 tldap_errstr(talloc_tos(), ld
, rc
)));
619 return NT_STATUS_LDAP(rc
);
622 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
623 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
625 "(&(objectclass=user)(samaccountname=%s))",
627 if (rc
!= TLDAP_SUCCESS
) {
628 DEBUG(10, ("Could not find just created user %s: %s\n",
629 name
, tldap_errstr(talloc_tos(), state
->ld
, rc
)));
631 return NT_STATUS_LDAP(rc
);
634 if (talloc_array_length(user
) != 1) {
635 DEBUG(10, ("Got %d users, expected one\n",
636 (int)talloc_array_length(user
)));
638 return NT_STATUS_LDAP(rc
);
641 if (!tldap_pull_binsid(user
[0], "objectSid", &sid
)) {
642 DEBUG(10, ("Could not fetch objectSid from user %s\n",
645 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
648 sid_peek_rid(&sid
, rid
);
653 static NTSTATUS
pdb_ads_delete_user(struct pdb_methods
*m
,
657 struct pdb_ads_state
*state
= talloc_get_type_abort(
658 m
->private_data
, struct pdb_ads_state
);
660 struct tldap_context
*ld
;
664 ld
= pdb_ads_ld(state
);
666 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
669 status
= pdb_ads_sid2dn(state
, pdb_get_user_sid(sam
), talloc_tos(),
671 if (!NT_STATUS_IS_OK(status
)) {
675 rc
= tldap_delete(ld
, dn
, NULL
, 0, NULL
, 0);
677 if (rc
!= TLDAP_SUCCESS
) {
678 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn
,
679 tldap_errstr(talloc_tos(), ld
, rc
)));
680 return NT_STATUS_LDAP(rc
);
685 static NTSTATUS
pdb_ads_add_sam_account(struct pdb_methods
*m
,
686 struct samu
*sampass
)
688 return NT_STATUS_NOT_IMPLEMENTED
;
691 static NTSTATUS
pdb_ads_update_sam_account(struct pdb_methods
*m
,
694 struct pdb_ads_state
*state
= talloc_get_type_abort(
695 m
->private_data
, struct pdb_ads_state
);
696 struct pdb_ads_samu_private
*priv
= pdb_ads_get_samu_private(m
, sam
);
697 struct tldap_context
*ld
;
698 struct tldap_mod
*mods
= NULL
;
699 int rc
, num_mods
= 0;
701 ld
= pdb_ads_ld(state
);
703 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
706 if (!pdb_ads_init_ads_from_sam(state
, priv
->ldapmsg
, talloc_tos(),
707 &mods
, &num_mods
, sam
)) {
708 return NT_STATUS_NO_MEMORY
;
712 /* Nothing to do, just return success */
716 rc
= tldap_modify(ld
, priv
->dn
, mods
, num_mods
, NULL
, 0,
719 if (rc
!= TLDAP_SUCCESS
) {
720 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv
->dn
,
721 tldap_errstr(talloc_tos(), ld
, rc
)));
722 return NT_STATUS_LDAP(rc
);
728 static NTSTATUS
pdb_ads_delete_sam_account(struct pdb_methods
*m
,
729 struct samu
*username
)
731 return NT_STATUS_NOT_IMPLEMENTED
;
734 static NTSTATUS
pdb_ads_rename_sam_account(struct pdb_methods
*m
,
735 struct samu
*oldname
,
738 return NT_STATUS_NOT_IMPLEMENTED
;
741 static NTSTATUS
pdb_ads_update_login_attempts(struct pdb_methods
*m
,
742 struct samu
*sam_acct
,
745 return NT_STATUS_NOT_IMPLEMENTED
;
748 static NTSTATUS
pdb_ads_getgrfilter(struct pdb_methods
*m
, GROUP_MAP
*map
,
751 struct tldap_message
**pmsg
)
753 struct pdb_ads_state
*state
= talloc_get_type_abort(
754 m
->private_data
, struct pdb_ads_state
);
755 const char *attrs
[4] = { "objectSid", "description", "samAccountName",
758 struct tldap_message
**group
;
762 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
763 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
764 &group
, "%s", filter
);
765 if (rc
!= TLDAP_SUCCESS
) {
766 DEBUG(10, ("ldap_search failed %s\n",
767 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
768 return NT_STATUS_LDAP(rc
);
770 if (talloc_array_length(group
) != 1) {
771 DEBUG(10, ("Expected 1 group, got %d\n",
772 (int)talloc_array_length(group
)));
773 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
776 if (!tldap_pull_binsid(group
[0], "objectSid", &map
->sid
)) {
777 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
779 map
->gid
= pdb_ads_sid2gid(&map
->sid
);
781 if (!tldap_pull_uint32(group
[0], "groupType", &grouptype
)) {
782 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
785 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
:
786 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
:
787 map
->sid_name_use
= SID_NAME_ALIAS
;
789 case GTYPE_SECURITY_GLOBAL_GROUP
:
790 map
->sid_name_use
= SID_NAME_DOM_GRP
;
793 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
796 str
= tldap_talloc_single_attribute(group
[0], "samAccountName",
799 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
801 map
->nt_name
= talloc_move(map
, &str
);
803 str
= tldap_talloc_single_attribute(group
[0], "description",
806 map
->comment
= talloc_move(map
, &str
);
808 map
->comment
= talloc_strdup(map
, "");
812 *pmsg
= talloc_move(mem_ctx
, &group
[0]);
818 static NTSTATUS
pdb_ads_getgrsid(struct pdb_methods
*m
, GROUP_MAP
*map
,
824 filter
= talloc_asprintf(talloc_tos(),
825 "(&(objectsid=%s)(objectclass=group))",
826 sid_string_talloc(talloc_tos(), &sid
));
827 if (filter
== NULL
) {
828 return NT_STATUS_NO_MEMORY
;
831 status
= pdb_ads_getgrfilter(m
, map
, filter
, NULL
, NULL
);
836 static NTSTATUS
pdb_ads_getgrgid(struct pdb_methods
*m
, GROUP_MAP
*map
,
840 pdb_ads_gid_to_sid(m
, gid
, &sid
);
841 return pdb_ads_getgrsid(m
, map
, sid
);
844 static NTSTATUS
pdb_ads_getgrnam(struct pdb_methods
*m
, GROUP_MAP
*map
,
850 filter
= talloc_asprintf(talloc_tos(),
851 "(&(samaccountname=%s)(objectclass=group))",
853 if (filter
== NULL
) {
854 return NT_STATUS_NO_MEMORY
;
857 status
= pdb_ads_getgrfilter(m
, map
, filter
, NULL
, NULL
);
862 static NTSTATUS
pdb_ads_create_dom_group(struct pdb_methods
*m
,
863 TALLOC_CTX
*mem_ctx
, const char *name
,
866 TALLOC_CTX
*frame
= talloc_stackframe();
867 struct pdb_ads_state
*state
= talloc_get_type_abort(
868 m
->private_data
, struct pdb_ads_state
);
869 struct tldap_context
*ld
;
870 const char *attrs
[1] = { "objectSid" };
872 struct tldap_mod
*mods
= NULL
;
873 struct tldap_message
**alias
;
879 ld
= pdb_ads_ld(state
);
881 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
884 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
888 return NT_STATUS_NO_MEMORY
;
891 ok
&= tldap_make_mod_fmt(
892 NULL
, talloc_tos(), &mods
, &num_mods
, "samAccountName", "%s",
894 ok
&= tldap_make_mod_fmt(
895 NULL
, talloc_tos(), &mods
, &num_mods
, "objectClass", "group");
896 ok
&= tldap_make_mod_fmt(
897 NULL
, talloc_tos(), &mods
, &num_mods
, "groupType",
898 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP
);
902 return NT_STATUS_NO_MEMORY
;
905 rc
= tldap_add(ld
, dn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
906 if (rc
!= TLDAP_SUCCESS
) {
907 DEBUG(10, ("ldap_add failed %s\n",
908 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
910 return NT_STATUS_LDAP(rc
);
913 rc
= pdb_ads_search_fmt(
914 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
915 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &alias
,
916 "(&(objectclass=group)(samaccountname=%s))", name
);
917 if (rc
!= TLDAP_SUCCESS
) {
918 DEBUG(10, ("Could not find just created alias %s: %s\n",
919 name
, tldap_errstr(talloc_tos(), state
->ld
, rc
)));
921 return NT_STATUS_LDAP(rc
);
924 if (talloc_array_length(alias
) != 1) {
925 DEBUG(10, ("Got %d alias, expected one\n",
926 (int)talloc_array_length(alias
)));
928 return NT_STATUS_LDAP(rc
);
931 if (!tldap_pull_binsid(alias
[0], "objectSid", &sid
)) {
932 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
935 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
938 sid_peek_rid(&sid
, rid
);
943 static NTSTATUS
pdb_ads_delete_dom_group(struct pdb_methods
*m
,
944 TALLOC_CTX
*mem_ctx
, uint32 rid
)
946 struct pdb_ads_state
*state
= talloc_get_type_abort(
947 m
->private_data
, struct pdb_ads_state
);
948 struct tldap_context
*ld
;
951 struct tldap_message
**msg
;
955 sid_compose(&sid
, &state
->domainsid
, rid
);
957 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), &sid
);
958 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
960 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
961 NULL
, 0, 0, talloc_tos(), &msg
,
962 ("(&(objectSid=%s)(objectClass=group))"),
965 if (rc
!= TLDAP_SUCCESS
) {
966 DEBUG(10, ("ldap_search failed %s\n",
967 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
968 return NT_STATUS_LDAP(rc
);
971 switch talloc_array_length(msg
) {
973 return NT_STATUS_NO_SUCH_GROUP
;
977 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
980 if (!tldap_entry_dn(msg
[0], &dn
)) {
982 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
985 ld
= pdb_ads_ld(state
);
988 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
991 rc
= tldap_delete(ld
, dn
, NULL
, 0, NULL
, 0);
993 if (rc
!= TLDAP_SUCCESS
) {
994 DEBUG(10, ("ldap_delete failed: %s\n",
995 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
996 return NT_STATUS_LDAP(rc
);
1002 static NTSTATUS
pdb_ads_add_group_mapping_entry(struct pdb_methods
*m
,
1005 return NT_STATUS_NOT_IMPLEMENTED
;
1008 static NTSTATUS
pdb_ads_update_group_mapping_entry(struct pdb_methods
*m
,
1011 struct pdb_ads_state
*state
= talloc_get_type_abort(
1012 m
->private_data
, struct pdb_ads_state
);
1013 struct tldap_context
*ld
;
1014 struct tldap_mod
*mods
= NULL
;
1016 struct tldap_message
*existing
;
1018 GROUP_MAP
*existing_map
;
1019 int rc
, num_mods
= 0;
1023 ld
= pdb_ads_ld(state
);
1025 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1028 filter
= talloc_asprintf(talloc_tos(),
1029 "(&(objectsid=%s)(objectclass=group))",
1030 sid_string_talloc(talloc_tos(), &map
->sid
));
1031 if (filter
== NULL
) {
1032 return NT_STATUS_NO_MEMORY
;
1035 existing_map
= talloc_zero(talloc_tos(), GROUP_MAP
);
1036 if (!existing_map
) {
1037 return NT_STATUS_NO_MEMORY
;
1040 status
= pdb_ads_getgrfilter(m
, existing_map
, filter
,
1041 talloc_tos(), &existing
);
1042 TALLOC_FREE(existing_map
);
1043 TALLOC_FREE(filter
);
1045 if (!tldap_entry_dn(existing
, &dn
)) {
1046 return NT_STATUS_LDAP(TLDAP_DECODING_ERROR
);
1051 ret
&= tldap_make_mod_fmt(
1052 existing
, talloc_tos(), &mods
, &num_mods
, "description",
1053 "%s", map
->comment
);
1054 ret
&= tldap_make_mod_fmt(
1055 existing
, talloc_tos(), &mods
, &num_mods
, "samaccountname",
1056 "%s", map
->nt_name
);
1059 return NT_STATUS_NO_MEMORY
;
1062 if (num_mods
== 0) {
1063 TALLOC_FREE(existing
);
1064 return NT_STATUS_OK
;
1067 rc
= tldap_modify(ld
, dn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
1068 if (rc
!= TLDAP_SUCCESS
) {
1069 DEBUG(10, ("ldap_modify for %s failed: %s\n", dn
,
1070 tldap_errstr(talloc_tos(), ld
, rc
)));
1071 TALLOC_FREE(existing
);
1072 return NT_STATUS_LDAP(rc
);
1074 TALLOC_FREE(existing
);
1075 return NT_STATUS_OK
;
1078 static NTSTATUS
pdb_ads_delete_group_mapping_entry(struct pdb_methods
*m
,
1081 return NT_STATUS_NOT_IMPLEMENTED
;
1084 static NTSTATUS
pdb_ads_enum_group_mapping(struct pdb_methods
*m
,
1085 const struct dom_sid
*sid
,
1086 enum lsa_SidType sid_name_use
,
1087 GROUP_MAP
***pp_rmap
,
1088 size_t *p_num_entries
,
1091 return NT_STATUS_NOT_IMPLEMENTED
;
1094 static NTSTATUS
pdb_ads_enum_group_members(struct pdb_methods
*m
,
1095 TALLOC_CTX
*mem_ctx
,
1096 const struct dom_sid
*group
,
1098 size_t *pnum_members
)
1100 struct pdb_ads_state
*state
= talloc_get_type_abort(
1101 m
->private_data
, struct pdb_ads_state
);
1102 const char *attrs
[1] = { "member" };
1104 struct tldap_message
**msg
;
1105 int i
, rc
, num_members
;
1109 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), group
);
1110 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1112 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1113 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1114 &msg
, "(objectsid=%s)", sidstr
);
1115 TALLOC_FREE(sidstr
);
1116 if (rc
!= TLDAP_SUCCESS
) {
1117 DEBUG(10, ("ldap_search failed %s\n",
1118 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1119 return NT_STATUS_LDAP(rc
);
1121 switch talloc_array_length(msg
) {
1123 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1128 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1132 if (!tldap_entry_values(msg
[0], "member", &blobs
, &num_members
)) {
1135 return NT_STATUS_OK
;
1138 members
= talloc_array(mem_ctx
, uint32_t, num_members
);
1139 if (members
== NULL
) {
1140 return NT_STATUS_NO_MEMORY
;
1143 for (i
=0; i
<num_members
; i
++) {
1145 if (!pdb_ads_dnblob2sid(state
, &blobs
[i
], &sid
)
1146 || !sid_peek_rid(&sid
, &members
[i
])) {
1147 TALLOC_FREE(members
);
1148 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1152 *pmembers
= members
;
1153 *pnum_members
= num_members
;
1154 return NT_STATUS_OK
;
1157 static NTSTATUS
pdb_ads_enum_group_memberships(struct pdb_methods
*m
,
1158 TALLOC_CTX
*mem_ctx
,
1160 struct dom_sid
**pp_sids
,
1162 uint32_t *p_num_groups
)
1164 struct pdb_ads_state
*state
= talloc_get_type_abort(
1165 m
->private_data
, struct pdb_ads_state
);
1166 struct pdb_ads_samu_private
*priv
;
1167 const char *attrs
[1] = { "objectSid" };
1168 struct tldap_message
**groups
;
1171 struct dom_sid
*group_sids
;
1174 priv
= pdb_ads_get_samu_private(m
, user
);
1176 rc
= pdb_ads_search_fmt(
1177 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1178 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &groups
,
1179 "(&(member=%s)(grouptype=%d)(objectclass=group))",
1180 priv
->dn
, GTYPE_SECURITY_GLOBAL_GROUP
);
1181 if (rc
!= TLDAP_SUCCESS
) {
1182 DEBUG(10, ("ldap_search failed %s\n",
1183 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1184 return NT_STATUS_LDAP(rc
);
1186 count
= talloc_array_length(groups
);
1189 * This happens for artificial samu users
1191 DEBUG(10, ("Could not get pdb_ads_samu_private\n"));
1195 group_sids
= talloc_array(mem_ctx
, struct dom_sid
, count
+1);
1196 if (group_sids
== NULL
) {
1197 return NT_STATUS_NO_MEMORY
;
1199 gids
= talloc_array(mem_ctx
, gid_t
, count
+1);
1201 TALLOC_FREE(group_sids
);
1202 return NT_STATUS_NO_MEMORY
;
1205 sid_copy(&group_sids
[0], pdb_get_group_sid(user
));
1206 if (!sid_to_gid(&group_sids
[0], &gids
[0])) {
1208 TALLOC_FREE(group_sids
);
1209 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1213 for (i
=0; i
<count
; i
++) {
1214 if (!tldap_pull_binsid(groups
[i
], "objectSid",
1215 &group_sids
[num_groups
])) {
1218 gids
[num_groups
] = pdb_ads_sid2gid(&group_sids
[num_groups
]);
1221 if (num_groups
== count
) {
1226 *pp_sids
= group_sids
;
1228 *p_num_groups
= num_groups
;
1229 return NT_STATUS_OK
;
1232 static NTSTATUS
pdb_ads_set_unix_primary_group(struct pdb_methods
*m
,
1233 TALLOC_CTX
*mem_ctx
,
1236 return NT_STATUS_NOT_IMPLEMENTED
;
1239 static NTSTATUS
pdb_ads_mod_groupmem(struct pdb_methods
*m
,
1240 TALLOC_CTX
*mem_ctx
,
1241 uint32 grouprid
, uint32 memberrid
,
1244 struct pdb_ads_state
*state
= talloc_get_type_abort(
1245 m
->private_data
, struct pdb_ads_state
);
1246 TALLOC_CTX
*frame
= talloc_stackframe();
1247 struct tldap_context
*ld
;
1248 struct dom_sid groupsid
, membersid
;
1249 char *groupdn
, *memberdn
;
1250 struct tldap_mod
*mods
;
1255 ld
= pdb_ads_ld(state
);
1257 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1260 sid_compose(&groupsid
, &state
->domainsid
, grouprid
);
1261 sid_compose(&membersid
, &state
->domainsid
, memberrid
);
1263 status
= pdb_ads_sid2dn(state
, &groupsid
, talloc_tos(), &groupdn
);
1264 if (!NT_STATUS_IS_OK(status
)) {
1266 return NT_STATUS_NO_SUCH_GROUP
;
1268 status
= pdb_ads_sid2dn(state
, &membersid
, talloc_tos(), &memberdn
);
1269 if (!NT_STATUS_IS_OK(status
)) {
1271 return NT_STATUS_NO_SUCH_USER
;
1277 if (!tldap_add_mod_str(talloc_tos(), &mods
, &num_mods
, mod_op
,
1278 "member", memberdn
)) {
1280 return NT_STATUS_NO_MEMORY
;
1283 rc
= tldap_modify(ld
, groupdn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
1285 if (rc
!= TLDAP_SUCCESS
) {
1286 DEBUG(10, ("ldap_modify failed: %s\n",
1287 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1288 if ((mod_op
== TLDAP_MOD_ADD
) &&
1289 (rc
== TLDAP_ALREADY_EXISTS
)) {
1290 return NT_STATUS_MEMBER_IN_GROUP
;
1292 if ((mod_op
== TLDAP_MOD_DELETE
) &&
1293 (rc
== TLDAP_UNWILLING_TO_PERFORM
)) {
1294 return NT_STATUS_MEMBER_NOT_IN_GROUP
;
1296 return NT_STATUS_LDAP(rc
);
1299 return NT_STATUS_OK
;
1302 static NTSTATUS
pdb_ads_add_groupmem(struct pdb_methods
*m
,
1303 TALLOC_CTX
*mem_ctx
,
1304 uint32 group_rid
, uint32 member_rid
)
1306 return pdb_ads_mod_groupmem(m
, mem_ctx
, group_rid
, member_rid
,
1310 static NTSTATUS
pdb_ads_del_groupmem(struct pdb_methods
*m
,
1311 TALLOC_CTX
*mem_ctx
,
1312 uint32 group_rid
, uint32 member_rid
)
1314 return pdb_ads_mod_groupmem(m
, mem_ctx
, group_rid
, member_rid
,
1318 static NTSTATUS
pdb_ads_create_alias(struct pdb_methods
*m
,
1319 const char *name
, uint32
*rid
)
1321 TALLOC_CTX
*frame
= talloc_stackframe();
1322 struct pdb_ads_state
*state
= talloc_get_type_abort(
1323 m
->private_data
, struct pdb_ads_state
);
1324 struct tldap_context
*ld
;
1325 const char *attrs
[1] = { "objectSid" };
1327 struct tldap_mod
*mods
= NULL
;
1328 struct tldap_message
**alias
;
1334 ld
= pdb_ads_ld(state
);
1336 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1339 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
1343 return NT_STATUS_NO_MEMORY
;
1346 ok
&= tldap_make_mod_fmt(
1347 NULL
, talloc_tos(), &mods
, &num_mods
, "samAccountName", "%s",
1349 ok
&= tldap_make_mod_fmt(
1350 NULL
, talloc_tos(), &mods
, &num_mods
, "objectClass", "group");
1351 ok
&= tldap_make_mod_fmt(
1352 NULL
, talloc_tos(), &mods
, &num_mods
, "groupType",
1353 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1357 return NT_STATUS_NO_MEMORY
;
1360 rc
= tldap_add(ld
, dn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
1361 if (rc
!= TLDAP_SUCCESS
) {
1362 DEBUG(10, ("ldap_add failed %s\n",
1363 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1365 return NT_STATUS_LDAP(rc
);
1368 rc
= pdb_ads_search_fmt(
1369 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1370 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &alias
,
1371 "(&(objectclass=group)(samaccountname=%s))", name
);
1372 if (rc
!= TLDAP_SUCCESS
) {
1373 DEBUG(10, ("Could not find just created alias %s: %s\n",
1374 name
, tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1376 return NT_STATUS_LDAP(rc
);
1379 if (talloc_array_length(alias
) != 1) {
1380 DEBUG(10, ("Got %d alias, expected one\n",
1381 (int)talloc_array_length(alias
)));
1383 return NT_STATUS_LDAP(rc
);
1386 if (!tldap_pull_binsid(alias
[0], "objectSid", &sid
)) {
1387 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1390 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1393 sid_peek_rid(&sid
, rid
);
1395 return NT_STATUS_OK
;
1398 static NTSTATUS
pdb_ads_delete_alias(struct pdb_methods
*m
,
1399 const struct dom_sid
*sid
)
1401 struct pdb_ads_state
*state
= talloc_get_type_abort(
1402 m
->private_data
, struct pdb_ads_state
);
1403 struct tldap_context
*ld
;
1404 struct tldap_message
**alias
;
1405 char *sidstr
, *dn
= NULL
;
1408 ld
= pdb_ads_ld(state
);
1410 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1413 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), sid
);
1414 if (sidstr
== NULL
) {
1415 return NT_STATUS_NO_MEMORY
;
1418 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1419 NULL
, 0, 0, talloc_tos(), &alias
,
1420 "(&(objectSid=%s)(objectclass=group)"
1421 "(|(grouptype=%d)(grouptype=%d)))",
1422 sidstr
, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1423 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1424 TALLOC_FREE(sidstr
);
1425 if (rc
!= TLDAP_SUCCESS
) {
1426 DEBUG(10, ("ldap_search failed: %s\n",
1427 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1428 return NT_STATUS_LDAP(rc
);
1430 if (talloc_array_length(alias
) != 1) {
1431 DEBUG(10, ("Expected 1 alias, got %d\n",
1432 (int)talloc_array_length(alias
)));
1433 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1435 if (!tldap_entry_dn(alias
[0], &dn
)) {
1436 DEBUG(10, ("Could not get DN for alias %s\n",
1437 sid_string_dbg(sid
)));
1438 return NT_STATUS_INTERNAL_ERROR
;
1441 rc
= tldap_delete(ld
, dn
, NULL
, 0, NULL
, 0);
1442 if (rc
!= TLDAP_SUCCESS
) {
1443 DEBUG(10, ("ldap_delete failed: %s\n",
1444 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1445 return NT_STATUS_LDAP(rc
);
1448 return NT_STATUS_OK
;
1451 static NTSTATUS
pdb_ads_set_aliasinfo(struct pdb_methods
*m
,
1452 const struct dom_sid
*sid
,
1453 struct acct_info
*info
)
1455 struct pdb_ads_state
*state
= talloc_get_type_abort(
1456 m
->private_data
, struct pdb_ads_state
);
1457 struct tldap_context
*ld
;
1458 const char *attrs
[3] = { "objectSid", "description",
1460 struct tldap_message
**msg
;
1463 struct tldap_mod
*mods
;
1467 ld
= pdb_ads_ld(state
);
1469 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1472 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), sid
);
1473 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1475 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1476 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1477 &msg
, "(&(objectSid=%s)(objectclass=group)"
1478 "(|(grouptype=%d)(grouptype=%d)))",
1479 sidstr
, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1480 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1481 TALLOC_FREE(sidstr
);
1482 if (rc
!= TLDAP_SUCCESS
) {
1483 DEBUG(10, ("ldap_search failed %s\n",
1484 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1485 return NT_STATUS_LDAP(rc
);
1487 switch talloc_array_length(msg
) {
1489 return NT_STATUS_NO_SUCH_ALIAS
;
1493 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1496 if (!tldap_entry_dn(msg
[0], &dn
)) {
1498 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1505 ok
&= tldap_make_mod_fmt(
1506 msg
[0], msg
, &mods
, &num_mods
, "description",
1507 "%s", info
->acct_desc
);
1508 ok
&= tldap_make_mod_fmt(
1509 msg
[0], msg
, &mods
, &num_mods
, "samAccountName",
1510 "%s", info
->acct_name
);
1513 return NT_STATUS_NO_MEMORY
;
1515 if (num_mods
== 0) {
1518 return NT_STATUS_OK
;
1521 rc
= tldap_modify(ld
, dn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
1523 if (rc
!= TLDAP_SUCCESS
) {
1524 DEBUG(10, ("ldap_modify failed: %s\n",
1525 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1526 return NT_STATUS_LDAP(rc
);
1528 return NT_STATUS_OK
;
1531 static NTSTATUS
pdb_ads_sid2dn(struct pdb_ads_state
*state
,
1532 const struct dom_sid
*sid
,
1533 TALLOC_CTX
*mem_ctx
, char **pdn
)
1535 struct tldap_message
**msg
;
1539 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), sid
);
1540 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1542 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1543 NULL
, 0, 0, talloc_tos(), &msg
,
1544 "(objectsid=%s)", sidstr
);
1545 TALLOC_FREE(sidstr
);
1546 if (rc
!= TLDAP_SUCCESS
) {
1547 DEBUG(10, ("ldap_search failed %s\n",
1548 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1549 return NT_STATUS_LDAP(rc
);
1552 switch talloc_array_length(msg
) {
1554 return NT_STATUS_NOT_FOUND
;
1558 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1561 if (!tldap_entry_dn(msg
[0], &dn
)) {
1562 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1565 dn
= talloc_strdup(mem_ctx
, dn
);
1567 return NT_STATUS_NO_MEMORY
;
1572 return NT_STATUS_OK
;
1575 static NTSTATUS
pdb_ads_mod_aliasmem(struct pdb_methods
*m
,
1576 const struct dom_sid
*alias
,
1577 const struct dom_sid
*member
,
1580 struct pdb_ads_state
*state
= talloc_get_type_abort(
1581 m
->private_data
, struct pdb_ads_state
);
1582 struct tldap_context
*ld
;
1583 TALLOC_CTX
*frame
= talloc_stackframe();
1584 struct tldap_mod
*mods
;
1587 char *aliasdn
, *memberdn
;
1590 ld
= pdb_ads_ld(state
);
1592 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1595 status
= pdb_ads_sid2dn(state
, alias
, talloc_tos(), &aliasdn
);
1596 if (!NT_STATUS_IS_OK(status
)) {
1597 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1598 sid_string_dbg(alias
), nt_errstr(status
)));
1600 return NT_STATUS_NO_SUCH_ALIAS
;
1602 status
= pdb_ads_sid2dn(state
, member
, talloc_tos(), &memberdn
);
1603 if (!NT_STATUS_IS_OK(status
)) {
1604 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1605 sid_string_dbg(member
), nt_errstr(status
)));
1613 if (!tldap_add_mod_str(talloc_tos(), &mods
, &num_mods
, mod_op
,
1614 "member", memberdn
)) {
1616 return NT_STATUS_NO_MEMORY
;
1619 rc
= tldap_modify(ld
, aliasdn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
1621 if (rc
!= TLDAP_SUCCESS
) {
1622 DEBUG(10, ("ldap_modify failed: %s\n",
1623 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1624 if (rc
== TLDAP_TYPE_OR_VALUE_EXISTS
) {
1625 return NT_STATUS_MEMBER_IN_ALIAS
;
1627 if (rc
== TLDAP_NO_SUCH_ATTRIBUTE
) {
1628 return NT_STATUS_MEMBER_NOT_IN_ALIAS
;
1630 return NT_STATUS_LDAP(rc
);
1633 return NT_STATUS_OK
;
1636 static NTSTATUS
pdb_ads_add_aliasmem(struct pdb_methods
*m
,
1637 const struct dom_sid
*alias
,
1638 const struct dom_sid
*member
)
1640 return pdb_ads_mod_aliasmem(m
, alias
, member
, TLDAP_MOD_ADD
);
1643 static NTSTATUS
pdb_ads_del_aliasmem(struct pdb_methods
*m
,
1644 const struct dom_sid
*alias
,
1645 const struct dom_sid
*member
)
1647 return pdb_ads_mod_aliasmem(m
, alias
, member
, TLDAP_MOD_DELETE
);
1650 static bool pdb_ads_dnblob2sid(struct pdb_ads_state
*state
, DATA_BLOB
*dnblob
,
1651 struct dom_sid
*psid
)
1653 const char *attrs
[1] = { "objectSid" };
1654 struct tldap_message
**msg
;
1660 if (!convert_string_talloc(talloc_tos(), CH_UTF8
, CH_UNIX
,
1661 dnblob
->data
, dnblob
->length
, &dn
, &len
)) {
1664 rc
= pdb_ads_search_fmt(state
, dn
, TLDAP_SCOPE_BASE
,
1665 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1666 &msg
, "(objectclass=*)");
1668 if (talloc_array_length(msg
) != 1) {
1669 DEBUG(10, ("Got %d objects, expected one\n",
1670 (int)talloc_array_length(msg
)));
1675 ret
= tldap_pull_binsid(msg
[0], "objectSid", psid
);
1680 static NTSTATUS
pdb_ads_enum_aliasmem(struct pdb_methods
*m
,
1681 const struct dom_sid
*alias
,
1682 TALLOC_CTX
*mem_ctx
,
1683 struct dom_sid
**pmembers
,
1684 size_t *pnum_members
)
1686 struct pdb_ads_state
*state
= talloc_get_type_abort(
1687 m
->private_data
, struct pdb_ads_state
);
1688 const char *attrs
[1] = { "member" };
1690 struct tldap_message
**msg
;
1691 int i
, rc
, num_members
;
1693 struct dom_sid
*members
;
1695 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), alias
);
1696 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1698 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1699 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1700 &msg
, "(objectsid=%s)", sidstr
);
1701 TALLOC_FREE(sidstr
);
1702 if (rc
!= TLDAP_SUCCESS
) {
1703 DEBUG(10, ("ldap_search failed %s\n",
1704 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1705 return NT_STATUS_LDAP(rc
);
1707 switch talloc_array_length(msg
) {
1709 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1714 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1718 if (!tldap_entry_values(msg
[0], "member", &blobs
, &num_members
)) {
1721 return NT_STATUS_OK
;
1724 members
= talloc_array(mem_ctx
, struct dom_sid
, num_members
);
1725 if (members
== NULL
) {
1726 return NT_STATUS_NO_MEMORY
;
1729 for (i
=0; i
<num_members
; i
++) {
1730 if (!pdb_ads_dnblob2sid(state
, &blobs
[i
], &members
[i
])) {
1731 TALLOC_FREE(members
);
1732 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1736 *pmembers
= members
;
1737 *pnum_members
= num_members
;
1738 return NT_STATUS_OK
;
1741 static NTSTATUS
pdb_ads_enum_alias_memberships(struct pdb_methods
*m
,
1742 TALLOC_CTX
*mem_ctx
,
1743 const struct dom_sid
*domain_sid
,
1744 const struct dom_sid
*members
,
1746 uint32_t **palias_rids
,
1747 size_t *pnum_alias_rids
)
1749 struct pdb_ads_state
*state
= talloc_get_type_abort(
1750 m
->private_data
, struct pdb_ads_state
);
1751 const char *attrs
[1] = { "objectSid" };
1752 struct tldap_message
**msg
= NULL
;
1753 uint32_t *alias_rids
= NULL
;
1754 size_t num_alias_rids
= 0;
1756 bool got_members
= false;
1761 * TODO: Get the filter right so that we only get the aliases from
1762 * either the SAM or BUILTIN
1765 filter
= talloc_asprintf(talloc_tos(),
1766 "(&(|(grouptype=%d)(grouptype=%d))"
1767 "(objectclass=group)(|",
1768 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1769 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1770 if (filter
== NULL
) {
1771 return NT_STATUS_NO_MEMORY
;
1774 for (i
=0; i
<num_members
; i
++) {
1777 status
= pdb_ads_sid2dn(state
, &members
[i
], talloc_tos(), &dn
);
1778 if (!NT_STATUS_IS_OK(status
)) {
1779 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1780 sid_string_dbg(&members
[i
]),
1781 nt_errstr(status
)));
1784 filter
= talloc_asprintf_append_buffer(
1785 filter
, "(member=%s)", dn
);
1787 if (filter
== NULL
) {
1788 return NT_STATUS_NO_MEMORY
;
1797 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1798 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1799 &msg
, "%s))", filter
);
1800 TALLOC_FREE(filter
);
1801 if (rc
!= TLDAP_SUCCESS
) {
1802 DEBUG(10, ("tldap_search failed %s\n",
1803 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1804 return NT_STATUS_LDAP(rc
);
1807 count
= talloc_array_length(msg
);
1812 alias_rids
= talloc_array(mem_ctx
, uint32_t, count
);
1813 if (alias_rids
== NULL
) {
1815 return NT_STATUS_NO_MEMORY
;
1818 for (i
=0; i
<count
; i
++) {
1821 if (!tldap_pull_binsid(msg
[i
], "objectSid", &sid
)) {
1822 DEBUG(10, ("Could not pull SID for member %d\n", i
));
1825 if (sid_peek_check_rid(domain_sid
, &sid
,
1826 &alias_rids
[num_alias_rids
])) {
1827 num_alias_rids
+= 1;
1832 *palias_rids
= alias_rids
;
1833 *pnum_alias_rids
= 0;
1834 return NT_STATUS_OK
;
1837 static NTSTATUS
pdb_ads_lookup_rids(struct pdb_methods
*m
,
1838 const struct dom_sid
*domain_sid
,
1842 enum lsa_SidType
*lsa_attrs
)
1844 struct pdb_ads_state
*state
= talloc_get_type_abort(
1845 m
->private_data
, struct pdb_ads_state
);
1846 const char *attrs
[2] = { "sAMAccountType", "sAMAccountName" };
1849 if (num_rids
== 0) {
1850 return NT_STATUS_NONE_MAPPED
;
1855 for (i
=0; i
<num_rids
; i
++) {
1857 struct tldap_message
**msg
;
1862 lsa_attrs
[i
] = SID_NAME_UNKNOWN
;
1864 sid_compose(&sid
, domain_sid
, rids
[i
]);
1866 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), &sid
);
1867 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1869 rc
= pdb_ads_search_fmt(state
, state
->domaindn
,
1870 TLDAP_SCOPE_SUB
, attrs
,
1871 ARRAY_SIZE(attrs
), 0, talloc_tos(),
1872 &msg
, "(objectsid=%s)", sidstr
);
1873 TALLOC_FREE(sidstr
);
1874 if (rc
!= TLDAP_SUCCESS
) {
1875 DEBUG(10, ("ldap_search failed %s\n",
1876 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1880 switch talloc_array_length(msg
) {
1882 DEBUG(10, ("rid %d not found\n", (int)rids
[i
]));
1887 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1890 names
[i
] = tldap_talloc_single_attribute(
1891 msg
[0], "samAccountName", talloc_tos());
1892 if (names
[i
] == NULL
) {
1893 DEBUG(10, ("no samAccountName\n"));
1896 if (!tldap_pull_uint32(msg
[0], "samAccountType", &attr
)) {
1897 DEBUG(10, ("no samAccountType"));
1900 lsa_attrs
[i
] = ds_atype_map(attr
);
1904 if (num_mapped
== 0) {
1905 return NT_STATUS_NONE_MAPPED
;
1907 if (num_mapped
< num_rids
) {
1908 return STATUS_SOME_UNMAPPED
;
1910 return NT_STATUS_OK
;
1913 static NTSTATUS
pdb_ads_lookup_names(struct pdb_methods
*m
,
1914 const struct dom_sid
*domain_sid
,
1916 const char **pp_names
,
1918 enum lsa_SidType
*attrs
)
1920 return NT_STATUS_NOT_IMPLEMENTED
;
1923 static NTSTATUS
pdb_ads_get_account_policy(struct pdb_methods
*m
,
1924 enum pdb_policy_type type
,
1927 return account_policy_get(type
, value
)
1928 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1931 static NTSTATUS
pdb_ads_set_account_policy(struct pdb_methods
*m
,
1932 enum pdb_policy_type type
,
1935 return account_policy_set(type
, value
)
1936 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1939 static NTSTATUS
pdb_ads_get_seq_num(struct pdb_methods
*m
,
1942 return NT_STATUS_NOT_IMPLEMENTED
;
1945 struct pdb_ads_search_state
{
1946 uint32_t acct_flags
;
1947 struct samr_displayentry
*entries
;
1948 uint32_t num_entries
;
1953 static bool pdb_ads_next_entry(struct pdb_search
*search
,
1954 struct samr_displayentry
*entry
)
1956 struct pdb_ads_search_state
*state
= talloc_get_type_abort(
1957 search
->private_data
, struct pdb_ads_search_state
);
1959 if (state
->current
== state
->num_entries
) {
1963 entry
->idx
= state
->entries
[state
->current
].idx
;
1964 entry
->rid
= state
->entries
[state
->current
].rid
;
1965 entry
->acct_flags
= state
->entries
[state
->current
].acct_flags
;
1967 entry
->account_name
= talloc_strdup(
1968 search
, state
->entries
[state
->current
].account_name
);
1969 entry
->fullname
= talloc_strdup(
1970 search
, state
->entries
[state
->current
].fullname
);
1971 entry
->description
= talloc_strdup(
1972 search
, state
->entries
[state
->current
].description
);
1974 if ((entry
->account_name
== NULL
) || (entry
->fullname
== NULL
)
1975 || (entry
->description
== NULL
)) {
1976 DEBUG(0, ("talloc_strdup failed\n"));
1980 state
->current
+= 1;
1984 static void pdb_ads_search_end(struct pdb_search
*search
)
1986 struct pdb_ads_search_state
*state
= talloc_get_type_abort(
1987 search
->private_data
, struct pdb_ads_search_state
);
1991 static bool pdb_ads_search_filter(struct pdb_methods
*m
,
1992 struct pdb_search
*search
,
1994 uint32_t acct_flags
,
1995 struct pdb_ads_search_state
**pstate
)
1997 struct pdb_ads_state
*state
= talloc_get_type_abort(
1998 m
->private_data
, struct pdb_ads_state
);
1999 struct pdb_ads_search_state
*sstate
;
2000 const char * attrs
[] = { "objectSid", "sAMAccountName", "displayName",
2001 "userAccountControl", "description" };
2002 struct tldap_message
**users
;
2003 int i
, rc
, num_users
;
2005 sstate
= talloc_zero(search
, struct pdb_ads_search_state
);
2006 if (sstate
== NULL
) {
2009 sstate
->acct_flags
= acct_flags
;
2011 rc
= pdb_ads_search_fmt(
2012 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
2013 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &users
,
2015 if (rc
!= TLDAP_SUCCESS
) {
2016 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
2017 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2021 num_users
= talloc_array_length(users
);
2023 sstate
->entries
= talloc_array(sstate
, struct samr_displayentry
,
2025 if (sstate
->entries
== NULL
) {
2026 DEBUG(10, ("talloc failed\n"));
2030 sstate
->num_entries
= 0;
2032 for (i
=0; i
<num_users
; i
++) {
2033 struct samr_displayentry
*e
;
2037 e
= &sstate
->entries
[sstate
->num_entries
];
2039 e
->idx
= sstate
->num_entries
;
2040 if (!tldap_pull_binsid(users
[i
], "objectSid", &sid
)) {
2041 DEBUG(10, ("Could not pull sid\n"));
2044 sid_peek_rid(&sid
, &e
->rid
);
2046 if (tldap_pull_uint32(users
[i
], "userAccountControl", &ctrl
)) {
2048 e
->acct_flags
= ds_uf2acb(ctrl
);
2050 DEBUG(10, ("pdb_ads_search_filter: Found %x, "
2051 "filter %x\n", (int)e
->acct_flags
,
2052 (int)sstate
->acct_flags
));
2055 if ((sstate
->acct_flags
!= 0) &&
2056 ((sstate
->acct_flags
& e
->acct_flags
) == 0)) {
2060 if (e
->acct_flags
& (ACB_WSTRUST
|ACB_SVRTRUST
)) {
2061 e
->acct_flags
|= ACB_NORMAL
;
2064 e
->acct_flags
= ACB_NORMAL
;
2067 if (e
->rid
== DOMAIN_RID_GUEST
) {
2069 * Guest is specially crafted in s3. Make
2070 * QueryDisplayInfo match QueryUserInfo
2072 e
->account_name
= lp_guestaccount();
2073 e
->fullname
= lp_guestaccount();
2074 e
->description
= "";
2075 e
->acct_flags
= ACB_NORMAL
;
2077 e
->account_name
= tldap_talloc_single_attribute(
2078 users
[i
], "samAccountName", sstate
->entries
);
2079 e
->fullname
= tldap_talloc_single_attribute(
2080 users
[i
], "displayName", sstate
->entries
);
2081 e
->description
= tldap_talloc_single_attribute(
2082 users
[i
], "description", sstate
->entries
);
2084 if (e
->account_name
== NULL
) {
2087 if (e
->fullname
== NULL
) {
2090 if (e
->description
== NULL
) {
2091 e
->description
= "";
2094 sstate
->num_entries
+= 1;
2095 if (sstate
->num_entries
>= num_users
) {
2100 search
->private_data
= sstate
;
2101 search
->next_entry
= pdb_ads_next_entry
;
2102 search
->search_end
= pdb_ads_search_end
;
2107 static bool pdb_ads_search_users(struct pdb_methods
*m
,
2108 struct pdb_search
*search
,
2111 struct pdb_ads_search_state
*sstate
;
2115 DEBUG(10, ("pdb_ads_search_users got flags %x\n", acct_flags
));
2117 if (acct_flags
& ACB_NORMAL
) {
2118 filter
= talloc_asprintf(
2120 "(&(objectclass=user)(sAMAccountType=%d))",
2121 ATYPE_NORMAL_ACCOUNT
);
2122 } else if (acct_flags
& ACB_WSTRUST
) {
2123 filter
= talloc_asprintf(
2125 "(&(objectclass=user)(sAMAccountType=%d))",
2126 ATYPE_WORKSTATION_TRUST
);
2128 filter
= talloc_strdup(talloc_tos(), "(objectclass=user)");
2130 if (filter
== NULL
) {
2134 ret
= pdb_ads_search_filter(m
, search
, filter
, acct_flags
, &sstate
);
2135 TALLOC_FREE(filter
);
2142 static bool pdb_ads_search_groups(struct pdb_methods
*m
,
2143 struct pdb_search
*search
)
2145 struct pdb_ads_search_state
*sstate
;
2149 filter
= talloc_asprintf(talloc_tos(),
2150 "(&(grouptype=%d)(objectclass=group))",
2151 GTYPE_SECURITY_GLOBAL_GROUP
);
2152 if (filter
== NULL
) {
2155 ret
= pdb_ads_search_filter(m
, search
, filter
, 0, &sstate
);
2156 TALLOC_FREE(filter
);
2163 static bool pdb_ads_search_aliases(struct pdb_methods
*m
,
2164 struct pdb_search
*search
,
2165 const struct dom_sid
*sid
)
2167 struct pdb_ads_search_state
*sstate
;
2171 filter
= talloc_asprintf(
2172 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
2173 sid_check_is_builtin(sid
)
2174 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2175 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
2177 if (filter
== NULL
) {
2180 ret
= pdb_ads_search_filter(m
, search
, filter
, 0, &sstate
);
2181 TALLOC_FREE(filter
);
2188 static bool pdb_ads_uid_to_sid(struct pdb_methods
*m
, uid_t uid
,
2189 struct dom_sid
*sid
)
2191 struct pdb_ads_state
*state
= talloc_get_type_abort(
2192 m
->private_data
, struct pdb_ads_state
);
2193 sid_compose(sid
, &state
->domainsid
, uid
);
2197 static bool pdb_ads_gid_to_sid(struct pdb_methods
*m
, gid_t gid
,
2198 struct dom_sid
*sid
)
2200 struct pdb_ads_state
*state
= talloc_get_type_abort(
2201 m
->private_data
, struct pdb_ads_state
);
2202 sid_compose(sid
, &state
->domainsid
, gid
);
2206 static bool pdb_ads_sid_to_id(struct pdb_methods
*m
, const struct dom_sid
*sid
,
2207 uid_t
*uid
, gid_t
*gid
, enum lsa_SidType
*type
)
2209 struct pdb_ads_state
*state
= talloc_get_type_abort(
2210 m
->private_data
, struct pdb_ads_state
);
2211 const char *attrs
[4] = { "objectClass", "samAccountType",
2212 "uidNumber", "gidNumber" };
2213 struct tldap_message
**msg
;
2214 char *sidstr
, *base
;
2222 sidstr
= sid_binstring_hex(sid
);
2223 if (sidstr
== NULL
) {
2226 base
= talloc_asprintf(talloc_tos(), "<SID=%s>", sidstr
);
2229 rc
= pdb_ads_search_fmt(
2230 state
, base
, TLDAP_SCOPE_BASE
,
2231 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &msg
,
2235 if (rc
!= TLDAP_SUCCESS
) {
2236 DEBUG(10, ("pdb_ads_search_fmt failed: %s\n",
2237 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2240 if (talloc_array_length(msg
) != 1) {
2241 DEBUG(10, ("Got %d objects, expected 1\n",
2242 (int)talloc_array_length(msg
)));
2245 if (!tldap_pull_uint32(msg
[0], "samAccountType", &atype
)) {
2246 DEBUG(10, ("samAccountType not found\n"));
2249 if (atype
== ATYPE_ACCOUNT
) {
2250 *type
= SID_NAME_USER
;
2251 if (!tldap_pull_uint32(msg
[0], "uidNumber", uid
)) {
2252 DEBUG(10, ("Did not find uidNumber\n"));
2256 *type
= SID_NAME_DOM_GRP
;
2257 if (!tldap_pull_uint32(msg
[0], "gidNumber", gid
)) {
2258 DEBUG(10, ("Did not find gidNumber\n"));
2268 static uint32_t pdb_ads_capabilities(struct pdb_methods
*m
)
2270 return PDB_CAP_STORE_RIDS
| PDB_CAP_ADS
;
2273 static bool pdb_ads_new_rid(struct pdb_methods
*m
, uint32
*rid
)
2278 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods
*m
,
2279 const char *domain
, char** pwd
,
2280 struct dom_sid
*sid
,
2281 time_t *pass_last_set_time
)
2286 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods
*m
,
2287 const char* domain
, const char* pwd
,
2288 const struct dom_sid
*sid
)
2293 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods
*m
,
2299 static NTSTATUS
pdb_ads_enum_trusteddoms(struct pdb_methods
*m
,
2300 TALLOC_CTX
*mem_ctx
,
2301 uint32
*num_domains
,
2302 struct trustdom_info
***domains
)
2306 return NT_STATUS_OK
;
2309 static void pdb_ads_init_methods(struct pdb_methods
*m
)
2312 m
->get_domain_info
= pdb_ads_get_domain_info
;
2313 m
->getsampwnam
= pdb_ads_getsampwnam
;
2314 m
->getsampwsid
= pdb_ads_getsampwsid
;
2315 m
->create_user
= pdb_ads_create_user
;
2316 m
->delete_user
= pdb_ads_delete_user
;
2317 m
->add_sam_account
= pdb_ads_add_sam_account
;
2318 m
->update_sam_account
= pdb_ads_update_sam_account
;
2319 m
->delete_sam_account
= pdb_ads_delete_sam_account
;
2320 m
->rename_sam_account
= pdb_ads_rename_sam_account
;
2321 m
->update_login_attempts
= pdb_ads_update_login_attempts
;
2322 m
->getgrsid
= pdb_ads_getgrsid
;
2323 m
->getgrgid
= pdb_ads_getgrgid
;
2324 m
->getgrnam
= pdb_ads_getgrnam
;
2325 m
->create_dom_group
= pdb_ads_create_dom_group
;
2326 m
->delete_dom_group
= pdb_ads_delete_dom_group
;
2327 m
->add_group_mapping_entry
= pdb_ads_add_group_mapping_entry
;
2328 m
->update_group_mapping_entry
= pdb_ads_update_group_mapping_entry
;
2329 m
->delete_group_mapping_entry
= pdb_ads_delete_group_mapping_entry
;
2330 m
->enum_group_mapping
= pdb_ads_enum_group_mapping
;
2331 m
->enum_group_members
= pdb_ads_enum_group_members
;
2332 m
->enum_group_memberships
= pdb_ads_enum_group_memberships
;
2333 m
->set_unix_primary_group
= pdb_ads_set_unix_primary_group
;
2334 m
->add_groupmem
= pdb_ads_add_groupmem
;
2335 m
->del_groupmem
= pdb_ads_del_groupmem
;
2336 m
->create_alias
= pdb_ads_create_alias
;
2337 m
->delete_alias
= pdb_ads_delete_alias
;
2338 m
->get_aliasinfo
= pdb_default_get_aliasinfo
;
2339 m
->set_aliasinfo
= pdb_ads_set_aliasinfo
;
2340 m
->add_aliasmem
= pdb_ads_add_aliasmem
;
2341 m
->del_aliasmem
= pdb_ads_del_aliasmem
;
2342 m
->enum_aliasmem
= pdb_ads_enum_aliasmem
;
2343 m
->enum_alias_memberships
= pdb_ads_enum_alias_memberships
;
2344 m
->lookup_rids
= pdb_ads_lookup_rids
;
2345 m
->lookup_names
= pdb_ads_lookup_names
;
2346 m
->get_account_policy
= pdb_ads_get_account_policy
;
2347 m
->set_account_policy
= pdb_ads_set_account_policy
;
2348 m
->get_seq_num
= pdb_ads_get_seq_num
;
2349 m
->search_users
= pdb_ads_search_users
;
2350 m
->search_groups
= pdb_ads_search_groups
;
2351 m
->search_aliases
= pdb_ads_search_aliases
;
2352 m
->uid_to_sid
= pdb_ads_uid_to_sid
;
2353 m
->gid_to_sid
= pdb_ads_gid_to_sid
;
2354 m
->sid_to_id
= pdb_ads_sid_to_id
;
2355 m
->capabilities
= pdb_ads_capabilities
;
2356 m
->new_rid
= pdb_ads_new_rid
;
2357 m
->get_trusteddom_pw
= pdb_ads_get_trusteddom_pw
;
2358 m
->set_trusteddom_pw
= pdb_ads_set_trusteddom_pw
;
2359 m
->del_trusteddom_pw
= pdb_ads_del_trusteddom_pw
;
2360 m
->enum_trusteddoms
= pdb_ads_enum_trusteddoms
;
2363 static void free_private_data(void **vp
)
2365 struct pdb_ads_state
*state
= talloc_get_type_abort(
2366 *vp
, struct pdb_ads_state
);
2368 TALLOC_FREE(state
->ld
);
2373 this is used to catch debug messages from events
2375 static void s3_tldap_debug(void *context
, enum tldap_debug_level level
,
2376 const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(3,0);
2378 static void s3_tldap_debug(void *context
, enum tldap_debug_level level
,
2379 const char *fmt
, va_list ap
)
2381 int samba_level
= -1;
2384 case TLDAP_DEBUG_FATAL
:
2387 case TLDAP_DEBUG_ERROR
:
2390 case TLDAP_DEBUG_WARNING
:
2393 case TLDAP_DEBUG_TRACE
:
2398 if (vasprintf(&s
, fmt
, ap
) == -1) {
2401 DEBUG(samba_level
, ("tldap: %s", s
));
2405 static struct tldap_context
*pdb_ads_ld(struct pdb_ads_state
*state
)
2410 if (tldap_connection_ok(state
->ld
)) {
2413 TALLOC_FREE(state
->ld
);
2415 status
= open_socket_out(
2416 (struct sockaddr_storage
*)(void *)&state
->socket_address
,
2418 if (!NT_STATUS_IS_OK(status
)) {
2419 DEBUG(10, ("Could not connect to %s: %s\n",
2420 state
->socket_address
.sun_path
, nt_errstr(status
)));
2424 set_blocking(fd
, false);
2426 state
->ld
= tldap_context_create(state
, fd
);
2427 if (state
->ld
== NULL
) {
2431 tldap_set_debug(state
->ld
, s3_tldap_debug
, NULL
);
2436 int pdb_ads_search_fmt(struct pdb_ads_state
*state
, const char *base
,
2437 int scope
, const char *attrs
[], int num_attrs
,
2439 TALLOC_CTX
*mem_ctx
, struct tldap_message
***res
,
2440 const char *fmt
, ...)
2442 struct tldap_context
*ld
;
2446 ld
= pdb_ads_ld(state
);
2448 return TLDAP_SERVER_DOWN
;
2452 ret
= tldap_search_va(ld
, base
, scope
, attrs
, num_attrs
, attrsonly
,
2453 mem_ctx
, res
, fmt
, ap
);
2456 if (ret
!= TLDAP_SERVER_DOWN
) {
2461 ld
= pdb_ads_ld(state
);
2463 return TLDAP_SERVER_DOWN
;
2467 ret
= tldap_search_va(ld
, base
, scope
, attrs
, num_attrs
, attrsonly
,
2468 mem_ctx
, res
, fmt
, ap
);
2473 static NTSTATUS
pdb_ads_connect(struct pdb_ads_state
*state
,
2474 const char *location
)
2476 const char *domain_attrs
[2] = { "objectSid", "objectGUID" };
2477 const char *ncname_attrs
[1] = { "netbiosname" };
2478 struct tldap_context
*ld
;
2479 struct tldap_message
*rootdse
, **domain
, **ncname
;
2480 TALLOC_CTX
*frame
= talloc_stackframe();
2485 ZERO_STRUCT(state
->socket_address
);
2486 state
->socket_address
.sun_family
= AF_UNIX
;
2487 strlcpy(state
->socket_address
.sun_path
, location
,
2488 sizeof(state
->socket_address
.sun_path
));
2490 ld
= pdb_ads_ld(state
);
2492 status
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2496 rc
= tldap_fetch_rootdse(ld
);
2497 if (rc
!= TLDAP_SUCCESS
) {
2498 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2499 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2500 status
= NT_STATUS_LDAP(rc
);
2503 rootdse
= tldap_rootdse(state
->ld
);
2505 state
->domaindn
= tldap_talloc_single_attribute(
2506 rootdse
, "defaultNamingContext", state
);
2507 if (state
->domaindn
== NULL
) {
2508 DEBUG(10, ("Could not get defaultNamingContext\n"));
2509 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2512 DEBUG(10, ("defaultNamingContext = %s\n", state
->domaindn
));
2514 state
->configdn
= tldap_talloc_single_attribute(
2515 rootdse
, "configurationNamingContext", state
);
2516 if (state
->configdn
== NULL
) {
2517 DEBUG(10, ("Could not get configurationNamingContext\n"));
2518 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2521 DEBUG(10, ("configurationNamingContext = %s\n", state
->configdn
));
2524 * Figure out our domain's SID
2526 rc
= pdb_ads_search_fmt(
2527 state
, state
->domaindn
, TLDAP_SCOPE_BASE
,
2528 domain_attrs
, ARRAY_SIZE(domain_attrs
), 0,
2529 talloc_tos(), &domain
, "(objectclass=*)");
2530 if (rc
!= TLDAP_SUCCESS
) {
2531 DEBUG(10, ("Could not retrieve domain: %s\n",
2532 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2533 status
= NT_STATUS_LDAP(rc
);
2537 num_domains
= talloc_array_length(domain
);
2538 if (num_domains
!= 1) {
2539 DEBUG(10, ("Got %d domains, expected one\n", num_domains
));
2540 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2543 if (!tldap_pull_binsid(domain
[0], "objectSid", &state
->domainsid
)) {
2544 DEBUG(10, ("Could not retrieve domain SID\n"));
2545 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2548 if (!tldap_pull_guid(domain
[0], "objectGUID", &state
->domainguid
)) {
2549 DEBUG(10, ("Could not retrieve domain GUID\n"));
2550 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2553 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state
->domainsid
)));
2556 * Figure out our domain's short name
2558 rc
= pdb_ads_search_fmt(
2559 state
, state
->configdn
, TLDAP_SCOPE_SUB
,
2560 ncname_attrs
, ARRAY_SIZE(ncname_attrs
), 0,
2561 talloc_tos(), &ncname
, "(ncname=%s)", state
->domaindn
);
2562 if (rc
!= TLDAP_SUCCESS
) {
2563 DEBUG(10, ("Could not retrieve ncname: %s\n",
2564 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2565 status
= NT_STATUS_LDAP(rc
);
2568 if (talloc_array_length(ncname
) != 1) {
2569 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2573 state
->netbiosname
= tldap_talloc_single_attribute(
2574 ncname
[0], "netbiosname", state
);
2575 if (state
->netbiosname
== NULL
) {
2576 DEBUG(10, ("Could not get netbiosname\n"));
2577 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2580 DEBUG(10, ("netbiosname: %s\n", state
->netbiosname
));
2582 if (!strequal(lp_workgroup(), state
->netbiosname
)) {
2583 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2584 state
->netbiosname
, lp_workgroup()));
2585 status
= NT_STATUS_NO_SUCH_DOMAIN
;
2589 secrets_store_domain_sid(state
->netbiosname
, &state
->domainsid
);
2591 status
= NT_STATUS_OK
;
2597 static NTSTATUS
pdb_ads_init_secrets(struct pdb_methods
*m
)
2599 #if _SAMBA_BUILD_ == 4
2600 struct pdb_domain_info
*dom_info
;
2603 dom_info
= pdb_ads_get_domain_info(m
, m
);
2605 return NT_STATUS_UNSUCCESSFUL
;
2608 secrets_clear_domain_protection(dom_info
->name
);
2609 ret
= secrets_store_domain_sid(dom_info
->name
,
2614 ret
= secrets_store_domain_guid(dom_info
->name
,
2619 ret
= secrets_mark_domain_protected(dom_info
->name
);
2625 TALLOC_FREE(dom_info
);
2627 return NT_STATUS_UNSUCCESSFUL
;
2630 return NT_STATUS_OK
;
2633 static NTSTATUS
pdb_init_ads(struct pdb_methods
**pdb_method
,
2634 const char *location
)
2636 struct pdb_methods
*m
;
2637 struct pdb_ads_state
*state
;
2641 m
= talloc(NULL
, struct pdb_methods
);
2643 return NT_STATUS_NO_MEMORY
;
2645 state
= talloc_zero(m
, struct pdb_ads_state
);
2646 if (state
== NULL
) {
2649 m
->private_data
= state
;
2650 m
->free_private_data
= free_private_data
;
2651 pdb_ads_init_methods(m
);
2653 if (location
== NULL
) {
2654 tmp
= talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2658 if (location
== NULL
) {
2662 status
= pdb_ads_connect(state
, location
);
2663 if (!NT_STATUS_IS_OK(status
)) {
2664 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status
)));
2668 status
= pdb_ads_init_secrets(m
);
2669 if (!NT_STATUS_IS_OK(status
)) {
2670 DEBUG(10, ("pdb_ads_init_secrets failed!\n"));
2675 return NT_STATUS_OK
;
2677 status
= NT_STATUS_NO_MEMORY
;
2683 NTSTATUS
pdb_ads_init(void);
2684 NTSTATUS
pdb_ads_init(void)
2686 return smb_register_passdb(PASSDB_INTERFACE_VERSION
, "ads",