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 "../librpc/gen_ndr/idmap.h"
28 #include "../libcli/ldap/ldap_ndr.h"
29 #include "../libcli/security/security.h"
30 #include "../libds/common/flag_mapping.h"
32 struct pdb_ads_state
{
33 struct sockaddr_un socket_address
;
34 struct tldap_context
*ld
;
35 struct dom_sid domainsid
;
36 struct GUID domainguid
;
42 struct pdb_ads_samu_private
{
44 struct tldap_message
*ldapmsg
;
47 static bool pdb_ads_gid_to_sid(struct pdb_methods
*m
, gid_t gid
,
49 static bool pdb_ads_dnblob2sid(struct pdb_ads_state
*state
, DATA_BLOB
*dnblob
,
50 struct dom_sid
*psid
);
51 static NTSTATUS
pdb_ads_sid2dn(struct pdb_ads_state
*state
,
52 const struct dom_sid
*sid
,
53 TALLOC_CTX
*mem_ctx
, char **pdn
);
54 static struct tldap_context
*pdb_ads_ld(struct pdb_ads_state
*state
);
55 static int pdb_ads_search_fmt(struct pdb_ads_state
*state
, const char *base
,
56 int scope
, const char *attrs
[], int num_attrs
,
58 TALLOC_CTX
*mem_ctx
, struct tldap_message
***res
,
59 const char *fmt
, ...);
60 static NTSTATUS
pdb_ads_getsamupriv(struct pdb_ads_state
*state
,
63 struct pdb_ads_samu_private
**presult
);
65 static bool pdb_ads_pull_time(struct tldap_message
*msg
, const char *attr
,
70 if (!tldap_pull_uint64(msg
, attr
, &tmp
)) {
73 *ptime
= nt_time_to_unix(tmp
);
77 static gid_t
pdb_ads_sid2gid(const struct dom_sid
*sid
)
80 sid_peek_rid(sid
, &rid
);
84 static char *pdb_ads_domaindn2dns(TALLOC_CTX
*mem_ctx
, char *dn
)
88 result
= talloc_string_sub2(mem_ctx
, dn
, "DC=", "", false, false,
94 while ((p
= strchr_m(result
, ',')) != NULL
) {
101 static struct pdb_domain_info
*pdb_ads_get_domain_info(
102 struct pdb_methods
*m
, TALLOC_CTX
*mem_ctx
)
104 struct pdb_ads_state
*state
= talloc_get_type_abort(
105 m
->private_data
, struct pdb_ads_state
);
106 struct pdb_domain_info
*info
;
107 struct tldap_message
*rootdse
;
110 info
= talloc(mem_ctx
, struct pdb_domain_info
);
114 info
->name
= talloc_strdup(info
, state
->netbiosname
);
115 if (info
->name
== NULL
) {
118 info
->dns_domain
= pdb_ads_domaindn2dns(info
, state
->domaindn
);
119 if (info
->dns_domain
== NULL
) {
123 rootdse
= tldap_rootdse(state
->ld
);
124 tmp
= tldap_talloc_single_attribute(rootdse
, "rootDomainNamingContext",
129 info
->dns_forest
= pdb_ads_domaindn2dns(info
, tmp
);
131 if (info
->dns_forest
== NULL
) {
134 info
->sid
= state
->domainsid
;
135 info
->guid
= state
->domainguid
;
143 static struct pdb_ads_samu_private
*pdb_ads_get_samu_private(
144 struct pdb_methods
*m
, struct samu
*sam
)
146 struct pdb_ads_state
*state
= talloc_get_type_abort(
147 m
->private_data
, struct pdb_ads_state
);
148 struct pdb_ads_samu_private
*result
;
149 char *sidstr
, *filter
;
152 result
= (struct pdb_ads_samu_private
*)
153 pdb_get_backend_private_data(sam
, m
);
155 if (result
!= NULL
) {
156 return talloc_get_type_abort(
157 result
, struct pdb_ads_samu_private
);
160 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), pdb_get_user_sid(sam
));
161 if (sidstr
== NULL
) {
165 filter
= talloc_asprintf(
166 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr
);
168 if (filter
== NULL
) {
172 status
= pdb_ads_getsamupriv(state
, filter
, sam
, &result
);
174 if (!NT_STATUS_IS_OK(status
)) {
181 static NTSTATUS
pdb_ads_init_sam_from_priv(struct pdb_methods
*m
,
183 struct pdb_ads_samu_private
*priv
)
185 struct pdb_ads_state
*state
= talloc_get_type_abort(
186 m
->private_data
, struct pdb_ads_state
);
187 TALLOC_CTX
*frame
= talloc_stackframe();
188 NTSTATUS status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
189 struct tldap_message
*entry
= priv
->ldapmsg
;
197 str
= tldap_talloc_single_attribute(entry
, "samAccountName", sam
);
199 DEBUG(10, ("no samAccountName\n"));
202 pdb_set_username(sam
, str
, PDB_SET
);
204 if (pdb_ads_pull_time(entry
, "lastLogon", &tmp_time
)) {
205 pdb_set_logon_time(sam
, tmp_time
, PDB_SET
);
207 if (pdb_ads_pull_time(entry
, "lastLogoff", &tmp_time
)) {
208 pdb_set_logoff_time(sam
, tmp_time
, PDB_SET
);
210 if (pdb_ads_pull_time(entry
, "pwdLastSet", &tmp_time
)) {
211 pdb_set_pass_last_set_time(sam
, tmp_time
, PDB_SET
);
213 if (pdb_ads_pull_time(entry
, "accountExpires", &tmp_time
)) {
214 pdb_set_kickoff_time(sam
, tmp_time
, PDB_SET
);
217 str
= tldap_talloc_single_attribute(entry
, "displayName",
220 pdb_set_fullname(sam
, str
, PDB_SET
);
223 str
= tldap_talloc_single_attribute(entry
, "homeDirectory",
226 pdb_set_homedir(sam
, str
, PDB_SET
);
229 str
= tldap_talloc_single_attribute(entry
, "homeDrive", talloc_tos());
231 pdb_set_dir_drive(sam
, str
, PDB_SET
);
234 str
= tldap_talloc_single_attribute(entry
, "scriptPath", talloc_tos());
236 pdb_set_logon_script(sam
, str
, PDB_SET
);
239 str
= tldap_talloc_single_attribute(entry
, "profilePath",
242 pdb_set_profile_path(sam
, str
, PDB_SET
);
245 str
= tldap_talloc_single_attribute(entry
, "profilePath",
248 pdb_set_profile_path(sam
, str
, PDB_SET
);
251 str
= tldap_talloc_single_attribute(entry
, "comment",
254 pdb_set_comment(sam
, str
, PDB_SET
);
257 str
= tldap_talloc_single_attribute(entry
, "description",
260 pdb_set_acct_desc(sam
, str
, PDB_SET
);
263 str
= tldap_talloc_single_attribute(entry
, "userWorkstations",
266 pdb_set_workstations(sam
, str
, PDB_SET
);
269 str
= tldap_talloc_single_attribute(entry
, "userParameters",
272 pdb_set_munged_dial(sam
, str
, PDB_SET
);
275 if (!tldap_pull_binsid(entry
, "objectSid", &sid
)) {
276 DEBUG(10, ("Could not pull SID\n"));
279 pdb_set_user_sid(sam
, &sid
, PDB_SET
);
281 if (!tldap_pull_uint64(entry
, "userAccountControl", &n
)) {
282 DEBUG(10, ("Could not pull userAccountControl\n"));
285 pdb_set_acct_ctrl(sam
, ds_uf2acb(n
), PDB_SET
);
287 if (tldap_get_single_valueblob(entry
, "unicodePwd", &blob
)) {
288 if (blob
.length
!= NT_HASH_LEN
) {
289 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
290 (int)blob
.length
, NT_HASH_LEN
));
293 pdb_set_nt_passwd(sam
, blob
.data
, PDB_SET
);
296 if (tldap_get_single_valueblob(entry
, "dBCSPwd", &blob
)) {
297 if (blob
.length
!= LM_HASH_LEN
) {
298 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
299 (int)blob
.length
, LM_HASH_LEN
));
302 pdb_set_lanman_passwd(sam
, blob
.data
, PDB_SET
);
305 if (tldap_pull_uint64(entry
, "primaryGroupID", &n
)) {
306 sid_compose(&sid
, &state
->domainsid
, n
);
307 pdb_set_group_sid(sam
, &sid
, PDB_SET
);
311 if (tldap_pull_uint32(entry
, "countryCode", &i
)) {
312 pdb_set_country_code(sam
, i
, PDB_SET
);
315 if (tldap_pull_uint32(entry
, "codePage", &i
)) {
316 pdb_set_code_page(sam
, i
, PDB_SET
);
319 if (tldap_get_single_valueblob(entry
, "logonHours", &blob
)) {
321 if (blob
.length
> MAX_HOURS_LEN
) {
322 status
= NT_STATUS_INVALID_PARAMETER
;
325 pdb_set_logon_divs(sam
, blob
.length
* 8, PDB_SET
);
326 pdb_set_hours_len(sam
, blob
.length
, PDB_SET
);
327 pdb_set_hours(sam
, blob
.data
, blob
.length
, PDB_SET
);
331 pdb_set_logon_divs(sam
, sizeof(hours
)/8, PDB_SET
);
332 pdb_set_hours_len(sam
, sizeof(hours
), PDB_SET
);
333 memset(hours
, 0xff, sizeof(hours
));
334 pdb_set_hours(sam
, hours
, sizeof(hours
), PDB_SET
);
337 status
= NT_STATUS_OK
;
343 static bool pdb_ads_make_time_mod(struct tldap_message
*existing
,
345 struct tldap_mod
**pmods
, int *pnum_mods
,
346 const char *attrib
, time_t t
)
350 unix_to_nt_time(&nt_time
, t
);
352 return tldap_make_mod_fmt(
353 existing
, mem_ctx
, pmods
, pnum_mods
, attrib
,
357 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state
*state
,
358 struct tldap_message
*existing
,
360 struct tldap_mod
**pmods
, int *pnum_mods
,
367 /* TODO: All fields :-) */
369 ret
&= tldap_make_mod_fmt(
370 existing
, mem_ctx
, pmods
, pnum_mods
, "displayName",
371 "%s", pdb_get_fullname(sam
));
373 pw
= pdb_get_plaintext_passwd(sam
);
376 * If we have the plain text pw, this is probably about to be
377 * set. Is this true always?
384 pw_quote
= talloc_asprintf(talloc_tos(), "\"%s\"", pw
);
385 if (pw_quote
== NULL
) {
390 ret
&= convert_string_talloc(talloc_tos(),
392 pw_quote
, strlen(pw_quote
),
393 &pw_utf16
, &pw_utf16_len
);
397 blob
= data_blob_const(pw_utf16
, pw_utf16_len
);
399 ret
&= tldap_add_mod_blobs(mem_ctx
, pmods
, pnum_mods
,
401 "unicodePwd", &blob
, 1);
402 TALLOC_FREE(pw_utf16
);
403 TALLOC_FREE(pw_quote
);
406 ret
&= tldap_make_mod_fmt(
407 existing
, mem_ctx
, pmods
, pnum_mods
, "userAccountControl",
408 "%d", ds_acb2uf(pdb_get_acct_ctrl(sam
)));
410 ret
&= tldap_make_mod_fmt(
411 existing
, mem_ctx
, pmods
, pnum_mods
, "homeDirectory",
412 "%s", pdb_get_homedir(sam
));
414 ret
&= tldap_make_mod_fmt(
415 existing
, mem_ctx
, pmods
, pnum_mods
, "homeDrive",
416 "%s", pdb_get_dir_drive(sam
));
418 ret
&= tldap_make_mod_fmt(
419 existing
, mem_ctx
, pmods
, pnum_mods
, "scriptPath",
420 "%s", pdb_get_logon_script(sam
));
422 ret
&= tldap_make_mod_fmt(
423 existing
, mem_ctx
, pmods
, pnum_mods
, "profilePath",
424 "%s", pdb_get_profile_path(sam
));
426 ret
&= tldap_make_mod_fmt(
427 existing
, mem_ctx
, pmods
, pnum_mods
, "comment",
428 "%s", pdb_get_comment(sam
));
430 ret
&= tldap_make_mod_fmt(
431 existing
, mem_ctx
, pmods
, pnum_mods
, "description",
432 "%s", pdb_get_acct_desc(sam
));
434 ret
&= tldap_make_mod_fmt(
435 existing
, mem_ctx
, pmods
, pnum_mods
, "userWorkstations",
436 "%s", pdb_get_workstations(sam
));
438 ret
&= tldap_make_mod_fmt(
439 existing
, mem_ctx
, pmods
, pnum_mods
, "userParameters",
440 "%s", pdb_get_munged_dial(sam
));
442 ret
&= tldap_make_mod_fmt(
443 existing
, mem_ctx
, pmods
, pnum_mods
, "countryCode",
444 "%i", (int)pdb_get_country_code(sam
));
446 ret
&= tldap_make_mod_fmt(
447 existing
, mem_ctx
, pmods
, pnum_mods
, "codePage",
448 "%i", (int)pdb_get_code_page(sam
));
450 ret
&= pdb_ads_make_time_mod(
451 existing
, mem_ctx
, pmods
, pnum_mods
, "accountExpires",
452 (int)pdb_get_kickoff_time(sam
));
454 ret
&= tldap_make_mod_blob(
455 existing
, mem_ctx
, pmods
, pnum_mods
, "logonHours",
456 data_blob_const(pdb_get_hours(sam
), pdb_get_hours_len(sam
)));
462 static NTSTATUS
pdb_ads_getsamupriv(struct pdb_ads_state
*state
,
465 struct pdb_ads_samu_private
**presult
)
467 const char * attrs
[] = {
468 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
469 "sAMAccountName", "displayName", "homeDirectory",
470 "homeDrive", "scriptPath", "profilePath", "description",
471 "userWorkstations", "comment", "userParameters", "objectSid",
472 "primaryGroupID", "userAccountControl", "logonHours",
473 "badPwdCount", "logonCount", "countryCode", "codePage",
474 "unicodePwd", "dBCSPwd" };
475 struct tldap_message
**users
;
477 struct pdb_ads_samu_private
*result
;
479 result
= talloc(mem_ctx
, struct pdb_ads_samu_private
);
480 if (result
== NULL
) {
481 return NT_STATUS_NO_MEMORY
;
484 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
485 attrs
, ARRAY_SIZE(attrs
), 0, result
,
486 &users
, "%s", filter
);
487 if (rc
!= TLDAP_SUCCESS
) {
488 DEBUG(10, ("ldap_search failed %s\n",
489 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
491 return NT_STATUS_LDAP(rc
);
494 count
= talloc_array_length(users
);
496 DEBUG(10, ("Expected 1 user, got %d\n", count
));
498 return NT_STATUS_NO_SUCH_USER
;
501 result
->ldapmsg
= users
[0];
502 if (!tldap_entry_dn(result
->ldapmsg
, &result
->dn
)) {
503 DEBUG(10, ("Could not extract dn\n"));
505 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
512 static NTSTATUS
pdb_ads_getsampwfilter(struct pdb_methods
*m
,
513 struct pdb_ads_state
*state
,
514 struct samu
*sam_acct
,
517 struct pdb_ads_samu_private
*priv
;
520 status
= pdb_ads_getsamupriv(state
, filter
, sam_acct
, &priv
);
521 if (!NT_STATUS_IS_OK(status
)) {
522 DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n",
527 status
= pdb_ads_init_sam_from_priv(m
, sam_acct
, priv
);
528 if (!NT_STATUS_IS_OK(status
)) {
529 DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n",
535 pdb_set_backend_private_data(sam_acct
, priv
, NULL
, m
, PDB_SET
);
539 static NTSTATUS
pdb_ads_getsampwnam(struct pdb_methods
*m
,
540 struct samu
*sam_acct
,
541 const char *username
)
543 struct pdb_ads_state
*state
= talloc_get_type_abort(
544 m
->private_data
, struct pdb_ads_state
);
547 filter
= talloc_asprintf(
548 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
550 NT_STATUS_HAVE_NO_MEMORY(filter
);
552 return pdb_ads_getsampwfilter(m
, state
, sam_acct
, filter
);
555 static NTSTATUS
pdb_ads_getsampwsid(struct pdb_methods
*m
,
556 struct samu
*sam_acct
,
557 const struct dom_sid
*sid
)
559 struct pdb_ads_state
*state
= talloc_get_type_abort(
560 m
->private_data
, struct pdb_ads_state
);
561 char *sidstr
, *filter
;
563 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), sid
);
564 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
566 filter
= talloc_asprintf(
567 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr
);
569 NT_STATUS_HAVE_NO_MEMORY(filter
);
571 return pdb_ads_getsampwfilter(m
, state
, sam_acct
, filter
);
574 static NTSTATUS
pdb_ads_create_user(struct pdb_methods
*m
,
576 const char *name
, uint32 acct_flags
,
579 struct pdb_ads_state
*state
= talloc_get_type_abort(
580 m
->private_data
, struct pdb_ads_state
);
581 struct tldap_context
*ld
;
582 const char *attrs
[1] = { "objectSid" };
583 struct tldap_mod
*mods
= NULL
;
585 struct tldap_message
**user
;
591 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
594 return NT_STATUS_NO_MEMORY
;
597 ld
= pdb_ads_ld(state
);
599 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
602 /* TODO: Create machines etc */
605 ok
&= tldap_make_mod_fmt(
606 NULL
, talloc_tos(), &mods
, &num_mods
, "objectClass", "user");
607 ok
&= tldap_make_mod_fmt(
608 NULL
, talloc_tos(), &mods
, &num_mods
, "samAccountName", "%s",
611 return NT_STATUS_NO_MEMORY
;
615 rc
= tldap_add(ld
, dn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
616 if (rc
!= TLDAP_SUCCESS
) {
617 DEBUG(10, ("ldap_add failed %s\n",
618 tldap_errstr(talloc_tos(), ld
, rc
)));
620 return NT_STATUS_LDAP(rc
);
623 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
624 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
626 "(&(objectclass=user)(samaccountname=%s))",
628 if (rc
!= TLDAP_SUCCESS
) {
629 DEBUG(10, ("Could not find just created user %s: %s\n",
630 name
, tldap_errstr(talloc_tos(), state
->ld
, rc
)));
632 return NT_STATUS_LDAP(rc
);
635 if (talloc_array_length(user
) != 1) {
636 DEBUG(10, ("Got %d users, expected one\n",
637 (int)talloc_array_length(user
)));
639 return NT_STATUS_LDAP(rc
);
642 if (!tldap_pull_binsid(user
[0], "objectSid", &sid
)) {
643 DEBUG(10, ("Could not fetch objectSid from user %s\n",
646 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
649 sid_peek_rid(&sid
, rid
);
654 static NTSTATUS
pdb_ads_delete_user(struct pdb_methods
*m
,
658 struct pdb_ads_state
*state
= talloc_get_type_abort(
659 m
->private_data
, struct pdb_ads_state
);
661 struct tldap_context
*ld
;
665 ld
= pdb_ads_ld(state
);
667 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
670 status
= pdb_ads_sid2dn(state
, pdb_get_user_sid(sam
), talloc_tos(),
672 if (!NT_STATUS_IS_OK(status
)) {
676 rc
= tldap_delete(ld
, dn
, NULL
, 0, NULL
, 0);
678 if (rc
!= TLDAP_SUCCESS
) {
679 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn
,
680 tldap_errstr(talloc_tos(), ld
, rc
)));
681 return NT_STATUS_LDAP(rc
);
686 static NTSTATUS
pdb_ads_add_sam_account(struct pdb_methods
*m
,
687 struct samu
*sampass
)
689 return NT_STATUS_NOT_IMPLEMENTED
;
692 static NTSTATUS
pdb_ads_update_sam_account(struct pdb_methods
*m
,
695 struct pdb_ads_state
*state
= talloc_get_type_abort(
696 m
->private_data
, struct pdb_ads_state
);
697 struct pdb_ads_samu_private
*priv
= pdb_ads_get_samu_private(m
, sam
);
698 struct tldap_context
*ld
;
699 struct tldap_mod
*mods
= NULL
;
700 int rc
, num_mods
= 0;
702 ld
= pdb_ads_ld(state
);
704 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
707 if (!pdb_ads_init_ads_from_sam(state
, priv
->ldapmsg
, talloc_tos(),
708 &mods
, &num_mods
, sam
)) {
709 return NT_STATUS_NO_MEMORY
;
713 /* Nothing to do, just return success */
717 rc
= tldap_modify(ld
, priv
->dn
, mods
, num_mods
, NULL
, 0,
720 if (rc
!= TLDAP_SUCCESS
) {
721 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv
->dn
,
722 tldap_errstr(talloc_tos(), ld
, rc
)));
723 return NT_STATUS_LDAP(rc
);
729 static NTSTATUS
pdb_ads_delete_sam_account(struct pdb_methods
*m
,
730 struct samu
*username
)
732 return NT_STATUS_NOT_IMPLEMENTED
;
735 static NTSTATUS
pdb_ads_rename_sam_account(struct pdb_methods
*m
,
736 struct samu
*oldname
,
739 return NT_STATUS_NOT_IMPLEMENTED
;
742 static NTSTATUS
pdb_ads_update_login_attempts(struct pdb_methods
*m
,
743 struct samu
*sam_acct
,
746 return NT_STATUS_NOT_IMPLEMENTED
;
749 static NTSTATUS
pdb_ads_getgrfilter(struct pdb_methods
*m
, GROUP_MAP
*map
,
752 struct tldap_message
**pmsg
)
754 struct pdb_ads_state
*state
= talloc_get_type_abort(
755 m
->private_data
, struct pdb_ads_state
);
756 const char *attrs
[4] = { "objectSid", "description", "samAccountName",
759 struct tldap_message
**group
;
763 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
764 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
765 &group
, "%s", filter
);
766 if (rc
!= TLDAP_SUCCESS
) {
767 DEBUG(10, ("ldap_search failed %s\n",
768 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
769 return NT_STATUS_LDAP(rc
);
771 if (talloc_array_length(group
) != 1) {
772 DEBUG(10, ("Expected 1 group, got %d\n",
773 (int)talloc_array_length(group
)));
774 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
777 if (!tldap_pull_binsid(group
[0], "objectSid", &map
->sid
)) {
778 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
780 map
->gid
= pdb_ads_sid2gid(&map
->sid
);
782 if (!tldap_pull_uint32(group
[0], "groupType", &grouptype
)) {
783 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
786 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
:
787 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
:
788 map
->sid_name_use
= SID_NAME_ALIAS
;
790 case GTYPE_SECURITY_GLOBAL_GROUP
:
791 map
->sid_name_use
= SID_NAME_DOM_GRP
;
794 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
797 str
= tldap_talloc_single_attribute(group
[0], "samAccountName",
800 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
802 map
->nt_name
= talloc_move(map
, &str
);
804 str
= tldap_talloc_single_attribute(group
[0], "description",
807 map
->comment
= talloc_move(map
, &str
);
809 map
->comment
= talloc_strdup(map
, "");
813 *pmsg
= talloc_move(mem_ctx
, &group
[0]);
819 static NTSTATUS
pdb_ads_getgrsid(struct pdb_methods
*m
, GROUP_MAP
*map
,
825 filter
= talloc_asprintf(talloc_tos(),
826 "(&(objectsid=%s)(objectclass=group))",
827 sid_string_talloc(talloc_tos(), &sid
));
828 if (filter
== NULL
) {
829 return NT_STATUS_NO_MEMORY
;
832 status
= pdb_ads_getgrfilter(m
, map
, filter
, NULL
, NULL
);
837 static NTSTATUS
pdb_ads_getgrgid(struct pdb_methods
*m
, GROUP_MAP
*map
,
841 pdb_ads_gid_to_sid(m
, gid
, &sid
);
842 return pdb_ads_getgrsid(m
, map
, sid
);
845 static NTSTATUS
pdb_ads_getgrnam(struct pdb_methods
*m
, GROUP_MAP
*map
,
851 filter
= talloc_asprintf(talloc_tos(),
852 "(&(samaccountname=%s)(objectclass=group))",
854 if (filter
== NULL
) {
855 return NT_STATUS_NO_MEMORY
;
858 status
= pdb_ads_getgrfilter(m
, map
, filter
, NULL
, NULL
);
863 static NTSTATUS
pdb_ads_create_dom_group(struct pdb_methods
*m
,
864 TALLOC_CTX
*mem_ctx
, const char *name
,
867 TALLOC_CTX
*frame
= talloc_stackframe();
868 struct pdb_ads_state
*state
= talloc_get_type_abort(
869 m
->private_data
, struct pdb_ads_state
);
870 struct tldap_context
*ld
;
871 const char *attrs
[1] = { "objectSid" };
873 struct tldap_mod
*mods
= NULL
;
874 struct tldap_message
**alias
;
880 ld
= pdb_ads_ld(state
);
882 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
885 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
889 return NT_STATUS_NO_MEMORY
;
892 ok
&= tldap_make_mod_fmt(
893 NULL
, talloc_tos(), &mods
, &num_mods
, "samAccountName", "%s",
895 ok
&= tldap_make_mod_fmt(
896 NULL
, talloc_tos(), &mods
, &num_mods
, "objectClass", "group");
897 ok
&= tldap_make_mod_fmt(
898 NULL
, talloc_tos(), &mods
, &num_mods
, "groupType",
899 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP
);
903 return NT_STATUS_NO_MEMORY
;
906 rc
= tldap_add(ld
, dn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
907 if (rc
!= TLDAP_SUCCESS
) {
908 DEBUG(10, ("ldap_add failed %s\n",
909 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
911 return NT_STATUS_LDAP(rc
);
914 rc
= pdb_ads_search_fmt(
915 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
916 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &alias
,
917 "(&(objectclass=group)(samaccountname=%s))", name
);
918 if (rc
!= TLDAP_SUCCESS
) {
919 DEBUG(10, ("Could not find just created alias %s: %s\n",
920 name
, tldap_errstr(talloc_tos(), state
->ld
, rc
)));
922 return NT_STATUS_LDAP(rc
);
925 if (talloc_array_length(alias
) != 1) {
926 DEBUG(10, ("Got %d alias, expected one\n",
927 (int)talloc_array_length(alias
)));
929 return NT_STATUS_LDAP(rc
);
932 if (!tldap_pull_binsid(alias
[0], "objectSid", &sid
)) {
933 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
936 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
939 sid_peek_rid(&sid
, rid
);
944 static NTSTATUS
pdb_ads_delete_dom_group(struct pdb_methods
*m
,
945 TALLOC_CTX
*mem_ctx
, uint32 rid
)
947 struct pdb_ads_state
*state
= talloc_get_type_abort(
948 m
->private_data
, struct pdb_ads_state
);
949 struct tldap_context
*ld
;
952 struct tldap_message
**msg
;
956 sid_compose(&sid
, &state
->domainsid
, rid
);
958 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), &sid
);
959 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
961 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
962 NULL
, 0, 0, talloc_tos(), &msg
,
963 ("(&(objectSid=%s)(objectClass=group))"),
966 if (rc
!= TLDAP_SUCCESS
) {
967 DEBUG(10, ("ldap_search failed %s\n",
968 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
969 return NT_STATUS_LDAP(rc
);
972 switch talloc_array_length(msg
) {
974 return NT_STATUS_NO_SUCH_GROUP
;
978 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
981 if (!tldap_entry_dn(msg
[0], &dn
)) {
983 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
986 ld
= pdb_ads_ld(state
);
989 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
992 rc
= tldap_delete(ld
, dn
, NULL
, 0, NULL
, 0);
994 if (rc
!= TLDAP_SUCCESS
) {
995 DEBUG(10, ("ldap_delete failed: %s\n",
996 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
997 return NT_STATUS_LDAP(rc
);
1000 return NT_STATUS_OK
;
1003 static NTSTATUS
pdb_ads_add_group_mapping_entry(struct pdb_methods
*m
,
1006 return NT_STATUS_NOT_IMPLEMENTED
;
1009 static NTSTATUS
pdb_ads_update_group_mapping_entry(struct pdb_methods
*m
,
1012 struct pdb_ads_state
*state
= talloc_get_type_abort(
1013 m
->private_data
, struct pdb_ads_state
);
1014 struct tldap_context
*ld
;
1015 struct tldap_mod
*mods
= NULL
;
1017 struct tldap_message
*existing
;
1019 GROUP_MAP
*existing_map
;
1020 int rc
, num_mods
= 0;
1024 ld
= pdb_ads_ld(state
);
1026 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1029 filter
= talloc_asprintf(talloc_tos(),
1030 "(&(objectsid=%s)(objectclass=group))",
1031 sid_string_talloc(talloc_tos(), &map
->sid
));
1032 if (filter
== NULL
) {
1033 return NT_STATUS_NO_MEMORY
;
1036 existing_map
= talloc_zero(talloc_tos(), GROUP_MAP
);
1037 if (!existing_map
) {
1038 return NT_STATUS_NO_MEMORY
;
1041 status
= pdb_ads_getgrfilter(m
, existing_map
, filter
,
1042 talloc_tos(), &existing
);
1043 TALLOC_FREE(existing_map
);
1044 TALLOC_FREE(filter
);
1046 if (!tldap_entry_dn(existing
, &dn
)) {
1047 return NT_STATUS_LDAP(TLDAP_DECODING_ERROR
);
1052 ret
&= tldap_make_mod_fmt(
1053 existing
, talloc_tos(), &mods
, &num_mods
, "description",
1054 "%s", map
->comment
);
1055 ret
&= tldap_make_mod_fmt(
1056 existing
, talloc_tos(), &mods
, &num_mods
, "samaccountname",
1057 "%s", map
->nt_name
);
1060 return NT_STATUS_NO_MEMORY
;
1063 if (num_mods
== 0) {
1064 TALLOC_FREE(existing
);
1065 return NT_STATUS_OK
;
1068 rc
= tldap_modify(ld
, dn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
1069 if (rc
!= TLDAP_SUCCESS
) {
1070 DEBUG(10, ("ldap_modify for %s failed: %s\n", dn
,
1071 tldap_errstr(talloc_tos(), ld
, rc
)));
1072 TALLOC_FREE(existing
);
1073 return NT_STATUS_LDAP(rc
);
1075 TALLOC_FREE(existing
);
1076 return NT_STATUS_OK
;
1079 static NTSTATUS
pdb_ads_delete_group_mapping_entry(struct pdb_methods
*m
,
1082 return NT_STATUS_NOT_IMPLEMENTED
;
1085 static NTSTATUS
pdb_ads_enum_group_mapping(struct pdb_methods
*m
,
1086 const struct dom_sid
*sid
,
1087 enum lsa_SidType sid_name_use
,
1088 GROUP_MAP
***pp_rmap
,
1089 size_t *p_num_entries
,
1092 return NT_STATUS_NOT_IMPLEMENTED
;
1095 static NTSTATUS
pdb_ads_enum_group_members(struct pdb_methods
*m
,
1096 TALLOC_CTX
*mem_ctx
,
1097 const struct dom_sid
*group
,
1099 size_t *pnum_members
)
1101 struct pdb_ads_state
*state
= talloc_get_type_abort(
1102 m
->private_data
, struct pdb_ads_state
);
1103 const char *attrs
[1] = { "member" };
1105 struct tldap_message
**msg
;
1106 int i
, rc
, num_members
;
1110 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), group
);
1111 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1113 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1114 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1115 &msg
, "(objectsid=%s)", sidstr
);
1116 TALLOC_FREE(sidstr
);
1117 if (rc
!= TLDAP_SUCCESS
) {
1118 DEBUG(10, ("ldap_search failed %s\n",
1119 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1120 return NT_STATUS_LDAP(rc
);
1122 switch talloc_array_length(msg
) {
1124 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1129 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1133 if (!tldap_entry_values(msg
[0], "member", &blobs
, &num_members
)) {
1136 return NT_STATUS_OK
;
1139 members
= talloc_array(mem_ctx
, uint32_t, num_members
);
1140 if (members
== NULL
) {
1141 return NT_STATUS_NO_MEMORY
;
1144 for (i
=0; i
<num_members
; i
++) {
1146 if (!pdb_ads_dnblob2sid(state
, &blobs
[i
], &sid
)
1147 || !sid_peek_rid(&sid
, &members
[i
])) {
1148 TALLOC_FREE(members
);
1149 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1153 *pmembers
= members
;
1154 *pnum_members
= num_members
;
1155 return NT_STATUS_OK
;
1158 static NTSTATUS
pdb_ads_enum_group_memberships(struct pdb_methods
*m
,
1159 TALLOC_CTX
*mem_ctx
,
1161 struct dom_sid
**pp_sids
,
1163 uint32_t *p_num_groups
)
1165 struct pdb_ads_state
*state
= talloc_get_type_abort(
1166 m
->private_data
, struct pdb_ads_state
);
1167 struct pdb_ads_samu_private
*priv
;
1168 const char *attrs
[1] = { "objectSid" };
1169 struct tldap_message
**groups
;
1172 struct dom_sid
*group_sids
;
1175 priv
= pdb_ads_get_samu_private(m
, user
);
1177 rc
= pdb_ads_search_fmt(
1178 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1179 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &groups
,
1180 "(&(member=%s)(grouptype=%d)(objectclass=group))",
1181 priv
->dn
, GTYPE_SECURITY_GLOBAL_GROUP
);
1182 if (rc
!= TLDAP_SUCCESS
) {
1183 DEBUG(10, ("ldap_search failed %s\n",
1184 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1185 return NT_STATUS_LDAP(rc
);
1187 count
= talloc_array_length(groups
);
1190 * This happens for artificial samu users
1192 DEBUG(10, ("Could not get pdb_ads_samu_private\n"));
1196 group_sids
= talloc_array(mem_ctx
, struct dom_sid
, count
+1);
1197 if (group_sids
== NULL
) {
1198 return NT_STATUS_NO_MEMORY
;
1200 gids
= talloc_array(mem_ctx
, gid_t
, count
+1);
1202 TALLOC_FREE(group_sids
);
1203 return NT_STATUS_NO_MEMORY
;
1206 sid_copy(&group_sids
[0], pdb_get_group_sid(user
));
1207 if (!sid_to_gid(&group_sids
[0], &gids
[0])) {
1209 TALLOC_FREE(group_sids
);
1210 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1214 for (i
=0; i
<count
; i
++) {
1215 if (!tldap_pull_binsid(groups
[i
], "objectSid",
1216 &group_sids
[num_groups
])) {
1219 gids
[num_groups
] = pdb_ads_sid2gid(&group_sids
[num_groups
]);
1222 if (num_groups
== count
) {
1227 *pp_sids
= group_sids
;
1229 *p_num_groups
= num_groups
;
1230 return NT_STATUS_OK
;
1233 static NTSTATUS
pdb_ads_set_unix_primary_group(struct pdb_methods
*m
,
1234 TALLOC_CTX
*mem_ctx
,
1237 return NT_STATUS_NOT_IMPLEMENTED
;
1240 static NTSTATUS
pdb_ads_mod_groupmem(struct pdb_methods
*m
,
1241 TALLOC_CTX
*mem_ctx
,
1242 uint32 grouprid
, uint32 memberrid
,
1245 struct pdb_ads_state
*state
= talloc_get_type_abort(
1246 m
->private_data
, struct pdb_ads_state
);
1247 TALLOC_CTX
*frame
= talloc_stackframe();
1248 struct tldap_context
*ld
;
1249 struct dom_sid groupsid
, membersid
;
1250 char *groupdn
, *memberdn
;
1251 struct tldap_mod
*mods
;
1256 ld
= pdb_ads_ld(state
);
1258 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1261 sid_compose(&groupsid
, &state
->domainsid
, grouprid
);
1262 sid_compose(&membersid
, &state
->domainsid
, memberrid
);
1264 status
= pdb_ads_sid2dn(state
, &groupsid
, talloc_tos(), &groupdn
);
1265 if (!NT_STATUS_IS_OK(status
)) {
1267 return NT_STATUS_NO_SUCH_GROUP
;
1269 status
= pdb_ads_sid2dn(state
, &membersid
, talloc_tos(), &memberdn
);
1270 if (!NT_STATUS_IS_OK(status
)) {
1272 return NT_STATUS_NO_SUCH_USER
;
1278 if (!tldap_add_mod_str(talloc_tos(), &mods
, &num_mods
, mod_op
,
1279 "member", memberdn
)) {
1281 return NT_STATUS_NO_MEMORY
;
1284 rc
= tldap_modify(ld
, groupdn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
1286 if (rc
!= TLDAP_SUCCESS
) {
1287 DEBUG(10, ("ldap_modify failed: %s\n",
1288 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1289 if ((mod_op
== TLDAP_MOD_ADD
) &&
1290 (rc
== TLDAP_ALREADY_EXISTS
)) {
1291 return NT_STATUS_MEMBER_IN_GROUP
;
1293 if ((mod_op
== TLDAP_MOD_DELETE
) &&
1294 (rc
== TLDAP_UNWILLING_TO_PERFORM
)) {
1295 return NT_STATUS_MEMBER_NOT_IN_GROUP
;
1297 return NT_STATUS_LDAP(rc
);
1300 return NT_STATUS_OK
;
1303 static NTSTATUS
pdb_ads_add_groupmem(struct pdb_methods
*m
,
1304 TALLOC_CTX
*mem_ctx
,
1305 uint32 group_rid
, uint32 member_rid
)
1307 return pdb_ads_mod_groupmem(m
, mem_ctx
, group_rid
, member_rid
,
1311 static NTSTATUS
pdb_ads_del_groupmem(struct pdb_methods
*m
,
1312 TALLOC_CTX
*mem_ctx
,
1313 uint32 group_rid
, uint32 member_rid
)
1315 return pdb_ads_mod_groupmem(m
, mem_ctx
, group_rid
, member_rid
,
1319 static NTSTATUS
pdb_ads_create_alias(struct pdb_methods
*m
,
1320 const char *name
, uint32
*rid
)
1322 TALLOC_CTX
*frame
= talloc_stackframe();
1323 struct pdb_ads_state
*state
= talloc_get_type_abort(
1324 m
->private_data
, struct pdb_ads_state
);
1325 struct tldap_context
*ld
;
1326 const char *attrs
[1] = { "objectSid" };
1328 struct tldap_mod
*mods
= NULL
;
1329 struct tldap_message
**alias
;
1335 ld
= pdb_ads_ld(state
);
1337 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1340 dn
= talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name
,
1344 return NT_STATUS_NO_MEMORY
;
1347 ok
&= tldap_make_mod_fmt(
1348 NULL
, talloc_tos(), &mods
, &num_mods
, "samAccountName", "%s",
1350 ok
&= tldap_make_mod_fmt(
1351 NULL
, talloc_tos(), &mods
, &num_mods
, "objectClass", "group");
1352 ok
&= tldap_make_mod_fmt(
1353 NULL
, talloc_tos(), &mods
, &num_mods
, "groupType",
1354 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1358 return NT_STATUS_NO_MEMORY
;
1361 rc
= tldap_add(ld
, dn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
1362 if (rc
!= TLDAP_SUCCESS
) {
1363 DEBUG(10, ("ldap_add failed %s\n",
1364 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1366 return NT_STATUS_LDAP(rc
);
1369 rc
= pdb_ads_search_fmt(
1370 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1371 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &alias
,
1372 "(&(objectclass=group)(samaccountname=%s))", name
);
1373 if (rc
!= TLDAP_SUCCESS
) {
1374 DEBUG(10, ("Could not find just created alias %s: %s\n",
1375 name
, tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1377 return NT_STATUS_LDAP(rc
);
1380 if (talloc_array_length(alias
) != 1) {
1381 DEBUG(10, ("Got %d alias, expected one\n",
1382 (int)talloc_array_length(alias
)));
1384 return NT_STATUS_LDAP(rc
);
1387 if (!tldap_pull_binsid(alias
[0], "objectSid", &sid
)) {
1388 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1391 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1394 sid_peek_rid(&sid
, rid
);
1396 return NT_STATUS_OK
;
1399 static NTSTATUS
pdb_ads_delete_alias(struct pdb_methods
*m
,
1400 const struct dom_sid
*sid
)
1402 struct pdb_ads_state
*state
= talloc_get_type_abort(
1403 m
->private_data
, struct pdb_ads_state
);
1404 struct tldap_context
*ld
;
1405 struct tldap_message
**alias
;
1406 char *sidstr
, *dn
= NULL
;
1409 ld
= pdb_ads_ld(state
);
1411 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1414 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), sid
);
1415 if (sidstr
== NULL
) {
1416 return NT_STATUS_NO_MEMORY
;
1419 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1420 NULL
, 0, 0, talloc_tos(), &alias
,
1421 "(&(objectSid=%s)(objectclass=group)"
1422 "(|(grouptype=%d)(grouptype=%d)))",
1423 sidstr
, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1424 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1425 TALLOC_FREE(sidstr
);
1426 if (rc
!= TLDAP_SUCCESS
) {
1427 DEBUG(10, ("ldap_search failed: %s\n",
1428 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1429 return NT_STATUS_LDAP(rc
);
1431 if (talloc_array_length(alias
) != 1) {
1432 DEBUG(10, ("Expected 1 alias, got %d\n",
1433 (int)talloc_array_length(alias
)));
1434 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1436 if (!tldap_entry_dn(alias
[0], &dn
)) {
1437 DEBUG(10, ("Could not get DN for alias %s\n",
1438 sid_string_dbg(sid
)));
1439 return NT_STATUS_INTERNAL_ERROR
;
1442 rc
= tldap_delete(ld
, dn
, NULL
, 0, NULL
, 0);
1443 if (rc
!= TLDAP_SUCCESS
) {
1444 DEBUG(10, ("ldap_delete failed: %s\n",
1445 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1446 return NT_STATUS_LDAP(rc
);
1449 return NT_STATUS_OK
;
1452 static NTSTATUS
pdb_ads_set_aliasinfo(struct pdb_methods
*m
,
1453 const struct dom_sid
*sid
,
1454 struct acct_info
*info
)
1456 struct pdb_ads_state
*state
= talloc_get_type_abort(
1457 m
->private_data
, struct pdb_ads_state
);
1458 struct tldap_context
*ld
;
1459 const char *attrs
[3] = { "objectSid", "description",
1461 struct tldap_message
**msg
;
1464 struct tldap_mod
*mods
;
1468 ld
= pdb_ads_ld(state
);
1470 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1473 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), sid
);
1474 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1476 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1477 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1478 &msg
, "(&(objectSid=%s)(objectclass=group)"
1479 "(|(grouptype=%d)(grouptype=%d)))",
1480 sidstr
, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1481 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1482 TALLOC_FREE(sidstr
);
1483 if (rc
!= TLDAP_SUCCESS
) {
1484 DEBUG(10, ("ldap_search failed %s\n",
1485 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1486 return NT_STATUS_LDAP(rc
);
1488 switch talloc_array_length(msg
) {
1490 return NT_STATUS_NO_SUCH_ALIAS
;
1494 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1497 if (!tldap_entry_dn(msg
[0], &dn
)) {
1499 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1506 ok
&= tldap_make_mod_fmt(
1507 msg
[0], msg
, &mods
, &num_mods
, "description",
1508 "%s", info
->acct_desc
);
1509 ok
&= tldap_make_mod_fmt(
1510 msg
[0], msg
, &mods
, &num_mods
, "samAccountName",
1511 "%s", info
->acct_name
);
1514 return NT_STATUS_NO_MEMORY
;
1516 if (num_mods
== 0) {
1519 return NT_STATUS_OK
;
1522 rc
= tldap_modify(ld
, dn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
1524 if (rc
!= TLDAP_SUCCESS
) {
1525 DEBUG(10, ("ldap_modify failed: %s\n",
1526 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1527 return NT_STATUS_LDAP(rc
);
1529 return NT_STATUS_OK
;
1532 static NTSTATUS
pdb_ads_sid2dn(struct pdb_ads_state
*state
,
1533 const struct dom_sid
*sid
,
1534 TALLOC_CTX
*mem_ctx
, char **pdn
)
1536 struct tldap_message
**msg
;
1540 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), sid
);
1541 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1543 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1544 NULL
, 0, 0, talloc_tos(), &msg
,
1545 "(objectsid=%s)", sidstr
);
1546 TALLOC_FREE(sidstr
);
1547 if (rc
!= TLDAP_SUCCESS
) {
1548 DEBUG(10, ("ldap_search failed %s\n",
1549 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1550 return NT_STATUS_LDAP(rc
);
1553 switch talloc_array_length(msg
) {
1555 return NT_STATUS_NOT_FOUND
;
1559 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1562 if (!tldap_entry_dn(msg
[0], &dn
)) {
1563 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1566 dn
= talloc_strdup(mem_ctx
, dn
);
1568 return NT_STATUS_NO_MEMORY
;
1573 return NT_STATUS_OK
;
1576 static NTSTATUS
pdb_ads_mod_aliasmem(struct pdb_methods
*m
,
1577 const struct dom_sid
*alias
,
1578 const struct dom_sid
*member
,
1581 struct pdb_ads_state
*state
= talloc_get_type_abort(
1582 m
->private_data
, struct pdb_ads_state
);
1583 struct tldap_context
*ld
;
1584 TALLOC_CTX
*frame
= talloc_stackframe();
1585 struct tldap_mod
*mods
;
1588 char *aliasdn
, *memberdn
;
1591 ld
= pdb_ads_ld(state
);
1593 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN
);
1596 status
= pdb_ads_sid2dn(state
, alias
, talloc_tos(), &aliasdn
);
1597 if (!NT_STATUS_IS_OK(status
)) {
1598 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1599 sid_string_dbg(alias
), nt_errstr(status
)));
1601 return NT_STATUS_NO_SUCH_ALIAS
;
1603 status
= pdb_ads_sid2dn(state
, member
, talloc_tos(), &memberdn
);
1604 if (!NT_STATUS_IS_OK(status
)) {
1605 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1606 sid_string_dbg(member
), nt_errstr(status
)));
1614 if (!tldap_add_mod_str(talloc_tos(), &mods
, &num_mods
, mod_op
,
1615 "member", memberdn
)) {
1617 return NT_STATUS_NO_MEMORY
;
1620 rc
= tldap_modify(ld
, aliasdn
, mods
, num_mods
, NULL
, 0, NULL
, 0);
1622 if (rc
!= TLDAP_SUCCESS
) {
1623 DEBUG(10, ("ldap_modify failed: %s\n",
1624 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1625 if (rc
== TLDAP_TYPE_OR_VALUE_EXISTS
) {
1626 return NT_STATUS_MEMBER_IN_ALIAS
;
1628 if (rc
== TLDAP_NO_SUCH_ATTRIBUTE
) {
1629 return NT_STATUS_MEMBER_NOT_IN_ALIAS
;
1631 return NT_STATUS_LDAP(rc
);
1634 return NT_STATUS_OK
;
1637 static NTSTATUS
pdb_ads_add_aliasmem(struct pdb_methods
*m
,
1638 const struct dom_sid
*alias
,
1639 const struct dom_sid
*member
)
1641 return pdb_ads_mod_aliasmem(m
, alias
, member
, TLDAP_MOD_ADD
);
1644 static NTSTATUS
pdb_ads_del_aliasmem(struct pdb_methods
*m
,
1645 const struct dom_sid
*alias
,
1646 const struct dom_sid
*member
)
1648 return pdb_ads_mod_aliasmem(m
, alias
, member
, TLDAP_MOD_DELETE
);
1651 static bool pdb_ads_dnblob2sid(struct pdb_ads_state
*state
, DATA_BLOB
*dnblob
,
1652 struct dom_sid
*psid
)
1654 const char *attrs
[1] = { "objectSid" };
1655 struct tldap_message
**msg
;
1661 if (!convert_string_talloc(talloc_tos(), CH_UTF8
, CH_UNIX
,
1662 dnblob
->data
, dnblob
->length
, &dn
, &len
)) {
1665 rc
= pdb_ads_search_fmt(state
, dn
, TLDAP_SCOPE_BASE
,
1666 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1667 &msg
, "(objectclass=*)");
1669 if (talloc_array_length(msg
) != 1) {
1670 DEBUG(10, ("Got %d objects, expected one\n",
1671 (int)talloc_array_length(msg
)));
1676 ret
= tldap_pull_binsid(msg
[0], "objectSid", psid
);
1681 static NTSTATUS
pdb_ads_enum_aliasmem(struct pdb_methods
*m
,
1682 const struct dom_sid
*alias
,
1683 TALLOC_CTX
*mem_ctx
,
1684 struct dom_sid
**pmembers
,
1685 size_t *pnum_members
)
1687 struct pdb_ads_state
*state
= talloc_get_type_abort(
1688 m
->private_data
, struct pdb_ads_state
);
1689 const char *attrs
[1] = { "member" };
1691 struct tldap_message
**msg
;
1692 int i
, rc
, num_members
;
1694 struct dom_sid
*members
;
1696 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), alias
);
1697 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1699 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1700 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1701 &msg
, "(objectsid=%s)", sidstr
);
1702 TALLOC_FREE(sidstr
);
1703 if (rc
!= TLDAP_SUCCESS
) {
1704 DEBUG(10, ("ldap_search failed %s\n",
1705 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1706 return NT_STATUS_LDAP(rc
);
1708 switch talloc_array_length(msg
) {
1710 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1715 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1719 if (!tldap_entry_values(msg
[0], "member", &blobs
, &num_members
)) {
1722 return NT_STATUS_OK
;
1725 members
= talloc_array(mem_ctx
, struct dom_sid
, num_members
);
1726 if (members
== NULL
) {
1727 return NT_STATUS_NO_MEMORY
;
1730 for (i
=0; i
<num_members
; i
++) {
1731 if (!pdb_ads_dnblob2sid(state
, &blobs
[i
], &members
[i
])) {
1732 TALLOC_FREE(members
);
1733 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1737 *pmembers
= members
;
1738 *pnum_members
= num_members
;
1739 return NT_STATUS_OK
;
1742 static NTSTATUS
pdb_ads_enum_alias_memberships(struct pdb_methods
*m
,
1743 TALLOC_CTX
*mem_ctx
,
1744 const struct dom_sid
*domain_sid
,
1745 const struct dom_sid
*members
,
1747 uint32_t **palias_rids
,
1748 size_t *pnum_alias_rids
)
1750 struct pdb_ads_state
*state
= talloc_get_type_abort(
1751 m
->private_data
, struct pdb_ads_state
);
1752 const char *attrs
[1] = { "objectSid" };
1753 struct tldap_message
**msg
= NULL
;
1754 uint32_t *alias_rids
= NULL
;
1755 size_t num_alias_rids
= 0;
1757 bool got_members
= false;
1762 * TODO: Get the filter right so that we only get the aliases from
1763 * either the SAM or BUILTIN
1766 filter
= talloc_asprintf(talloc_tos(),
1767 "(&(|(grouptype=%d)(grouptype=%d))"
1768 "(objectclass=group)(|",
1769 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
,
1770 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1771 if (filter
== NULL
) {
1772 return NT_STATUS_NO_MEMORY
;
1775 for (i
=0; i
<num_members
; i
++) {
1778 status
= pdb_ads_sid2dn(state
, &members
[i
], talloc_tos(), &dn
);
1779 if (!NT_STATUS_IS_OK(status
)) {
1780 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1781 sid_string_dbg(&members
[i
]),
1782 nt_errstr(status
)));
1785 filter
= talloc_asprintf_append_buffer(
1786 filter
, "(member=%s)", dn
);
1788 if (filter
== NULL
) {
1789 return NT_STATUS_NO_MEMORY
;
1798 rc
= pdb_ads_search_fmt(state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
1799 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(),
1800 &msg
, "%s))", filter
);
1801 TALLOC_FREE(filter
);
1802 if (rc
!= TLDAP_SUCCESS
) {
1803 DEBUG(10, ("tldap_search failed %s\n",
1804 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1805 return NT_STATUS_LDAP(rc
);
1808 count
= talloc_array_length(msg
);
1813 alias_rids
= talloc_array(mem_ctx
, uint32_t, count
);
1814 if (alias_rids
== NULL
) {
1816 return NT_STATUS_NO_MEMORY
;
1819 for (i
=0; i
<count
; i
++) {
1822 if (!tldap_pull_binsid(msg
[i
], "objectSid", &sid
)) {
1823 DEBUG(10, ("Could not pull SID for member %d\n", i
));
1826 if (sid_peek_check_rid(domain_sid
, &sid
,
1827 &alias_rids
[num_alias_rids
])) {
1828 num_alias_rids
+= 1;
1833 *palias_rids
= alias_rids
;
1834 *pnum_alias_rids
= 0;
1835 return NT_STATUS_OK
;
1838 static NTSTATUS
pdb_ads_lookup_rids(struct pdb_methods
*m
,
1839 const struct dom_sid
*domain_sid
,
1843 enum lsa_SidType
*lsa_attrs
)
1845 struct pdb_ads_state
*state
= talloc_get_type_abort(
1846 m
->private_data
, struct pdb_ads_state
);
1847 const char *attrs
[2] = { "sAMAccountType", "sAMAccountName" };
1850 if (num_rids
== 0) {
1851 return NT_STATUS_NONE_MAPPED
;
1856 for (i
=0; i
<num_rids
; i
++) {
1858 struct tldap_message
**msg
;
1863 lsa_attrs
[i
] = SID_NAME_UNKNOWN
;
1865 sid_compose(&sid
, domain_sid
, rids
[i
]);
1867 sidstr
= ldap_encode_ndr_dom_sid(talloc_tos(), &sid
);
1868 NT_STATUS_HAVE_NO_MEMORY(sidstr
);
1870 rc
= pdb_ads_search_fmt(state
, state
->domaindn
,
1871 TLDAP_SCOPE_SUB
, attrs
,
1872 ARRAY_SIZE(attrs
), 0, talloc_tos(),
1873 &msg
, "(objectsid=%s)", sidstr
);
1874 TALLOC_FREE(sidstr
);
1875 if (rc
!= TLDAP_SUCCESS
) {
1876 DEBUG(10, ("ldap_search failed %s\n",
1877 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
1881 switch talloc_array_length(msg
) {
1883 DEBUG(10, ("rid %d not found\n", (int)rids
[i
]));
1888 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
1891 names
[i
] = tldap_talloc_single_attribute(
1892 msg
[0], "samAccountName", talloc_tos());
1893 if (names
[i
] == NULL
) {
1894 DEBUG(10, ("no samAccountName\n"));
1897 if (!tldap_pull_uint32(msg
[0], "samAccountType", &attr
)) {
1898 DEBUG(10, ("no samAccountType"));
1901 lsa_attrs
[i
] = ds_atype_map(attr
);
1905 if (num_mapped
== 0) {
1906 return NT_STATUS_NONE_MAPPED
;
1908 if (num_mapped
< num_rids
) {
1909 return STATUS_SOME_UNMAPPED
;
1911 return NT_STATUS_OK
;
1914 static NTSTATUS
pdb_ads_lookup_names(struct pdb_methods
*m
,
1915 const struct dom_sid
*domain_sid
,
1917 const char **pp_names
,
1919 enum lsa_SidType
*attrs
)
1921 return NT_STATUS_NOT_IMPLEMENTED
;
1924 static NTSTATUS
pdb_ads_get_account_policy(struct pdb_methods
*m
,
1925 enum pdb_policy_type type
,
1928 return account_policy_get(type
, value
)
1929 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1932 static NTSTATUS
pdb_ads_set_account_policy(struct pdb_methods
*m
,
1933 enum pdb_policy_type type
,
1936 return account_policy_set(type
, value
)
1937 ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1940 static NTSTATUS
pdb_ads_get_seq_num(struct pdb_methods
*m
,
1943 return NT_STATUS_NOT_IMPLEMENTED
;
1946 struct pdb_ads_search_state
{
1947 uint32_t acct_flags
;
1948 struct samr_displayentry
*entries
;
1949 uint32_t num_entries
;
1954 static bool pdb_ads_next_entry(struct pdb_search
*search
,
1955 struct samr_displayentry
*entry
)
1957 struct pdb_ads_search_state
*state
= talloc_get_type_abort(
1958 search
->private_data
, struct pdb_ads_search_state
);
1960 if (state
->current
== state
->num_entries
) {
1964 entry
->idx
= state
->entries
[state
->current
].idx
;
1965 entry
->rid
= state
->entries
[state
->current
].rid
;
1966 entry
->acct_flags
= state
->entries
[state
->current
].acct_flags
;
1968 entry
->account_name
= talloc_strdup(
1969 search
, state
->entries
[state
->current
].account_name
);
1970 entry
->fullname
= talloc_strdup(
1971 search
, state
->entries
[state
->current
].fullname
);
1972 entry
->description
= talloc_strdup(
1973 search
, state
->entries
[state
->current
].description
);
1975 if ((entry
->account_name
== NULL
) || (entry
->fullname
== NULL
)
1976 || (entry
->description
== NULL
)) {
1977 DEBUG(0, ("talloc_strdup failed\n"));
1981 state
->current
+= 1;
1985 static void pdb_ads_search_end(struct pdb_search
*search
)
1987 struct pdb_ads_search_state
*state
= talloc_get_type_abort(
1988 search
->private_data
, struct pdb_ads_search_state
);
1992 static bool pdb_ads_search_filter(struct pdb_methods
*m
,
1993 struct pdb_search
*search
,
1995 uint32_t acct_flags
,
1996 struct pdb_ads_search_state
**pstate
)
1998 struct pdb_ads_state
*state
= talloc_get_type_abort(
1999 m
->private_data
, struct pdb_ads_state
);
2000 struct pdb_ads_search_state
*sstate
;
2001 const char * attrs
[] = { "objectSid", "sAMAccountName", "displayName",
2002 "userAccountControl", "description" };
2003 struct tldap_message
**users
;
2004 int i
, rc
, num_users
;
2006 sstate
= talloc_zero(search
, struct pdb_ads_search_state
);
2007 if (sstate
== NULL
) {
2010 sstate
->acct_flags
= acct_flags
;
2012 rc
= pdb_ads_search_fmt(
2013 state
, state
->domaindn
, TLDAP_SCOPE_SUB
,
2014 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &users
,
2016 if (rc
!= TLDAP_SUCCESS
) {
2017 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
2018 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2022 num_users
= talloc_array_length(users
);
2024 sstate
->entries
= talloc_array(sstate
, struct samr_displayentry
,
2026 if (sstate
->entries
== NULL
) {
2027 DEBUG(10, ("talloc failed\n"));
2031 sstate
->num_entries
= 0;
2033 for (i
=0; i
<num_users
; i
++) {
2034 struct samr_displayentry
*e
;
2038 e
= &sstate
->entries
[sstate
->num_entries
];
2040 e
->idx
= sstate
->num_entries
;
2041 if (!tldap_pull_binsid(users
[i
], "objectSid", &sid
)) {
2042 DEBUG(10, ("Could not pull sid\n"));
2045 sid_peek_rid(&sid
, &e
->rid
);
2047 if (tldap_pull_uint32(users
[i
], "userAccountControl", &ctrl
)) {
2049 e
->acct_flags
= ds_uf2acb(ctrl
);
2051 DEBUG(10, ("pdb_ads_search_filter: Found %x, "
2052 "filter %x\n", (int)e
->acct_flags
,
2053 (int)sstate
->acct_flags
));
2056 if ((sstate
->acct_flags
!= 0) &&
2057 ((sstate
->acct_flags
& e
->acct_flags
) == 0)) {
2061 if (e
->acct_flags
& (ACB_WSTRUST
|ACB_SVRTRUST
)) {
2062 e
->acct_flags
|= ACB_NORMAL
;
2065 e
->acct_flags
= ACB_NORMAL
;
2068 if (e
->rid
== DOMAIN_RID_GUEST
) {
2070 * Guest is specially crafted in s3. Make
2071 * QueryDisplayInfo match QueryUserInfo
2073 e
->account_name
= lp_guestaccount();
2074 e
->fullname
= lp_guestaccount();
2075 e
->description
= "";
2076 e
->acct_flags
= ACB_NORMAL
;
2078 e
->account_name
= tldap_talloc_single_attribute(
2079 users
[i
], "samAccountName", sstate
->entries
);
2080 e
->fullname
= tldap_talloc_single_attribute(
2081 users
[i
], "displayName", sstate
->entries
);
2082 e
->description
= tldap_talloc_single_attribute(
2083 users
[i
], "description", sstate
->entries
);
2085 if (e
->account_name
== NULL
) {
2088 if (e
->fullname
== NULL
) {
2091 if (e
->description
== NULL
) {
2092 e
->description
= "";
2095 sstate
->num_entries
+= 1;
2096 if (sstate
->num_entries
>= num_users
) {
2101 search
->private_data
= sstate
;
2102 search
->next_entry
= pdb_ads_next_entry
;
2103 search
->search_end
= pdb_ads_search_end
;
2108 static bool pdb_ads_search_users(struct pdb_methods
*m
,
2109 struct pdb_search
*search
,
2112 struct pdb_ads_search_state
*sstate
;
2116 DEBUG(10, ("pdb_ads_search_users got flags %x\n", acct_flags
));
2118 if (acct_flags
& ACB_NORMAL
) {
2119 filter
= talloc_asprintf(
2121 "(&(objectclass=user)(sAMAccountType=%d))",
2122 ATYPE_NORMAL_ACCOUNT
);
2123 } else if (acct_flags
& ACB_WSTRUST
) {
2124 filter
= talloc_asprintf(
2126 "(&(objectclass=user)(sAMAccountType=%d))",
2127 ATYPE_WORKSTATION_TRUST
);
2129 filter
= talloc_strdup(talloc_tos(), "(objectclass=user)");
2131 if (filter
== NULL
) {
2135 ret
= pdb_ads_search_filter(m
, search
, filter
, acct_flags
, &sstate
);
2136 TALLOC_FREE(filter
);
2143 static bool pdb_ads_search_groups(struct pdb_methods
*m
,
2144 struct pdb_search
*search
)
2146 struct pdb_ads_search_state
*sstate
;
2150 filter
= talloc_asprintf(talloc_tos(),
2151 "(&(grouptype=%d)(objectclass=group))",
2152 GTYPE_SECURITY_GLOBAL_GROUP
);
2153 if (filter
== NULL
) {
2156 ret
= pdb_ads_search_filter(m
, search
, filter
, 0, &sstate
);
2157 TALLOC_FREE(filter
);
2164 static bool pdb_ads_search_aliases(struct pdb_methods
*m
,
2165 struct pdb_search
*search
,
2166 const struct dom_sid
*sid
)
2168 struct pdb_ads_search_state
*sstate
;
2172 filter
= talloc_asprintf(
2173 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
2174 sid_check_is_builtin(sid
)
2175 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2176 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
2178 if (filter
== NULL
) {
2181 ret
= pdb_ads_search_filter(m
, search
, filter
, 0, &sstate
);
2182 TALLOC_FREE(filter
);
2189 static bool pdb_ads_uid_to_sid(struct pdb_methods
*m
, uid_t uid
,
2190 struct dom_sid
*sid
)
2192 struct pdb_ads_state
*state
= talloc_get_type_abort(
2193 m
->private_data
, struct pdb_ads_state
);
2194 sid_compose(sid
, &state
->domainsid
, uid
);
2198 static bool pdb_ads_gid_to_sid(struct pdb_methods
*m
, gid_t gid
,
2199 struct dom_sid
*sid
)
2201 struct pdb_ads_state
*state
= talloc_get_type_abort(
2202 m
->private_data
, struct pdb_ads_state
);
2203 sid_compose(sid
, &state
->domainsid
, gid
);
2207 static bool pdb_ads_sid_to_id(struct pdb_methods
*m
, const struct dom_sid
*sid
,
2210 struct pdb_ads_state
*state
= talloc_get_type_abort(
2211 m
->private_data
, struct pdb_ads_state
);
2212 const char *attrs
[4] = { "objectClass", "samAccountType",
2213 "uidNumber", "gidNumber" };
2214 struct tldap_message
**msg
;
2215 char *sidstr
, *base
;
2221 id
->type
= ID_TYPE_NOT_SPECIFIED
;
2223 sidstr
= sid_binstring_hex(sid
);
2224 if (sidstr
== NULL
) {
2227 base
= talloc_asprintf(talloc_tos(), "<SID=%s>", sidstr
);
2230 rc
= pdb_ads_search_fmt(
2231 state
, base
, TLDAP_SCOPE_BASE
,
2232 attrs
, ARRAY_SIZE(attrs
), 0, talloc_tos(), &msg
,
2236 if (rc
!= TLDAP_SUCCESS
) {
2237 DEBUG(10, ("pdb_ads_search_fmt failed: %s\n",
2238 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2241 if (talloc_array_length(msg
) != 1) {
2242 DEBUG(10, ("Got %d objects, expected 1\n",
2243 (int)talloc_array_length(msg
)));
2246 if (!tldap_pull_uint32(msg
[0], "samAccountType", &atype
)) {
2247 DEBUG(10, ("samAccountType not found\n"));
2250 if (atype
== ATYPE_ACCOUNT
) {
2252 id
->type
= ID_TYPE_UID
;
2253 if (!tldap_pull_uint32(msg
[0], "uidNumber", &uid
)) {
2254 DEBUG(10, ("Did not find uidNumber\n"));
2260 id
->type
= ID_TYPE_GID
;
2261 if (!tldap_pull_uint32(msg
[0], "gidNumber", &gid
)) {
2262 DEBUG(10, ("Did not find gidNumber\n"));
2273 static uint32_t pdb_ads_capabilities(struct pdb_methods
*m
)
2275 return PDB_CAP_STORE_RIDS
| PDB_CAP_ADS
;
2278 static bool pdb_ads_new_rid(struct pdb_methods
*m
, uint32
*rid
)
2283 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods
*m
,
2284 const char *domain
, char** pwd
,
2285 struct dom_sid
*sid
,
2286 time_t *pass_last_set_time
)
2291 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods
*m
,
2292 const char* domain
, const char* pwd
,
2293 const struct dom_sid
*sid
)
2298 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods
*m
,
2304 static NTSTATUS
pdb_ads_enum_trusteddoms(struct pdb_methods
*m
,
2305 TALLOC_CTX
*mem_ctx
,
2306 uint32
*num_domains
,
2307 struct trustdom_info
***domains
)
2311 return NT_STATUS_OK
;
2314 static void pdb_ads_init_methods(struct pdb_methods
*m
)
2317 m
->get_domain_info
= pdb_ads_get_domain_info
;
2318 m
->getsampwnam
= pdb_ads_getsampwnam
;
2319 m
->getsampwsid
= pdb_ads_getsampwsid
;
2320 m
->create_user
= pdb_ads_create_user
;
2321 m
->delete_user
= pdb_ads_delete_user
;
2322 m
->add_sam_account
= pdb_ads_add_sam_account
;
2323 m
->update_sam_account
= pdb_ads_update_sam_account
;
2324 m
->delete_sam_account
= pdb_ads_delete_sam_account
;
2325 m
->rename_sam_account
= pdb_ads_rename_sam_account
;
2326 m
->update_login_attempts
= pdb_ads_update_login_attempts
;
2327 m
->getgrsid
= pdb_ads_getgrsid
;
2328 m
->getgrgid
= pdb_ads_getgrgid
;
2329 m
->getgrnam
= pdb_ads_getgrnam
;
2330 m
->create_dom_group
= pdb_ads_create_dom_group
;
2331 m
->delete_dom_group
= pdb_ads_delete_dom_group
;
2332 m
->add_group_mapping_entry
= pdb_ads_add_group_mapping_entry
;
2333 m
->update_group_mapping_entry
= pdb_ads_update_group_mapping_entry
;
2334 m
->delete_group_mapping_entry
= pdb_ads_delete_group_mapping_entry
;
2335 m
->enum_group_mapping
= pdb_ads_enum_group_mapping
;
2336 m
->enum_group_members
= pdb_ads_enum_group_members
;
2337 m
->enum_group_memberships
= pdb_ads_enum_group_memberships
;
2338 m
->set_unix_primary_group
= pdb_ads_set_unix_primary_group
;
2339 m
->add_groupmem
= pdb_ads_add_groupmem
;
2340 m
->del_groupmem
= pdb_ads_del_groupmem
;
2341 m
->create_alias
= pdb_ads_create_alias
;
2342 m
->delete_alias
= pdb_ads_delete_alias
;
2343 m
->get_aliasinfo
= pdb_default_get_aliasinfo
;
2344 m
->set_aliasinfo
= pdb_ads_set_aliasinfo
;
2345 m
->add_aliasmem
= pdb_ads_add_aliasmem
;
2346 m
->del_aliasmem
= pdb_ads_del_aliasmem
;
2347 m
->enum_aliasmem
= pdb_ads_enum_aliasmem
;
2348 m
->enum_alias_memberships
= pdb_ads_enum_alias_memberships
;
2349 m
->lookup_rids
= pdb_ads_lookup_rids
;
2350 m
->lookup_names
= pdb_ads_lookup_names
;
2351 m
->get_account_policy
= pdb_ads_get_account_policy
;
2352 m
->set_account_policy
= pdb_ads_set_account_policy
;
2353 m
->get_seq_num
= pdb_ads_get_seq_num
;
2354 m
->search_users
= pdb_ads_search_users
;
2355 m
->search_groups
= pdb_ads_search_groups
;
2356 m
->search_aliases
= pdb_ads_search_aliases
;
2357 m
->uid_to_sid
= pdb_ads_uid_to_sid
;
2358 m
->gid_to_sid
= pdb_ads_gid_to_sid
;
2359 m
->sid_to_id
= pdb_ads_sid_to_id
;
2360 m
->capabilities
= pdb_ads_capabilities
;
2361 m
->new_rid
= pdb_ads_new_rid
;
2362 m
->get_trusteddom_pw
= pdb_ads_get_trusteddom_pw
;
2363 m
->set_trusteddom_pw
= pdb_ads_set_trusteddom_pw
;
2364 m
->del_trusteddom_pw
= pdb_ads_del_trusteddom_pw
;
2365 m
->enum_trusteddoms
= pdb_ads_enum_trusteddoms
;
2368 static void free_private_data(void **vp
)
2370 struct pdb_ads_state
*state
= talloc_get_type_abort(
2371 *vp
, struct pdb_ads_state
);
2373 TALLOC_FREE(state
->ld
);
2378 this is used to catch debug messages from events
2380 static void s3_tldap_debug(void *context
, enum tldap_debug_level level
,
2381 const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(3,0);
2383 static void s3_tldap_debug(void *context
, enum tldap_debug_level level
,
2384 const char *fmt
, va_list ap
)
2386 int samba_level
= -1;
2389 case TLDAP_DEBUG_FATAL
:
2392 case TLDAP_DEBUG_ERROR
:
2395 case TLDAP_DEBUG_WARNING
:
2398 case TLDAP_DEBUG_TRACE
:
2403 if (vasprintf(&s
, fmt
, ap
) == -1) {
2406 DEBUG(samba_level
, ("tldap: %s", s
));
2410 static struct tldap_context
*pdb_ads_ld(struct pdb_ads_state
*state
)
2415 if (tldap_connection_ok(state
->ld
)) {
2418 TALLOC_FREE(state
->ld
);
2420 status
= open_socket_out(
2421 (struct sockaddr_storage
*)(void *)&state
->socket_address
,
2423 if (!NT_STATUS_IS_OK(status
)) {
2424 DEBUG(10, ("Could not connect to %s: %s\n",
2425 state
->socket_address
.sun_path
, nt_errstr(status
)));
2429 set_blocking(fd
, false);
2431 state
->ld
= tldap_context_create(state
, fd
);
2432 if (state
->ld
== NULL
) {
2436 tldap_set_debug(state
->ld
, s3_tldap_debug
, NULL
);
2441 int pdb_ads_search_fmt(struct pdb_ads_state
*state
, const char *base
,
2442 int scope
, const char *attrs
[], int num_attrs
,
2444 TALLOC_CTX
*mem_ctx
, struct tldap_message
***res
,
2445 const char *fmt
, ...)
2447 struct tldap_context
*ld
;
2451 ld
= pdb_ads_ld(state
);
2453 return TLDAP_SERVER_DOWN
;
2457 ret
= tldap_search_va(ld
, base
, scope
, attrs
, num_attrs
, attrsonly
,
2458 mem_ctx
, res
, fmt
, ap
);
2461 if (ret
!= TLDAP_SERVER_DOWN
) {
2466 ld
= pdb_ads_ld(state
);
2468 return TLDAP_SERVER_DOWN
;
2472 ret
= tldap_search_va(ld
, base
, scope
, attrs
, num_attrs
, attrsonly
,
2473 mem_ctx
, res
, fmt
, ap
);
2478 static NTSTATUS
pdb_ads_connect(struct pdb_ads_state
*state
,
2479 const char *location
)
2481 const char *domain_attrs
[2] = { "objectSid", "objectGUID" };
2482 const char *ncname_attrs
[1] = { "netbiosname" };
2483 struct tldap_context
*ld
;
2484 struct tldap_message
*rootdse
, **domain
, **ncname
;
2485 TALLOC_CTX
*frame
= talloc_stackframe();
2490 ZERO_STRUCT(state
->socket_address
);
2491 state
->socket_address
.sun_family
= AF_UNIX
;
2492 strlcpy(state
->socket_address
.sun_path
, location
,
2493 sizeof(state
->socket_address
.sun_path
));
2495 ld
= pdb_ads_ld(state
);
2497 status
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2501 rc
= tldap_fetch_rootdse(ld
);
2502 if (rc
!= TLDAP_SUCCESS
) {
2503 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2504 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2505 status
= NT_STATUS_LDAP(rc
);
2508 rootdse
= tldap_rootdse(state
->ld
);
2510 state
->domaindn
= tldap_talloc_single_attribute(
2511 rootdse
, "defaultNamingContext", state
);
2512 if (state
->domaindn
== NULL
) {
2513 DEBUG(10, ("Could not get defaultNamingContext\n"));
2514 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2517 DEBUG(10, ("defaultNamingContext = %s\n", state
->domaindn
));
2519 state
->configdn
= tldap_talloc_single_attribute(
2520 rootdse
, "configurationNamingContext", state
);
2521 if (state
->configdn
== NULL
) {
2522 DEBUG(10, ("Could not get configurationNamingContext\n"));
2523 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2526 DEBUG(10, ("configurationNamingContext = %s\n", state
->configdn
));
2529 * Figure out our domain's SID
2531 rc
= pdb_ads_search_fmt(
2532 state
, state
->domaindn
, TLDAP_SCOPE_BASE
,
2533 domain_attrs
, ARRAY_SIZE(domain_attrs
), 0,
2534 talloc_tos(), &domain
, "(objectclass=*)");
2535 if (rc
!= TLDAP_SUCCESS
) {
2536 DEBUG(10, ("Could not retrieve domain: %s\n",
2537 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2538 status
= NT_STATUS_LDAP(rc
);
2542 num_domains
= talloc_array_length(domain
);
2543 if (num_domains
!= 1) {
2544 DEBUG(10, ("Got %d domains, expected one\n", num_domains
));
2545 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2548 if (!tldap_pull_binsid(domain
[0], "objectSid", &state
->domainsid
)) {
2549 DEBUG(10, ("Could not retrieve domain SID\n"));
2550 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2553 if (!tldap_pull_guid(domain
[0], "objectGUID", &state
->domainguid
)) {
2554 DEBUG(10, ("Could not retrieve domain GUID\n"));
2555 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2558 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state
->domainsid
)));
2561 * Figure out our domain's short name
2563 rc
= pdb_ads_search_fmt(
2564 state
, state
->configdn
, TLDAP_SCOPE_SUB
,
2565 ncname_attrs
, ARRAY_SIZE(ncname_attrs
), 0,
2566 talloc_tos(), &ncname
, "(ncname=%s)", state
->domaindn
);
2567 if (rc
!= TLDAP_SUCCESS
) {
2568 DEBUG(10, ("Could not retrieve ncname: %s\n",
2569 tldap_errstr(talloc_tos(), state
->ld
, rc
)));
2570 status
= NT_STATUS_LDAP(rc
);
2573 if (talloc_array_length(ncname
) != 1) {
2574 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2578 state
->netbiosname
= tldap_talloc_single_attribute(
2579 ncname
[0], "netbiosname", state
);
2580 if (state
->netbiosname
== NULL
) {
2581 DEBUG(10, ("Could not get netbiosname\n"));
2582 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2585 DEBUG(10, ("netbiosname: %s\n", state
->netbiosname
));
2587 if (!strequal(lp_workgroup(), state
->netbiosname
)) {
2588 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2589 state
->netbiosname
, lp_workgroup()));
2590 status
= NT_STATUS_NO_SUCH_DOMAIN
;
2594 secrets_store_domain_sid(state
->netbiosname
, &state
->domainsid
);
2596 status
= NT_STATUS_OK
;
2602 static NTSTATUS
pdb_ads_init_secrets(struct pdb_methods
*m
)
2604 #if _SAMBA_BUILD_ == 4
2605 struct pdb_domain_info
*dom_info
;
2608 dom_info
= pdb_ads_get_domain_info(m
, m
);
2610 return NT_STATUS_UNSUCCESSFUL
;
2613 secrets_clear_domain_protection(dom_info
->name
);
2614 ret
= secrets_store_domain_sid(dom_info
->name
,
2619 ret
= secrets_store_domain_guid(dom_info
->name
,
2624 ret
= secrets_mark_domain_protected(dom_info
->name
);
2630 TALLOC_FREE(dom_info
);
2632 return NT_STATUS_UNSUCCESSFUL
;
2635 return NT_STATUS_OK
;
2638 static NTSTATUS
pdb_init_ads(struct pdb_methods
**pdb_method
,
2639 const char *location
)
2641 struct pdb_methods
*m
;
2642 struct pdb_ads_state
*state
;
2646 m
= talloc(NULL
, struct pdb_methods
);
2648 return NT_STATUS_NO_MEMORY
;
2650 state
= talloc_zero(m
, struct pdb_ads_state
);
2651 if (state
== NULL
) {
2654 m
->private_data
= state
;
2655 m
->free_private_data
= free_private_data
;
2656 pdb_ads_init_methods(m
);
2658 if (location
== NULL
) {
2659 tmp
= talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2663 if (location
== NULL
) {
2667 status
= pdb_ads_connect(state
, location
);
2668 if (!NT_STATUS_IS_OK(status
)) {
2669 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status
)));
2673 status
= pdb_ads_init_secrets(m
);
2674 if (!NT_STATUS_IS_OK(status
)) {
2675 DEBUG(10, ("pdb_ads_init_secrets failed!\n"));
2680 return NT_STATUS_OK
;
2682 status
= NT_STATUS_NO_MEMORY
;
2688 NTSTATUS
pdb_ads_init(void);
2689 NTSTATUS
pdb_ads_init(void)
2691 return smb_register_passdb(PASSDB_INTERFACE_VERSION
, "ads",