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 fstrcpy(map
->nt_name
, str
);
804 str
= tldap_talloc_single_attribute(group
[0], "description",
807 fstrcpy(map
->comment
, str
);
810 map
->comment
[0] = '\0';
814 *pmsg
= talloc_move(mem_ctx
, &group
[0]);
820 static NTSTATUS
pdb_ads_getgrsid(struct pdb_methods
*m
, GROUP_MAP
*map
,
826 filter
= talloc_asprintf(talloc_tos(),
827 "(&(objectsid=%s)(objectclass=group))",
828 sid_string_talloc(talloc_tos(), &sid
));
829 if (filter
== NULL
) {
830 return NT_STATUS_NO_MEMORY
;
833 status
= pdb_ads_getgrfilter(m
, map
, filter
, NULL
, NULL
);
838 static NTSTATUS
pdb_ads_getgrgid(struct pdb_methods
*m
, GROUP_MAP
*map
,
842 pdb_ads_gid_to_sid(m
, gid
, &sid
);
843 return pdb_ads_getgrsid(m
, map
, sid
);
846 static NTSTATUS
pdb_ads_getgrnam(struct pdb_methods
*m
, GROUP_MAP
*map
,
852 filter
= talloc_asprintf(talloc_tos(),
853 "(&(samaccountname=%s)(objectclass=group))",
855 if (filter
== NULL
) {
856 return NT_STATUS_NO_MEMORY
;
859 status
= pdb_ads_getgrfilter(m
, map
, filter
, NULL
, NULL
);
864 static NTSTATUS
pdb_ads_create_dom_group(struct pdb_methods
*m
,
865 TALLOC_CTX
*mem_ctx
, const char *name
,
868 TALLOC_CTX
*frame
= talloc_stackframe();
869 struct pdb_ads_state
*state
= talloc_get_type_abort(
870 m
->private_data
, struct pdb_ads_state
);
871 struct tldap_context
*ld
;
872 const char *attrs
[1] = { "objectSid" };
874 struct tldap_mod
*mods
= NULL
;
875 struct tldap_message
**alias
;
881 ld
= pdb_ads_ld(state
);
883 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
886 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
890 return NT_STATUS_NO_MEMORY
;
893 ok
&= tldap_make_mod_fmt(
894 NULL
, talloc_tos(), &mods
, &num_mods
, "samAccountName", "%s",
896 ok
&= tldap_make_mod_fmt(
897 NULL
, talloc_tos(), &mods
, &num_mods
, "objectClass", "group");
898 ok
&= tldap_make_mod_fmt(
899 NULL
, talloc_tos(), &mods
, &num_mods
, "groupType",
900 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP
);
904 return NT_STATUS_NO_MEMORY
;
907 rc
= tldap_add(ld
, dn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
908 if (rc
!= TLDAP_SUCCESS
) {
909 DEBUG(10, ("ldap_add failed %s\n",
910 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
912 return NT_STATUS_LDAP(rc
);
915 rc
= pdb_ads_search_fmt(
916 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
917 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &alias
,
918 "(&(objectclass=group)(samaccountname=%s))", name
);
919 if (rc
!= TLDAP_SUCCESS
) {
920 DEBUG(10, ("Could not find just created alias %s: %s\n",
921 name
, tldap_errstr(talloc_tos(), state
->ld
, rc
)));
923 return NT_STATUS_LDAP(rc
);
926 if (talloc_array_length(alias
) != 1) {
927 DEBUG(10, ("Got %d alias, expected one\n",
928 (int)talloc_array_length(alias
)));
930 return NT_STATUS_LDAP(rc
);
933 if (!tldap_pull_binsid(alias
[0], "objectSid", &sid
)) {
934 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
937 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
940 sid_peek_rid(&sid
, rid
);
945 static NTSTATUS
pdb_ads_delete_dom_group(struct pdb_methods
*m
,
946 TALLOC_CTX
*mem_ctx
, uint32 rid
)
948 struct pdb_ads_state
*state
= talloc_get_type_abort(
949 m
->private_data
, struct pdb_ads_state
);
950 struct tldap_context
*ld
;
953 struct tldap_message
**msg
;
957 sid_compose(&sid
, &state
->domainsid
, rid
);
959 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), &sid
);
960 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
962 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
963 NULL
, 0, 0, talloc_tos(), &msg
,
964 ("(&(objectSid=%s)(objectClass=group))"),
967 if (rc
!= TLDAP_SUCCESS
) {
968 DEBUG(10, ("ldap_search failed %s\n",
969 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
970 return NT_STATUS_LDAP(rc
);
973 switch talloc_array_length(msg
) {
975 return NT_STATUS_NO_SUCH_GROUP
;
979 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
982 if (!tldap_entry_dn(msg
[0], &dn
)) {
984 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
987 ld
= pdb_ads_ld(state
);
990 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
993 rc
= tldap_delete(ld
, dn
, NULL
, 0, NULL
, 0);
995 if (rc
!= TLDAP_SUCCESS
) {
996 DEBUG(10, ("ldap_delete failed: %s\n",
997 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
998 return NT_STATUS_LDAP(rc
);
1001 return NT_STATUS_OK
;
1004 static NTSTATUS
pdb_ads_add_group_mapping_entry(struct pdb_methods
*m
,
1007 return NT_STATUS_NOT_IMPLEMENTED
;
1010 static NTSTATUS
pdb_ads_update_group_mapping_entry(struct pdb_methods
*m
,
1013 struct pdb_ads_state
*state
= talloc_get_type_abort(
1014 m
->private_data
, struct pdb_ads_state
);
1015 struct tldap_context
*ld
;
1016 struct tldap_mod
*mods
= NULL
;
1018 struct tldap_message
*existing
;
1020 GROUP_MAP existing_map
;
1021 int rc
, num_mods
= 0;
1025 ld
= pdb_ads_ld(state
);
1027 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1030 filter
= talloc_asprintf(talloc_tos(),
1031 "(&(objectsid=%s)(objectclass=group))",
1032 sid_string_talloc(talloc_tos(), &map
->sid
));
1033 if (filter
== NULL
) {
1034 return NT_STATUS_NO_MEMORY
;
1036 status
= pdb_ads_getgrfilter(m
, &existing_map
, filter
,
1037 talloc_tos(), &existing
);
1038 TALLOC_FREE(filter
);
1040 if (!tldap_entry_dn(existing
, &dn
)) {
1041 return NT_STATUS_LDAP(TLDAP_DECODING_ERROR
);
1046 ret
&= tldap_make_mod_fmt(
1047 existing
, talloc_tos(), &mods
, &num_mods
, "description",
1048 "%s", map
->comment
);
1049 ret
&= tldap_make_mod_fmt(
1050 existing
, talloc_tos(), &mods
, &num_mods
, "samaccountname",
1051 "%s", map
->nt_name
);
1054 return NT_STATUS_NO_MEMORY
;
1057 if (num_mods
== 0) {
1058 TALLOC_FREE(existing
);
1059 return NT_STATUS_OK
;
1062 rc
= tldap_modify(ld
, dn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
1063 if (rc
!= TLDAP_SUCCESS
) {
1064 DEBUG(10, ("ldap_modify for %s failed: %s\n", dn
,
1065 tldap_errstr(talloc_tos(), ld
, rc
)));
1066 TALLOC_FREE(existing
);
1067 return NT_STATUS_LDAP(rc
);
1069 TALLOC_FREE(existing
);
1070 return NT_STATUS_OK
;
1073 static NTSTATUS
pdb_ads_delete_group_mapping_entry(struct pdb_methods
*m
,
1076 return NT_STATUS_NOT_IMPLEMENTED
;
1079 static NTSTATUS
pdb_ads_enum_group_mapping(struct pdb_methods
*m
,
1080 const struct dom_sid
*sid
,
1081 enum lsa_SidType sid_name_use
,
1082 GROUP_MAP
**pp_rmap
,
1083 size_t *p_num_entries
,
1086 return NT_STATUS_NOT_IMPLEMENTED
;
1089 static NTSTATUS
pdb_ads_enum_group_members(struct pdb_methods
*m
,
1090 TALLOC_CTX
*mem_ctx
,
1091 const struct dom_sid
*group
,
1093 size_t *pnum_members
)
1095 struct pdb_ads_state
*state
= talloc_get_type_abort(
1096 m
->private_data
, struct pdb_ads_state
);
1097 const char *attrs
[1] = { "member" };
1099 struct tldap_message
**msg
;
1100 int i
, rc
, num_members
;
1104 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), group
);
1105 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1107 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1108 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1109 &msg
, "(objectsid=%s)", sidstr
);
1110 TALLOC_FREE(sidstr
);
1111 if (rc
!= TLDAP_SUCCESS
) {
1112 DEBUG(10, ("ldap_search failed %s\n",
1113 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1114 return NT_STATUS_LDAP(rc
);
1116 switch talloc_array_length(msg
) {
1118 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1123 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1127 if (!tldap_entry_values(msg
[0], "member", &blobs
, &num_members
)) {
1130 return NT_STATUS_OK
;
1133 members
= talloc_array(mem_ctx
, uint32_t, num_members
);
1134 if (members
== NULL
) {
1135 return NT_STATUS_NO_MEMORY
;
1138 for (i
=0; i
<num_members
; i
++) {
1140 if (!pdb_ads_dnblob2sid(state
, &blobs
[i
], &sid
)
1141 || !sid_peek_rid(&sid
, &members
[i
])) {
1142 TALLOC_FREE(members
);
1143 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1147 *pmembers
= members
;
1148 *pnum_members
= num_members
;
1149 return NT_STATUS_OK
;
1152 static NTSTATUS
pdb_ads_enum_group_memberships(struct pdb_methods
*m
,
1153 TALLOC_CTX
*mem_ctx
,
1155 struct dom_sid
**pp_sids
,
1157 uint32_t *p_num_groups
)
1159 struct pdb_ads_state
*state
= talloc_get_type_abort(
1160 m
->private_data
, struct pdb_ads_state
);
1161 struct pdb_ads_samu_private
*priv
;
1162 const char *attrs
[1] = { "objectSid" };
1163 struct tldap_message
**groups
;
1166 struct dom_sid
*group_sids
;
1169 priv
= pdb_ads_get_samu_private(m
, user
);
1171 rc
= pdb_ads_search_fmt(
1172 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1173 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &groups
,
1174 "(&(member=%s)(grouptype=%d)(objectclass=group))",
1175 priv
->dn
, GTYPE_SECURITY_GLOBAL_GROUP
);
1176 if (rc
!= TLDAP_SUCCESS
) {
1177 DEBUG(10, ("ldap_search failed %s\n",
1178 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1179 return NT_STATUS_LDAP(rc
);
1181 count
= talloc_array_length(groups
);
1184 * This happens for artificial samu users
1186 DEBUG(10, ("Could not get pdb_ads_samu_private\n"));
1190 group_sids
= talloc_array(mem_ctx
, struct dom_sid
, count
+1);
1191 if (group_sids
== NULL
) {
1192 return NT_STATUS_NO_MEMORY
;
1194 gids
= talloc_array(mem_ctx
, gid_t
, count
+1);
1196 TALLOC_FREE(group_sids
);
1197 return NT_STATUS_NO_MEMORY
;
1200 sid_copy(&group_sids
[0], pdb_get_group_sid(user
));
1201 if (!sid_to_gid(&group_sids
[0], &gids
[0])) {
1203 TALLOC_FREE(group_sids
);
1204 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1208 for (i
=0; i
<count
; i
++) {
1209 if (!tldap_pull_binsid(groups
[i
], "objectSid",
1210 &group_sids
[num_groups
])) {
1213 gids
[num_groups
] = pdb_ads_sid2gid(&group_sids
[num_groups
]);
1216 if (num_groups
== count
) {
1221 *pp_sids
= group_sids
;
1223 *p_num_groups
= num_groups
;
1224 return NT_STATUS_OK
;
1227 static NTSTATUS
pdb_ads_set_unix_primary_group(struct pdb_methods
*m
,
1228 TALLOC_CTX
*mem_ctx
,
1231 return NT_STATUS_NOT_IMPLEMENTED
;
1234 static NTSTATUS
pdb_ads_mod_groupmem(struct pdb_methods
*m
,
1235 TALLOC_CTX
*mem_ctx
,
1236 uint32 grouprid
, uint32 memberrid
,
1239 struct pdb_ads_state
*state
= talloc_get_type_abort(
1240 m
->private_data
, struct pdb_ads_state
);
1241 TALLOC_CTX
*frame
= talloc_stackframe();
1242 struct tldap_context
*ld
;
1243 struct dom_sid groupsid
, membersid
;
1244 char *groupdn
, *memberdn
;
1245 struct tldap_mod
*mods
;
1250 ld
= pdb_ads_ld(state
);
1252 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1255 sid_compose(&groupsid
, &state
->domainsid
, grouprid
);
1256 sid_compose(&membersid
, &state
->domainsid
, memberrid
);
1258 status
= pdb_ads_sid2dn(state
, &groupsid
, talloc_tos(), &groupdn
);
1259 if (!NT_STATUS_IS_OK(status
)) {
1261 return NT_STATUS_NO_SUCH_GROUP
;
1263 status
= pdb_ads_sid2dn(state
, &membersid
, talloc_tos(), &memberdn
);
1264 if (!NT_STATUS_IS_OK(status
)) {
1266 return NT_STATUS_NO_SUCH_USER
;
1272 if (!tldap_add_mod_str(talloc_tos(), &mods
, &num_mods
, mod_op
,
1273 "member", memberdn
)) {
1275 return NT_STATUS_NO_MEMORY
;
1278 rc
= tldap_modify(ld
, groupdn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
1280 if (rc
!= TLDAP_SUCCESS
) {
1281 DEBUG(10, ("ldap_modify failed: %s\n",
1282 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1283 if ((mod_op
== TLDAP_MOD_ADD
) &&
1284 (rc
== TLDAP_ALREADY_EXISTS
)) {
1285 return NT_STATUS_MEMBER_IN_GROUP
;
1287 if ((mod_op
== TLDAP_MOD_DELETE
) &&
1288 (rc
== TLDAP_UNWILLING_TO_PERFORM
)) {
1289 return NT_STATUS_MEMBER_NOT_IN_GROUP
;
1291 return NT_STATUS_LDAP(rc
);
1294 return NT_STATUS_OK
;
1297 static NTSTATUS
pdb_ads_add_groupmem(struct pdb_methods
*m
,
1298 TALLOC_CTX
*mem_ctx
,
1299 uint32 group_rid
, uint32 member_rid
)
1301 return pdb_ads_mod_groupmem(m
, mem_ctx
, group_rid
, member_rid
,
1305 static NTSTATUS
pdb_ads_del_groupmem(struct pdb_methods
*m
,
1306 TALLOC_CTX
*mem_ctx
,
1307 uint32 group_rid
, uint32 member_rid
)
1309 return pdb_ads_mod_groupmem(m
, mem_ctx
, group_rid
, member_rid
,
1313 static NTSTATUS
pdb_ads_create_alias(struct pdb_methods
*m
,
1314 const char *name
, uint32
*rid
)
1316 TALLOC_CTX
*frame
= talloc_stackframe();
1317 struct pdb_ads_state
*state
= talloc_get_type_abort(
1318 m
->private_data
, struct pdb_ads_state
);
1319 struct tldap_context
*ld
;
1320 const char *attrs
[1] = { "objectSid" };
1322 struct tldap_mod
*mods
= NULL
;
1323 struct tldap_message
**alias
;
1329 ld
= pdb_ads_ld(state
);
1331 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1334 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
1338 return NT_STATUS_NO_MEMORY
;
1341 ok
&= tldap_make_mod_fmt(
1342 NULL
, talloc_tos(), &mods
, &num_mods
, "samAccountName", "%s",
1344 ok
&= tldap_make_mod_fmt(
1345 NULL
, talloc_tos(), &mods
, &num_mods
, "objectClass", "group");
1346 ok
&= tldap_make_mod_fmt(
1347 NULL
, talloc_tos(), &mods
, &num_mods
, "groupType",
1348 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1352 return NT_STATUS_NO_MEMORY
;
1355 rc
= tldap_add(ld
, dn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
1356 if (rc
!= TLDAP_SUCCESS
) {
1357 DEBUG(10, ("ldap_add failed %s\n",
1358 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1360 return NT_STATUS_LDAP(rc
);
1363 rc
= pdb_ads_search_fmt(
1364 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1365 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &alias
,
1366 "(&(objectclass=group)(samaccountname=%s))", name
);
1367 if (rc
!= TLDAP_SUCCESS
) {
1368 DEBUG(10, ("Could not find just created alias %s: %s\n",
1369 name
, tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1371 return NT_STATUS_LDAP(rc
);
1374 if (talloc_array_length(alias
) != 1) {
1375 DEBUG(10, ("Got %d alias, expected one\n",
1376 (int)talloc_array_length(alias
)));
1378 return NT_STATUS_LDAP(rc
);
1381 if (!tldap_pull_binsid(alias
[0], "objectSid", &sid
)) {
1382 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1385 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1388 sid_peek_rid(&sid
, rid
);
1390 return NT_STATUS_OK
;
1393 static NTSTATUS
pdb_ads_delete_alias(struct pdb_methods
*m
,
1394 const struct dom_sid
*sid
)
1396 struct pdb_ads_state
*state
= talloc_get_type_abort(
1397 m
->private_data
, struct pdb_ads_state
);
1398 struct tldap_context
*ld
;
1399 struct tldap_message
**alias
;
1400 char *sidstr
, *dn
= NULL
;
1403 ld
= pdb_ads_ld(state
);
1405 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1408 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), sid
);
1409 if (sidstr
== NULL
) {
1410 return NT_STATUS_NO_MEMORY
;
1413 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1414 NULL
, 0, 0, talloc_tos(), &alias
,
1415 "(&(objectSid=%s)(objectclass=group)"
1416 "(|(grouptype=%d)(grouptype=%d)))",
1417 sidstr
, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1418 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1419 TALLOC_FREE(sidstr
);
1420 if (rc
!= TLDAP_SUCCESS
) {
1421 DEBUG(10, ("ldap_search failed: %s\n",
1422 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1423 return NT_STATUS_LDAP(rc
);
1425 if (talloc_array_length(alias
) != 1) {
1426 DEBUG(10, ("Expected 1 alias, got %d\n",
1427 (int)talloc_array_length(alias
)));
1428 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1430 if (!tldap_entry_dn(alias
[0], &dn
)) {
1431 DEBUG(10, ("Could not get DN for alias %s\n",
1432 sid_string_dbg(sid
)));
1433 return NT_STATUS_INTERNAL_ERROR
;
1436 rc
= tldap_delete(ld
, dn
, NULL
, 0, NULL
, 0);
1437 if (rc
!= TLDAP_SUCCESS
) {
1438 DEBUG(10, ("ldap_delete failed: %s\n",
1439 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1440 return NT_STATUS_LDAP(rc
);
1443 return NT_STATUS_OK
;
1446 static NTSTATUS
pdb_ads_set_aliasinfo(struct pdb_methods
*m
,
1447 const struct dom_sid
*sid
,
1448 struct acct_info
*info
)
1450 struct pdb_ads_state
*state
= talloc_get_type_abort(
1451 m
->private_data
, struct pdb_ads_state
);
1452 struct tldap_context
*ld
;
1453 const char *attrs
[3] = { "objectSid", "description",
1455 struct tldap_message
**msg
;
1458 struct tldap_mod
*mods
;
1462 ld
= pdb_ads_ld(state
);
1464 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1467 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), sid
);
1468 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1470 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1471 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1472 &msg
, "(&(objectSid=%s)(objectclass=group)"
1473 "(|(grouptype=%d)(grouptype=%d)))",
1474 sidstr
, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1475 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1476 TALLOC_FREE(sidstr
);
1477 if (rc
!= TLDAP_SUCCESS
) {
1478 DEBUG(10, ("ldap_search failed %s\n",
1479 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1480 return NT_STATUS_LDAP(rc
);
1482 switch talloc_array_length(msg
) {
1484 return NT_STATUS_NO_SUCH_ALIAS
;
1488 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1491 if (!tldap_entry_dn(msg
[0], &dn
)) {
1493 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1500 ok
&= tldap_make_mod_fmt(
1501 msg
[0], msg
, &mods
, &num_mods
, "description",
1502 "%s", info
->acct_desc
);
1503 ok
&= tldap_make_mod_fmt(
1504 msg
[0], msg
, &mods
, &num_mods
, "samAccountName",
1505 "%s", info
->acct_name
);
1508 return NT_STATUS_NO_MEMORY
;
1510 if (num_mods
== 0) {
1513 return NT_STATUS_OK
;
1516 rc
= tldap_modify(ld
, dn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
1518 if (rc
!= TLDAP_SUCCESS
) {
1519 DEBUG(10, ("ldap_modify failed: %s\n",
1520 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1521 return NT_STATUS_LDAP(rc
);
1523 return NT_STATUS_OK
;
1526 static NTSTATUS
pdb_ads_sid2dn(struct pdb_ads_state
*state
,
1527 const struct dom_sid
*sid
,
1528 TALLOC_CTX
*mem_ctx
, char **pdn
)
1530 struct tldap_message
**msg
;
1534 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), sid
);
1535 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1537 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1538 NULL
, 0, 0, talloc_tos(), &msg
,
1539 "(objectsid=%s)", sidstr
);
1540 TALLOC_FREE(sidstr
);
1541 if (rc
!= TLDAP_SUCCESS
) {
1542 DEBUG(10, ("ldap_search failed %s\n",
1543 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1544 return NT_STATUS_LDAP(rc
);
1547 switch talloc_array_length(msg
) {
1549 return NT_STATUS_NOT_FOUND
;
1553 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1556 if (!tldap_entry_dn(msg
[0], &dn
)) {
1557 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1560 dn
= talloc_strdup(mem_ctx
, dn
);
1562 return NT_STATUS_NO_MEMORY
;
1567 return NT_STATUS_OK
;
1570 static NTSTATUS
pdb_ads_mod_aliasmem(struct pdb_methods
*m
,
1571 const struct dom_sid
*alias
,
1572 const struct dom_sid
*member
,
1575 struct pdb_ads_state
*state
= talloc_get_type_abort(
1576 m
->private_data
, struct pdb_ads_state
);
1577 struct tldap_context
*ld
;
1578 TALLOC_CTX
*frame
= talloc_stackframe();
1579 struct tldap_mod
*mods
;
1582 char *aliasdn
, *memberdn
;
1585 ld
= pdb_ads_ld(state
);
1587 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1590 status
= pdb_ads_sid2dn(state
, alias
, talloc_tos(), &aliasdn
);
1591 if (!NT_STATUS_IS_OK(status
)) {
1592 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1593 sid_string_dbg(alias
), nt_errstr(status
)));
1595 return NT_STATUS_NO_SUCH_ALIAS
;
1597 status
= pdb_ads_sid2dn(state
, member
, talloc_tos(), &memberdn
);
1598 if (!NT_STATUS_IS_OK(status
)) {
1599 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1600 sid_string_dbg(member
), nt_errstr(status
)));
1608 if (!tldap_add_mod_str(talloc_tos(), &mods
, &num_mods
, mod_op
,
1609 "member", memberdn
)) {
1611 return NT_STATUS_NO_MEMORY
;
1614 rc
= tldap_modify(ld
, aliasdn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
1616 if (rc
!= TLDAP_SUCCESS
) {
1617 DEBUG(10, ("ldap_modify failed: %s\n",
1618 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1619 if (rc
== TLDAP_TYPE_OR_VALUE_EXISTS
) {
1620 return NT_STATUS_MEMBER_IN_ALIAS
;
1622 if (rc
== TLDAP_NO_SUCH_ATTRIBUTE
) {
1623 return NT_STATUS_MEMBER_NOT_IN_ALIAS
;
1625 return NT_STATUS_LDAP(rc
);
1628 return NT_STATUS_OK
;
1631 static NTSTATUS
pdb_ads_add_aliasmem(struct pdb_methods
*m
,
1632 const struct dom_sid
*alias
,
1633 const struct dom_sid
*member
)
1635 return pdb_ads_mod_aliasmem(m
, alias
, member
, TLDAP_MOD_ADD
);
1638 static NTSTATUS
pdb_ads_del_aliasmem(struct pdb_methods
*m
,
1639 const struct dom_sid
*alias
,
1640 const struct dom_sid
*member
)
1642 return pdb_ads_mod_aliasmem(m
, alias
, member
, TLDAP_MOD_DELETE
);
1645 static bool pdb_ads_dnblob2sid(struct pdb_ads_state
*state
, DATA_BLOB
*dnblob
,
1646 struct dom_sid
*psid
)
1648 const char *attrs
[1] = { "objectSid" };
1649 struct tldap_message
**msg
;
1655 if (!convert_string_talloc(talloc_tos(), CH_UTF8
, CH_UNIX
,
1656 dnblob
->data
, dnblob
->length
, &dn
, &len
)) {
1659 rc
= pdb_ads_search_fmt(state
, dn
, TLDAP_SCOPE_BASE
,
1660 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1661 &msg
, "(objectclass=*)");
1663 if (talloc_array_length(msg
) != 1) {
1664 DEBUG(10, ("Got %d objects, expected one\n",
1665 (int)talloc_array_length(msg
)));
1670 ret
= tldap_pull_binsid(msg
[0], "objectSid", psid
);
1675 static NTSTATUS
pdb_ads_enum_aliasmem(struct pdb_methods
*m
,
1676 const struct dom_sid
*alias
,
1677 TALLOC_CTX
*mem_ctx
,
1678 struct dom_sid
**pmembers
,
1679 size_t *pnum_members
)
1681 struct pdb_ads_state
*state
= talloc_get_type_abort(
1682 m
->private_data
, struct pdb_ads_state
);
1683 const char *attrs
[1] = { "member" };
1685 struct tldap_message
**msg
;
1686 int i
, rc
, num_members
;
1688 struct dom_sid
*members
;
1690 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), alias
);
1691 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1693 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1694 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1695 &msg
, "(objectsid=%s)", sidstr
);
1696 TALLOC_FREE(sidstr
);
1697 if (rc
!= TLDAP_SUCCESS
) {
1698 DEBUG(10, ("ldap_search failed %s\n",
1699 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1700 return NT_STATUS_LDAP(rc
);
1702 switch talloc_array_length(msg
) {
1704 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1709 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1713 if (!tldap_entry_values(msg
[0], "member", &blobs
, &num_members
)) {
1716 return NT_STATUS_OK
;
1719 members
= talloc_array(mem_ctx
, struct dom_sid
, num_members
);
1720 if (members
== NULL
) {
1721 return NT_STATUS_NO_MEMORY
;
1724 for (i
=0; i
<num_members
; i
++) {
1725 if (!pdb_ads_dnblob2sid(state
, &blobs
[i
], &members
[i
])) {
1726 TALLOC_FREE(members
);
1727 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1731 *pmembers
= members
;
1732 *pnum_members
= num_members
;
1733 return NT_STATUS_OK
;
1736 static NTSTATUS
pdb_ads_enum_alias_memberships(struct pdb_methods
*m
,
1737 TALLOC_CTX
*mem_ctx
,
1738 const struct dom_sid
*domain_sid
,
1739 const struct dom_sid
*members
,
1741 uint32_t **palias_rids
,
1742 size_t *pnum_alias_rids
)
1744 struct pdb_ads_state
*state
= talloc_get_type_abort(
1745 m
->private_data
, struct pdb_ads_state
);
1746 const char *attrs
[1] = { "objectSid" };
1747 struct tldap_message
**msg
= NULL
;
1748 uint32_t *alias_rids
= NULL
;
1749 size_t num_alias_rids
= 0;
1751 bool got_members
= false;
1756 * TODO: Get the filter right so that we only get the aliases from
1757 * either the SAM or BUILTIN
1760 filter
= talloc_asprintf(talloc_tos(),
1761 "(&(|(grouptype=%d)(grouptype=%d))"
1762 "(objectclass=group)(|",
1763 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1764 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1765 if (filter
== NULL
) {
1766 return NT_STATUS_NO_MEMORY
;
1769 for (i
=0; i
<num_members
; i
++) {
1772 status
= pdb_ads_sid2dn(state
, &members
[i
], talloc_tos(), &dn
);
1773 if (!NT_STATUS_IS_OK(status
)) {
1774 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1775 sid_string_dbg(&members
[i
]),
1776 nt_errstr(status
)));
1779 filter
= talloc_asprintf_append_buffer(
1780 filter
, "(member=%s)", dn
);
1782 if (filter
== NULL
) {
1783 return NT_STATUS_NO_MEMORY
;
1792 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1793 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1794 &msg
, "%s))", filter
);
1795 TALLOC_FREE(filter
);
1796 if (rc
!= TLDAP_SUCCESS
) {
1797 DEBUG(10, ("tldap_search failed %s\n",
1798 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1799 return NT_STATUS_LDAP(rc
);
1802 count
= talloc_array_length(msg
);
1807 alias_rids
= talloc_array(mem_ctx
, uint32_t, count
);
1808 if (alias_rids
== NULL
) {
1810 return NT_STATUS_NO_MEMORY
;
1813 for (i
=0; i
<count
; i
++) {
1816 if (!tldap_pull_binsid(msg
[i
], "objectSid", &sid
)) {
1817 DEBUG(10, ("Could not pull SID for member %d\n", i
));
1820 if (sid_peek_check_rid(domain_sid
, &sid
,
1821 &alias_rids
[num_alias_rids
])) {
1822 num_alias_rids
+= 1;
1827 *palias_rids
= alias_rids
;
1828 *pnum_alias_rids
= 0;
1829 return NT_STATUS_OK
;
1832 static NTSTATUS
pdb_ads_lookup_rids(struct pdb_methods
*m
,
1833 const struct dom_sid
*domain_sid
,
1837 enum lsa_SidType
*lsa_attrs
)
1839 struct pdb_ads_state
*state
= talloc_get_type_abort(
1840 m
->private_data
, struct pdb_ads_state
);
1841 const char *attrs
[2] = { "sAMAccountType", "sAMAccountName" };
1844 if (num_rids
== 0) {
1845 return NT_STATUS_NONE_MAPPED
;
1850 for (i
=0; i
<num_rids
; i
++) {
1852 struct tldap_message
**msg
;
1857 lsa_attrs
[i
] = SID_NAME_UNKNOWN
;
1859 sid_compose(&sid
, domain_sid
, rids
[i
]);
1861 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), &sid
);
1862 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1864 rc
= pdb_ads_search_fmt(state
, state
->domaindn
,
1865 TLDAP_SCOPE_SUB
, attrs
,
1866 ARRAY_SIZE(attrs
), 0, talloc_tos(),
1867 &msg
, "(objectsid=%s)", sidstr
);
1868 TALLOC_FREE(sidstr
);
1869 if (rc
!= TLDAP_SUCCESS
) {
1870 DEBUG(10, ("ldap_search failed %s\n",
1871 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1875 switch talloc_array_length(msg
) {
1877 DEBUG(10, ("rid %d not found\n", (int)rids
[i
]));
1882 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1885 names
[i
] = tldap_talloc_single_attribute(
1886 msg
[0], "samAccountName", talloc_tos());
1887 if (names
[i
] == NULL
) {
1888 DEBUG(10, ("no samAccountName\n"));
1891 if (!tldap_pull_uint32(msg
[0], "samAccountType", &attr
)) {
1892 DEBUG(10, ("no samAccountType"));
1895 lsa_attrs
[i
] = ds_atype_map(attr
);
1899 if (num_mapped
== 0) {
1900 return NT_STATUS_NONE_MAPPED
;
1902 if (num_mapped
< num_rids
) {
1903 return STATUS_SOME_UNMAPPED
;
1905 return NT_STATUS_OK
;
1908 static NTSTATUS
pdb_ads_lookup_names(struct pdb_methods
*m
,
1909 const struct dom_sid
*domain_sid
,
1911 const char **pp_names
,
1913 enum lsa_SidType
*attrs
)
1915 return NT_STATUS_NOT_IMPLEMENTED
;
1918 static NTSTATUS
pdb_ads_get_account_policy(struct pdb_methods
*m
,
1919 enum pdb_policy_type type
,
1922 return account_policy_get(type
, value
)
1923 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1926 static NTSTATUS
pdb_ads_set_account_policy(struct pdb_methods
*m
,
1927 enum pdb_policy_type type
,
1930 return account_policy_set(type
, value
)
1931 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1934 static NTSTATUS
pdb_ads_get_seq_num(struct pdb_methods
*m
,
1937 return NT_STATUS_NOT_IMPLEMENTED
;
1940 struct pdb_ads_search_state
{
1941 uint32_t acct_flags
;
1942 struct samr_displayentry
*entries
;
1943 uint32_t num_entries
;
1948 static bool pdb_ads_next_entry(struct pdb_search
*search
,
1949 struct samr_displayentry
*entry
)
1951 struct pdb_ads_search_state
*state
= talloc_get_type_abort(
1952 search
->private_data
, struct pdb_ads_search_state
);
1954 if (state
->current
== state
->num_entries
) {
1958 entry
->idx
= state
->entries
[state
->current
].idx
;
1959 entry
->rid
= state
->entries
[state
->current
].rid
;
1960 entry
->acct_flags
= state
->entries
[state
->current
].acct_flags
;
1962 entry
->account_name
= talloc_strdup(
1963 search
, state
->entries
[state
->current
].account_name
);
1964 entry
->fullname
= talloc_strdup(
1965 search
, state
->entries
[state
->current
].fullname
);
1966 entry
->description
= talloc_strdup(
1967 search
, state
->entries
[state
->current
].description
);
1969 if ((entry
->account_name
== NULL
) || (entry
->fullname
== NULL
)
1970 || (entry
->description
== NULL
)) {
1971 DEBUG(0, ("talloc_strdup failed\n"));
1975 state
->current
+= 1;
1979 static void pdb_ads_search_end(struct pdb_search
*search
)
1981 struct pdb_ads_search_state
*state
= talloc_get_type_abort(
1982 search
->private_data
, struct pdb_ads_search_state
);
1986 static bool pdb_ads_search_filter(struct pdb_methods
*m
,
1987 struct pdb_search
*search
,
1989 uint32_t acct_flags
,
1990 struct pdb_ads_search_state
**pstate
)
1992 struct pdb_ads_state
*state
= talloc_get_type_abort(
1993 m
->private_data
, struct pdb_ads_state
);
1994 struct pdb_ads_search_state
*sstate
;
1995 const char * attrs
[] = { "objectSid", "sAMAccountName", "displayName",
1996 "userAccountControl", "description" };
1997 struct tldap_message
**users
;
1998 int i
, rc
, num_users
;
2000 sstate
= talloc_zero(search
, struct pdb_ads_search_state
);
2001 if (sstate
== NULL
) {
2004 sstate
->acct_flags
= acct_flags
;
2006 rc
= pdb_ads_search_fmt(
2007 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
2008 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &users
,
2010 if (rc
!= TLDAP_SUCCESS
) {
2011 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
2012 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2016 num_users
= talloc_array_length(users
);
2018 sstate
->entries
= talloc_array(sstate
, struct samr_displayentry
,
2020 if (sstate
->entries
== NULL
) {
2021 DEBUG(10, ("talloc failed\n"));
2025 sstate
->num_entries
= 0;
2027 for (i
=0; i
<num_users
; i
++) {
2028 struct samr_displayentry
*e
;
2032 e
= &sstate
->entries
[sstate
->num_entries
];
2034 e
->idx
= sstate
->num_entries
;
2035 if (!tldap_pull_binsid(users
[i
], "objectSid", &sid
)) {
2036 DEBUG(10, ("Could not pull sid\n"));
2039 sid_peek_rid(&sid
, &e
->rid
);
2041 if (tldap_pull_uint32(users
[i
], "userAccountControl", &ctrl
)) {
2043 e
->acct_flags
= ds_uf2acb(ctrl
);
2045 DEBUG(10, ("pdb_ads_search_filter: Found %x, "
2046 "filter %x\n", (int)e
->acct_flags
,
2047 (int)sstate
->acct_flags
));
2050 if ((sstate
->acct_flags
!= 0) &&
2051 ((sstate
->acct_flags
& e
->acct_flags
) == 0)) {
2055 if (e
->acct_flags
& (ACB_WSTRUST
|ACB_SVRTRUST
)) {
2056 e
->acct_flags
|= ACB_NORMAL
;
2059 e
->acct_flags
= ACB_NORMAL
;
2062 if (e
->rid
== DOMAIN_RID_GUEST
) {
2064 * Guest is specially crafted in s3. Make
2065 * QueryDisplayInfo match QueryUserInfo
2067 e
->account_name
= lp_guestaccount();
2068 e
->fullname
= lp_guestaccount();
2069 e
->description
= "";
2070 e
->acct_flags
= ACB_NORMAL
;
2072 e
->account_name
= tldap_talloc_single_attribute(
2073 users
[i
], "samAccountName", sstate
->entries
);
2074 e
->fullname
= tldap_talloc_single_attribute(
2075 users
[i
], "displayName", sstate
->entries
);
2076 e
->description
= tldap_talloc_single_attribute(
2077 users
[i
], "description", sstate
->entries
);
2079 if (e
->account_name
== NULL
) {
2082 if (e
->fullname
== NULL
) {
2085 if (e
->description
== NULL
) {
2086 e
->description
= "";
2089 sstate
->num_entries
+= 1;
2090 if (sstate
->num_entries
>= num_users
) {
2095 search
->private_data
= sstate
;
2096 search
->next_entry
= pdb_ads_next_entry
;
2097 search
->search_end
= pdb_ads_search_end
;
2102 static bool pdb_ads_search_users(struct pdb_methods
*m
,
2103 struct pdb_search
*search
,
2106 struct pdb_ads_search_state
*sstate
;
2110 DEBUG(10, ("pdb_ads_search_users got flags %x\n", acct_flags
));
2112 if (acct_flags
& ACB_NORMAL
) {
2113 filter
= talloc_asprintf(
2115 "(&(objectclass=user)(sAMAccountType=%d))",
2116 ATYPE_NORMAL_ACCOUNT
);
2117 } else if (acct_flags
& ACB_WSTRUST
) {
2118 filter
= talloc_asprintf(
2120 "(&(objectclass=user)(sAMAccountType=%d))",
2121 ATYPE_WORKSTATION_TRUST
);
2123 filter
= talloc_strdup(talloc_tos(), "(objectclass=user)");
2125 if (filter
== NULL
) {
2129 ret
= pdb_ads_search_filter(m
, search
, filter
, acct_flags
, &sstate
);
2130 TALLOC_FREE(filter
);
2137 static bool pdb_ads_search_groups(struct pdb_methods
*m
,
2138 struct pdb_search
*search
)
2140 struct pdb_ads_search_state
*sstate
;
2144 filter
= talloc_asprintf(talloc_tos(),
2145 "(&(grouptype=%d)(objectclass=group))",
2146 GTYPE_SECURITY_GLOBAL_GROUP
);
2147 if (filter
== NULL
) {
2150 ret
= pdb_ads_search_filter(m
, search
, filter
, 0, &sstate
);
2151 TALLOC_FREE(filter
);
2158 static bool pdb_ads_search_aliases(struct pdb_methods
*m
,
2159 struct pdb_search
*search
,
2160 const struct dom_sid
*sid
)
2162 struct pdb_ads_search_state
*sstate
;
2166 filter
= talloc_asprintf(
2167 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
2168 sid_check_is_builtin(sid
)
2169 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2170 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
2172 if (filter
== NULL
) {
2175 ret
= pdb_ads_search_filter(m
, search
, filter
, 0, &sstate
);
2176 TALLOC_FREE(filter
);
2183 static bool pdb_ads_uid_to_sid(struct pdb_methods
*m
, uid_t uid
,
2184 struct dom_sid
*sid
)
2186 struct pdb_ads_state
*state
= talloc_get_type_abort(
2187 m
->private_data
, struct pdb_ads_state
);
2188 sid_compose(sid
, &state
->domainsid
, uid
);
2192 static bool pdb_ads_gid_to_sid(struct pdb_methods
*m
, gid_t gid
,
2193 struct dom_sid
*sid
)
2195 struct pdb_ads_state
*state
= talloc_get_type_abort(
2196 m
->private_data
, struct pdb_ads_state
);
2197 sid_compose(sid
, &state
->domainsid
, gid
);
2201 static bool pdb_ads_sid_to_id(struct pdb_methods
*m
, const struct dom_sid
*sid
,
2202 union unid_t
*id
, enum lsa_SidType
*type
)
2204 struct pdb_ads_state
*state
= talloc_get_type_abort(
2205 m
->private_data
, struct pdb_ads_state
);
2206 const char *attrs
[4] = { "objectClass", "samAccountType",
2207 "uidNumber", "gidNumber" };
2208 struct tldap_message
**msg
;
2209 char *sidstr
, *base
;
2214 sidstr
= sid_binstring_hex(sid
);
2215 if (sidstr
== NULL
) {
2218 base
= talloc_asprintf(talloc_tos(), "<SID=%s>", sidstr
);
2221 rc
= pdb_ads_search_fmt(
2222 state
, base
, TLDAP_SCOPE_BASE
,
2223 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &msg
,
2227 if (rc
!= TLDAP_SUCCESS
) {
2228 DEBUG(10, ("pdb_ads_search_fmt failed: %s\n",
2229 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2232 if (talloc_array_length(msg
) != 1) {
2233 DEBUG(10, ("Got %d objects, expected 1\n",
2234 (int)talloc_array_length(msg
)));
2237 if (!tldap_pull_uint32(msg
[0], "samAccountType", &atype
)) {
2238 DEBUG(10, ("samAccountType not found\n"));
2241 if (atype
== ATYPE_ACCOUNT
) {
2243 *type
= SID_NAME_USER
;
2244 if (!tldap_pull_uint32(msg
[0], "uidNumber", &uid
)) {
2245 DEBUG(10, ("Did not find uidNumber\n"));
2251 *type
= SID_NAME_DOM_GRP
;
2252 if (!tldap_pull_uint32(msg
[0], "gidNumber", &gid
)) {
2253 DEBUG(10, ("Did not find gidNumber\n"));
2264 static uint32_t pdb_ads_capabilities(struct pdb_methods
*m
)
2266 return PDB_CAP_STORE_RIDS
| PDB_CAP_ADS
;
2269 static bool pdb_ads_new_rid(struct pdb_methods
*m
, uint32
*rid
)
2274 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods
*m
,
2275 const char *domain
, char** pwd
,
2276 struct dom_sid
*sid
,
2277 time_t *pass_last_set_time
)
2282 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods
*m
,
2283 const char* domain
, const char* pwd
,
2284 const struct dom_sid
*sid
)
2289 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods
*m
,
2295 static NTSTATUS
pdb_ads_enum_trusteddoms(struct pdb_methods
*m
,
2296 TALLOC_CTX
*mem_ctx
,
2297 uint32
*num_domains
,
2298 struct trustdom_info
***domains
)
2302 return NT_STATUS_OK
;
2305 static void pdb_ads_init_methods(struct pdb_methods
*m
)
2308 m
->get_domain_info
= pdb_ads_get_domain_info
;
2309 m
->getsampwnam
= pdb_ads_getsampwnam
;
2310 m
->getsampwsid
= pdb_ads_getsampwsid
;
2311 m
->create_user
= pdb_ads_create_user
;
2312 m
->delete_user
= pdb_ads_delete_user
;
2313 m
->add_sam_account
= pdb_ads_add_sam_account
;
2314 m
->update_sam_account
= pdb_ads_update_sam_account
;
2315 m
->delete_sam_account
= pdb_ads_delete_sam_account
;
2316 m
->rename_sam_account
= pdb_ads_rename_sam_account
;
2317 m
->update_login_attempts
= pdb_ads_update_login_attempts
;
2318 m
->getgrsid
= pdb_ads_getgrsid
;
2319 m
->getgrgid
= pdb_ads_getgrgid
;
2320 m
->getgrnam
= pdb_ads_getgrnam
;
2321 m
->create_dom_group
= pdb_ads_create_dom_group
;
2322 m
->delete_dom_group
= pdb_ads_delete_dom_group
;
2323 m
->add_group_mapping_entry
= pdb_ads_add_group_mapping_entry
;
2324 m
->update_group_mapping_entry
= pdb_ads_update_group_mapping_entry
;
2325 m
->delete_group_mapping_entry
= pdb_ads_delete_group_mapping_entry
;
2326 m
->enum_group_mapping
= pdb_ads_enum_group_mapping
;
2327 m
->enum_group_members
= pdb_ads_enum_group_members
;
2328 m
->enum_group_memberships
= pdb_ads_enum_group_memberships
;
2329 m
->set_unix_primary_group
= pdb_ads_set_unix_primary_group
;
2330 m
->add_groupmem
= pdb_ads_add_groupmem
;
2331 m
->del_groupmem
= pdb_ads_del_groupmem
;
2332 m
->create_alias
= pdb_ads_create_alias
;
2333 m
->delete_alias
= pdb_ads_delete_alias
;
2334 m
->get_aliasinfo
= pdb_default_get_aliasinfo
;
2335 m
->set_aliasinfo
= pdb_ads_set_aliasinfo
;
2336 m
->add_aliasmem
= pdb_ads_add_aliasmem
;
2337 m
->del_aliasmem
= pdb_ads_del_aliasmem
;
2338 m
->enum_aliasmem
= pdb_ads_enum_aliasmem
;
2339 m
->enum_alias_memberships
= pdb_ads_enum_alias_memberships
;
2340 m
->lookup_rids
= pdb_ads_lookup_rids
;
2341 m
->lookup_names
= pdb_ads_lookup_names
;
2342 m
->get_account_policy
= pdb_ads_get_account_policy
;
2343 m
->set_account_policy
= pdb_ads_set_account_policy
;
2344 m
->get_seq_num
= pdb_ads_get_seq_num
;
2345 m
->search_users
= pdb_ads_search_users
;
2346 m
->search_groups
= pdb_ads_search_groups
;
2347 m
->search_aliases
= pdb_ads_search_aliases
;
2348 m
->uid_to_sid
= pdb_ads_uid_to_sid
;
2349 m
->gid_to_sid
= pdb_ads_gid_to_sid
;
2350 m
->sid_to_id
= pdb_ads_sid_to_id
;
2351 m
->capabilities
= pdb_ads_capabilities
;
2352 m
->new_rid
= pdb_ads_new_rid
;
2353 m
->get_trusteddom_pw
= pdb_ads_get_trusteddom_pw
;
2354 m
->set_trusteddom_pw
= pdb_ads_set_trusteddom_pw
;
2355 m
->del_trusteddom_pw
= pdb_ads_del_trusteddom_pw
;
2356 m
->enum_trusteddoms
= pdb_ads_enum_trusteddoms
;
2359 static void free_private_data(void **vp
)
2361 struct pdb_ads_state
*state
= talloc_get_type_abort(
2362 *vp
, struct pdb_ads_state
);
2364 TALLOC_FREE(state
->ld
);
2369 this is used to catch debug messages from events
2371 static void s3_tldap_debug(void *context
, enum tldap_debug_level level
,
2372 const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(3,0);
2374 static void s3_tldap_debug(void *context
, enum tldap_debug_level level
,
2375 const char *fmt
, va_list ap
)
2377 int samba_level
= -1;
2380 case TLDAP_DEBUG_FATAL
:
2383 case TLDAP_DEBUG_ERROR
:
2386 case TLDAP_DEBUG_WARNING
:
2389 case TLDAP_DEBUG_TRACE
:
2394 if (vasprintf(&s
, fmt
, ap
) == -1) {
2397 DEBUG(samba_level
, ("tldap: %s", s
));
2401 static struct tldap_context
*pdb_ads_ld(struct pdb_ads_state
*state
)
2406 if (tldap_connection_ok(state
->ld
)) {
2409 TALLOC_FREE(state
->ld
);
2411 status
= open_socket_out(
2412 (struct sockaddr_storage
*)(void *)&state
->socket_address
,
2414 if (!NT_STATUS_IS_OK(status
)) {
2415 DEBUG(10, ("Could not connect to %s: %s\n",
2416 state
->socket_address
.sun_path
, nt_errstr(status
)));
2420 set_blocking(fd
, false);
2422 state
->ld
= tldap_context_create(state
, fd
);
2423 if (state
->ld
== NULL
) {
2427 tldap_set_debug(state
->ld
, s3_tldap_debug
, NULL
);
2432 int pdb_ads_search_fmt(struct pdb_ads_state
*state
, const char *base
,
2433 int scope
, const char *attrs
[], int num_attrs
,
2435 TALLOC_CTX
*mem_ctx
, struct tldap_message
***res
,
2436 const char *fmt
, ...)
2438 struct tldap_context
*ld
;
2442 ld
= pdb_ads_ld(state
);
2444 return TLDAP_SERVER_DOWN
;
2448 ret
= tldap_search_va(ld
, base
, scope
, attrs
, num_attrs
, attrsonly
,
2449 mem_ctx
, res
, fmt
, ap
);
2452 if (ret
!= TLDAP_SERVER_DOWN
) {
2457 ld
= pdb_ads_ld(state
);
2459 return TLDAP_SERVER_DOWN
;
2463 ret
= tldap_search_va(ld
, base
, scope
, attrs
, num_attrs
, attrsonly
,
2464 mem_ctx
, res
, fmt
, ap
);
2469 static NTSTATUS
pdb_ads_connect(struct pdb_ads_state
*state
,
2470 const char *location
)
2472 const char *domain_attrs
[2] = { "objectSid", "objectGUID" };
2473 const char *ncname_attrs
[1] = { "netbiosname" };
2474 struct tldap_context
*ld
;
2475 struct tldap_message
*rootdse
, **domain
, **ncname
;
2476 TALLOC_CTX
*frame
= talloc_stackframe();
2481 ZERO_STRUCT(state
->socket_address
);
2482 state
->socket_address
.sun_family
= AF_UNIX
;
2483 strlcpy(state
->socket_address
.sun_path
, location
,
2484 sizeof(state
->socket_address
.sun_path
));
2486 ld
= pdb_ads_ld(state
);
2488 status
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2492 rc
= tldap_fetch_rootdse(ld
);
2493 if (rc
!= TLDAP_SUCCESS
) {
2494 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2495 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2496 status
= NT_STATUS_LDAP(rc
);
2499 rootdse
= tldap_rootdse(state
->ld
);
2501 state
->domaindn
= tldap_talloc_single_attribute(
2502 rootdse
, "defaultNamingContext", state
);
2503 if (state
->domaindn
== NULL
) {
2504 DEBUG(10, ("Could not get defaultNamingContext\n"));
2505 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2508 DEBUG(10, ("defaultNamingContext = %s\n", state
->domaindn
));
2510 state
->configdn
= tldap_talloc_single_attribute(
2511 rootdse
, "configurationNamingContext", state
);
2512 if (state
->configdn
== NULL
) {
2513 DEBUG(10, ("Could not get configurationNamingContext\n"));
2514 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2517 DEBUG(10, ("configurationNamingContext = %s\n", state
->configdn
));
2520 * Figure out our domain's SID
2522 rc
= pdb_ads_search_fmt(
2523 state
, state
->domaindn
, TLDAP_SCOPE_BASE
,
2524 domain_attrs
, ARRAY_SIZE(domain_attrs
), 0,
2525 talloc_tos(), &domain
, "(objectclass=*)");
2526 if (rc
!= TLDAP_SUCCESS
) {
2527 DEBUG(10, ("Could not retrieve domain: %s\n",
2528 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2529 status
= NT_STATUS_LDAP(rc
);
2533 num_domains
= talloc_array_length(domain
);
2534 if (num_domains
!= 1) {
2535 DEBUG(10, ("Got %d domains, expected one\n", num_domains
));
2536 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2539 if (!tldap_pull_binsid(domain
[0], "objectSid", &state
->domainsid
)) {
2540 DEBUG(10, ("Could not retrieve domain SID\n"));
2541 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2544 if (!tldap_pull_guid(domain
[0], "objectGUID", &state
->domainguid
)) {
2545 DEBUG(10, ("Could not retrieve domain GUID\n"));
2546 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2549 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state
->domainsid
)));
2552 * Figure out our domain's short name
2554 rc
= pdb_ads_search_fmt(
2555 state
, state
->configdn
, TLDAP_SCOPE_SUB
,
2556 ncname_attrs
, ARRAY_SIZE(ncname_attrs
), 0,
2557 talloc_tos(), &ncname
, "(ncname=%s)", state
->domaindn
);
2558 if (rc
!= TLDAP_SUCCESS
) {
2559 DEBUG(10, ("Could not retrieve ncname: %s\n",
2560 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2561 status
= NT_STATUS_LDAP(rc
);
2564 if (talloc_array_length(ncname
) != 1) {
2565 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2569 state
->netbiosname
= tldap_talloc_single_attribute(
2570 ncname
[0], "netbiosname", state
);
2571 if (state
->netbiosname
== NULL
) {
2572 DEBUG(10, ("Could not get netbiosname\n"));
2573 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2576 DEBUG(10, ("netbiosname: %s\n", state
->netbiosname
));
2578 if (!strequal(lp_workgroup(), state
->netbiosname
)) {
2579 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2580 state
->netbiosname
, lp_workgroup()));
2581 status
= NT_STATUS_NO_SUCH_DOMAIN
;
2585 secrets_store_domain_sid(state
->netbiosname
, &state
->domainsid
);
2587 status
= NT_STATUS_OK
;
2593 static NTSTATUS
pdb_init_ads(struct pdb_methods
**pdb_method
,
2594 const char *location
)
2596 struct pdb_methods
*m
;
2597 struct pdb_ads_state
*state
;
2601 m
= talloc(NULL
, struct pdb_methods
);
2603 return NT_STATUS_NO_MEMORY
;
2605 state
= talloc_zero(m
, struct pdb_ads_state
);
2606 if (state
== NULL
) {
2609 m
->private_data
= state
;
2610 m
->free_private_data
= free_private_data
;
2611 pdb_ads_init_methods(m
);
2613 if (location
== NULL
) {
2614 tmp
= talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2618 if (location
== NULL
) {
2622 status
= pdb_ads_connect(state
, location
);
2623 if (!NT_STATUS_IS_OK(status
)) {
2624 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status
)));
2629 return NT_STATUS_OK
;
2631 status
= NT_STATUS_NO_MEMORY
;
2637 NTSTATUS
pdb_ads_init(void);
2638 NTSTATUS
pdb_ads_init(void)
2640 return smb_register_passdb(PASSDB_INTERFACE_VERSION
, "ads",