2 Unix SMB/CIFS implementation.
3 pdb_ldap with ads schema
4 Copyright (C) Volker Lendecke 2009
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "tldap_util.h"
23 #include "../libds/common/flags.h"
25 #include "../librpc/gen_ndr/samr.h"
26 #include "../libcli/ldap/ldap_ndr.h"
27 #include "../libcli/security/security.h"
29 struct pdb_ads_state {
30 struct sockaddr_un socket_address;
31 struct tldap_context *ld;
32 struct dom_sid domainsid;
33 struct GUID domainguid;
39 struct pdb_ads_samu_private {
41 struct tldap_message *ldapmsg;
44 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
45 struct samu *sam_acct,
46 const struct dom_sid *sid);
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 = uint64s_nt_time_to_unix_abs(&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;
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 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
251 DEBUG(10, ("Could not pull SID\n"));
254 pdb_set_user_sid(sam, &sid, PDB_SET);
256 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
257 DEBUG(10, ("Could not pull userAccountControl\n"));
260 pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
262 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
263 if (blob.length != NT_HASH_LEN) {
264 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
265 (int)blob.length, NT_HASH_LEN));
268 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
271 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
272 if (blob.length != LM_HASH_LEN) {
273 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
274 (int)blob.length, LM_HASH_LEN));
277 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
280 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
281 sid_compose(&sid, &state->domainsid, n);
282 pdb_set_group_sid(sam, &sid, PDB_SET);
285 status = NT_STATUS_OK;
291 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
292 struct tldap_message *existing,
294 int *pnum_mods, struct tldap_mod **pmods,
300 /* TODO: All fields :-) */
302 ret &= tldap_make_mod_fmt(
303 existing, mem_ctx, pnum_mods, pmods, "displayName",
304 "%s", pdb_get_fullname(sam));
306 blob = data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN);
307 if (blob.data != NULL) {
308 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
309 "unicodePwd", 1, &blob);
312 blob = data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN);
313 if (blob.data != NULL) {
314 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
315 "dBCSPwd", 1, &blob);
318 ret &= tldap_make_mod_fmt(
319 existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
320 "%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
322 ret &= tldap_make_mod_fmt(
323 existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
324 "%s", pdb_get_homedir(sam));
326 ret &= tldap_make_mod_fmt(
327 existing, mem_ctx, pnum_mods, pmods, "homeDrive",
328 "%s", pdb_get_dir_drive(sam));
330 ret &= tldap_make_mod_fmt(
331 existing, mem_ctx, pnum_mods, pmods, "scriptPath",
332 "%s", pdb_get_logon_script(sam));
334 ret &= tldap_make_mod_fmt(
335 existing, mem_ctx, pnum_mods, pmods, "profilePath",
336 "%s", pdb_get_profile_path(sam));
341 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
344 struct pdb_ads_samu_private **presult)
346 const char * attrs[] = {
347 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
348 "sAMAccountName", "displayName", "homeDirectory",
349 "homeDrive", "scriptPath", "profilePath", "description",
350 "userWorkstations", "comment", "userParameters", "objectSid",
351 "primaryGroupID", "userAccountControl", "logonHours",
352 "badPwdCount", "logonCount", "countryCode", "codePage",
353 "unicodePwd", "dBCSPwd" };
354 struct tldap_message **users;
356 struct pdb_ads_samu_private *result;
358 result = talloc(mem_ctx, struct pdb_ads_samu_private);
359 if (result == NULL) {
360 return NT_STATUS_NO_MEMORY;
363 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
364 attrs, ARRAY_SIZE(attrs), 0, result,
365 &users, "%s", filter);
366 if (rc != TLDAP_SUCCESS) {
367 DEBUG(10, ("ldap_search failed %s\n",
368 tldap_errstr(talloc_tos(), state->ld, rc)));
370 return NT_STATUS_LDAP(rc);
373 count = talloc_array_length(users);
375 DEBUG(10, ("Expected 1 user, got %d\n", count));
377 return NT_STATUS_INTERNAL_DB_CORRUPTION;
380 result->ldapmsg = users[0];
381 if (!tldap_entry_dn(result->ldapmsg, &result->dn)) {
382 DEBUG(10, ("Could not extract dn\n"));
384 return NT_STATUS_INTERNAL_DB_CORRUPTION;
391 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
392 struct pdb_ads_state *state,
393 struct samu *sam_acct,
396 struct pdb_ads_samu_private *priv;
399 status = pdb_ads_getsamupriv(state, filter, sam_acct, &priv);
400 if (!NT_STATUS_IS_OK(status)) {
401 DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n",
406 status = pdb_ads_init_sam_from_priv(m, sam_acct, priv);
407 if (!NT_STATUS_IS_OK(status)) {
408 DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n",
414 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
418 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
419 struct samu *sam_acct,
420 const char *username)
422 struct pdb_ads_state *state = talloc_get_type_abort(
423 m->private_data, struct pdb_ads_state);
426 filter = talloc_asprintf(
427 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
429 NT_STATUS_HAVE_NO_MEMORY(filter);
431 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
434 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
435 struct samu *sam_acct,
436 const struct dom_sid *sid)
438 struct pdb_ads_state *state = talloc_get_type_abort(
439 m->private_data, struct pdb_ads_state);
440 char *sidstr, *filter;
442 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
443 NT_STATUS_HAVE_NO_MEMORY(sidstr);
445 filter = talloc_asprintf(
446 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
448 NT_STATUS_HAVE_NO_MEMORY(filter);
450 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
453 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
455 const char *name, uint32 acct_flags,
458 struct pdb_ads_state *state = talloc_get_type_abort(
459 m->private_data, struct pdb_ads_state);
460 struct tldap_context *ld;
461 const char *attrs[1] = { "objectSid" };
462 struct tldap_mod *mods = NULL;
464 struct tldap_message **user;
470 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
473 return NT_STATUS_NO_MEMORY;
476 ld = pdb_ads_ld(state);
478 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
481 /* TODO: Create machines etc */
484 ok &= tldap_make_mod_fmt(
485 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
486 ok &= tldap_make_mod_fmt(
487 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
490 return NT_STATUS_NO_MEMORY;
494 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
495 if (rc != TLDAP_SUCCESS) {
496 DEBUG(10, ("ldap_add failed %s\n",
497 tldap_errstr(talloc_tos(), ld, rc)));
499 return NT_STATUS_LDAP(rc);
502 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
503 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
505 "(&(objectclass=user)(samaccountname=%s))",
507 if (rc != TLDAP_SUCCESS) {
508 DEBUG(10, ("Could not find just created user %s: %s\n",
509 name, tldap_errstr(talloc_tos(), state->ld, rc)));
511 return NT_STATUS_LDAP(rc);
514 if (talloc_array_length(user) != 1) {
515 DEBUG(10, ("Got %d users, expected one\n",
516 (int)talloc_array_length(user)));
518 return NT_STATUS_LDAP(rc);
521 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
522 DEBUG(10, ("Could not fetch objectSid from user %s\n",
525 return NT_STATUS_INTERNAL_DB_CORRUPTION;
528 sid_peek_rid(&sid, rid);
533 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
537 struct pdb_ads_state *state = talloc_get_type_abort(
538 m->private_data, struct pdb_ads_state);
540 struct tldap_context *ld;
544 ld = pdb_ads_ld(state);
546 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
549 status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
551 if (!NT_STATUS_IS_OK(status)) {
555 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
557 if (rc != TLDAP_SUCCESS) {
558 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
559 tldap_errstr(talloc_tos(), ld, rc)));
560 return NT_STATUS_LDAP(rc);
565 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
566 struct samu *sampass)
568 return NT_STATUS_NOT_IMPLEMENTED;
571 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
574 struct pdb_ads_state *state = talloc_get_type_abort(
575 m->private_data, struct pdb_ads_state);
576 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
577 struct tldap_context *ld;
578 struct tldap_mod *mods = NULL;
579 int rc, num_mods = 0;
581 ld = pdb_ads_ld(state);
583 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
586 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
587 &num_mods, &mods, sam)) {
588 return NT_STATUS_NO_MEMORY;
592 /* Nothing to do, just return success */
596 rc = tldap_modify(ld, priv->dn, num_mods, mods, NULL, 0,
599 if (rc != TLDAP_SUCCESS) {
600 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
601 tldap_errstr(talloc_tos(), ld, rc)));
602 return NT_STATUS_LDAP(rc);
608 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
609 struct samu *username)
611 return NT_STATUS_NOT_IMPLEMENTED;
614 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
615 struct samu *oldname,
618 return NT_STATUS_NOT_IMPLEMENTED;
621 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
622 struct samu *sam_acct,
625 return NT_STATUS_NOT_IMPLEMENTED;
628 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
631 struct pdb_ads_state *state = talloc_get_type_abort(
632 m->private_data, struct pdb_ads_state);
633 const char *attrs[4] = { "objectSid", "description", "samAccountName",
636 struct tldap_message **group;
640 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
641 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
642 &group, "%s", filter);
643 if (rc != TLDAP_SUCCESS) {
644 DEBUG(10, ("ldap_search failed %s\n",
645 tldap_errstr(talloc_tos(), state->ld, rc)));
646 return NT_STATUS_LDAP(rc);
648 if (talloc_array_length(group) != 1) {
649 DEBUG(10, ("Expected 1 user, got %d\n",
650 (int)talloc_array_length(group)));
651 return NT_STATUS_INTERNAL_DB_CORRUPTION;
654 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
655 return NT_STATUS_INTERNAL_DB_CORRUPTION;
657 map->gid = pdb_ads_sid2gid(&map->sid);
659 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
660 return NT_STATUS_INTERNAL_DB_CORRUPTION;
663 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
664 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
665 map->sid_name_use = SID_NAME_ALIAS;
667 case GTYPE_SECURITY_GLOBAL_GROUP:
668 map->sid_name_use = SID_NAME_DOM_GRP;
671 return NT_STATUS_INTERNAL_DB_CORRUPTION;
674 str = tldap_talloc_single_attribute(group[0], "samAccountName",
677 return NT_STATUS_INTERNAL_DB_CORRUPTION;
679 fstrcpy(map->nt_name, str);
682 str = tldap_talloc_single_attribute(group[0], "description",
685 fstrcpy(map->comment, str);
688 map->comment[0] = '\0';
695 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
701 filter = talloc_asprintf(talloc_tos(),
702 "(&(objectsid=%s)(objectclass=group))",
703 sid_string_talloc(talloc_tos(), &sid));
704 if (filter == NULL) {
705 return NT_STATUS_NO_MEMORY;
708 status = pdb_ads_getgrfilter(m, map, filter);
713 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
717 pdb_ads_gid_to_sid(m, gid, &sid);
718 return pdb_ads_getgrsid(m, map, sid);
721 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
727 filter = talloc_asprintf(talloc_tos(),
728 "(&(samaccountname=%s)(objectclass=group))",
730 if (filter == NULL) {
731 return NT_STATUS_NO_MEMORY;
734 status = pdb_ads_getgrfilter(m, map, filter);
739 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
740 TALLOC_CTX *mem_ctx, const char *name,
743 TALLOC_CTX *frame = talloc_stackframe();
744 struct pdb_ads_state *state = talloc_get_type_abort(
745 m->private_data, struct pdb_ads_state);
746 struct tldap_context *ld;
747 const char *attrs[1] = { "objectSid" };
749 struct tldap_mod *mods = NULL;
750 struct tldap_message **alias;
756 ld = pdb_ads_ld(state);
758 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
761 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
765 return NT_STATUS_NO_MEMORY;
768 ok &= tldap_make_mod_fmt(
769 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
771 ok &= tldap_make_mod_fmt(
772 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
773 ok &= tldap_make_mod_fmt(
774 NULL, talloc_tos(), &num_mods, &mods, "groupType",
775 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
779 return NT_STATUS_NO_MEMORY;
782 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
783 if (rc != TLDAP_SUCCESS) {
784 DEBUG(10, ("ldap_add failed %s\n",
785 tldap_errstr(talloc_tos(), state->ld, rc)));
787 return NT_STATUS_LDAP(rc);
790 rc = pdb_ads_search_fmt(
791 state, state->domaindn, TLDAP_SCOPE_SUB,
792 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
793 "(&(objectclass=group)(samaccountname=%s))", name);
794 if (rc != TLDAP_SUCCESS) {
795 DEBUG(10, ("Could not find just created alias %s: %s\n",
796 name, tldap_errstr(talloc_tos(), state->ld, rc)));
798 return NT_STATUS_LDAP(rc);
801 if (talloc_array_length(alias) != 1) {
802 DEBUG(10, ("Got %d alias, expected one\n",
803 (int)talloc_array_length(alias)));
805 return NT_STATUS_LDAP(rc);
808 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
809 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
812 return NT_STATUS_INTERNAL_DB_CORRUPTION;
815 sid_peek_rid(&sid, rid);
820 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
821 TALLOC_CTX *mem_ctx, uint32 rid)
823 struct pdb_ads_state *state = talloc_get_type_abort(
824 m->private_data, struct pdb_ads_state);
825 struct tldap_context *ld;
828 struct tldap_message **msg;
832 sid_compose(&sid, &state->domainsid, rid);
834 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
835 NT_STATUS_HAVE_NO_MEMORY(sidstr);
837 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
838 NULL, 0, 0, talloc_tos(), &msg,
839 ("(&(objectSid=%s)(objectClass=group))"),
842 if (rc != TLDAP_SUCCESS) {
843 DEBUG(10, ("ldap_search failed %s\n",
844 tldap_errstr(talloc_tos(), state->ld, rc)));
845 return NT_STATUS_LDAP(rc);
848 switch talloc_array_length(msg) {
850 return NT_STATUS_NO_SUCH_GROUP;
854 return NT_STATUS_INTERNAL_DB_CORRUPTION;
857 if (!tldap_entry_dn(msg[0], &dn)) {
859 return NT_STATUS_INTERNAL_DB_CORRUPTION;
862 ld = pdb_ads_ld(state);
865 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
868 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
870 if (rc != TLDAP_SUCCESS) {
871 DEBUG(10, ("ldap_delete failed: %s\n",
872 tldap_errstr(talloc_tos(), state->ld, rc)));
873 return NT_STATUS_LDAP(rc);
879 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
882 return NT_STATUS_NOT_IMPLEMENTED;
885 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
888 return NT_STATUS_NOT_IMPLEMENTED;
891 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
894 return NT_STATUS_NOT_IMPLEMENTED;
897 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
898 const struct dom_sid *sid,
899 enum lsa_SidType sid_name_use,
901 size_t *p_num_entries,
904 return NT_STATUS_NOT_IMPLEMENTED;
907 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
909 const struct dom_sid *group,
911 size_t *pnum_members)
913 struct pdb_ads_state *state = talloc_get_type_abort(
914 m->private_data, struct pdb_ads_state);
915 const char *attrs[1] = { "member" };
917 struct tldap_message **msg;
918 int i, rc, num_members;
922 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), group);
923 NT_STATUS_HAVE_NO_MEMORY(sidstr);
925 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
926 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
927 &msg, "(objectsid=%s)", sidstr);
929 if (rc != TLDAP_SUCCESS) {
930 DEBUG(10, ("ldap_search failed %s\n",
931 tldap_errstr(talloc_tos(), state->ld, rc)));
932 return NT_STATUS_LDAP(rc);
934 switch talloc_array_length(msg) {
936 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
941 return NT_STATUS_INTERNAL_DB_CORRUPTION;
945 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
946 return NT_STATUS_INTERNAL_DB_CORRUPTION;
949 members = talloc_array(mem_ctx, uint32_t, num_members);
950 if (members == NULL) {
951 return NT_STATUS_NO_MEMORY;
954 for (i=0; i<num_members; i++) {
956 if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
957 || !sid_peek_rid(&sid, &members[i])) {
958 TALLOC_FREE(members);
959 return NT_STATUS_INTERNAL_DB_CORRUPTION;
964 *pnum_members = num_members;
968 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
971 struct dom_sid **pp_sids,
973 size_t *p_num_groups)
975 struct pdb_ads_state *state = talloc_get_type_abort(
976 m->private_data, struct pdb_ads_state);
977 struct pdb_ads_samu_private *priv;
978 const char *attrs[1] = { "objectSid" };
979 struct tldap_message **groups;
982 struct dom_sid *group_sids;
985 priv = pdb_ads_get_samu_private(m, user);
987 rc = pdb_ads_search_fmt(
988 state, state->domaindn, TLDAP_SCOPE_SUB,
989 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
990 "(&(member=%s)(grouptype=%d)(objectclass=group))",
991 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
992 if (rc != TLDAP_SUCCESS) {
993 DEBUG(10, ("ldap_search failed %s\n",
994 tldap_errstr(talloc_tos(), state->ld, rc)));
995 return NT_STATUS_LDAP(rc);
997 count = talloc_array_length(groups);
1000 * This happens for artificial samu users
1002 DEBUG(10, ("Could not get pdb_ads_samu_private\n"));
1006 group_sids = talloc_array(mem_ctx, struct dom_sid, count+1);
1007 if (group_sids == NULL) {
1008 return NT_STATUS_NO_MEMORY;
1010 gids = talloc_array(mem_ctx, gid_t, count+1);
1012 TALLOC_FREE(group_sids);
1013 return NT_STATUS_NO_MEMORY;
1016 sid_copy(&group_sids[0], pdb_get_group_sid(user));
1017 if (!sid_to_gid(&group_sids[0], &gids[0])) {
1019 TALLOC_FREE(group_sids);
1020 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1024 for (i=0; i<count; i++) {
1025 if (!tldap_pull_binsid(groups[i], "objectSid",
1026 &group_sids[num_groups])) {
1029 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
1032 if (num_groups == count) {
1037 *pp_sids = group_sids;
1039 *p_num_groups = num_groups;
1040 return NT_STATUS_OK;
1043 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
1044 TALLOC_CTX *mem_ctx,
1047 return NT_STATUS_NOT_IMPLEMENTED;
1050 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
1051 TALLOC_CTX *mem_ctx,
1052 uint32 grouprid, uint32 memberrid,
1055 struct pdb_ads_state *state = talloc_get_type_abort(
1056 m->private_data, struct pdb_ads_state);
1057 TALLOC_CTX *frame = talloc_stackframe();
1058 struct tldap_context *ld;
1059 struct dom_sid groupsid, membersid;
1060 char *groupdn, *memberdn;
1061 struct tldap_mod *mods;
1065 ld = pdb_ads_ld(state);
1067 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1070 sid_compose(&groupsid, &state->domainsid, grouprid);
1071 sid_compose(&membersid, &state->domainsid, memberrid);
1073 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
1074 if (!NT_STATUS_IS_OK(status)) {
1076 return NT_STATUS_NO_SUCH_GROUP;
1078 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
1079 if (!NT_STATUS_IS_OK(status)) {
1081 return NT_STATUS_NO_SUCH_USER;
1086 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1087 "member", memberdn)) {
1089 return NT_STATUS_NO_MEMORY;
1092 rc = tldap_modify(ld, groupdn, 1, mods, NULL, 0, NULL, 0);
1094 if (rc != TLDAP_SUCCESS) {
1095 DEBUG(10, ("ldap_modify failed: %s\n",
1096 tldap_errstr(talloc_tos(), state->ld, rc)));
1097 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1098 return NT_STATUS_MEMBER_IN_GROUP;
1100 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1101 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1103 return NT_STATUS_LDAP(rc);
1106 return NT_STATUS_OK;
1109 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
1110 TALLOC_CTX *mem_ctx,
1111 uint32 group_rid, uint32 member_rid)
1113 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1117 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
1118 TALLOC_CTX *mem_ctx,
1119 uint32 group_rid, uint32 member_rid)
1121 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1125 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
1126 const char *name, uint32 *rid)
1128 TALLOC_CTX *frame = talloc_stackframe();
1129 struct pdb_ads_state *state = talloc_get_type_abort(
1130 m->private_data, struct pdb_ads_state);
1131 struct tldap_context *ld;
1132 const char *attrs[1] = { "objectSid" };
1134 struct tldap_mod *mods = NULL;
1135 struct tldap_message **alias;
1141 ld = pdb_ads_ld(state);
1143 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1146 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1150 return NT_STATUS_NO_MEMORY;
1153 ok &= tldap_make_mod_fmt(
1154 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
1156 ok &= tldap_make_mod_fmt(
1157 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
1158 ok &= tldap_make_mod_fmt(
1159 NULL, talloc_tos(), &num_mods, &mods, "groupType",
1160 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1164 return NT_STATUS_NO_MEMORY;
1167 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1168 if (rc != TLDAP_SUCCESS) {
1169 DEBUG(10, ("ldap_add failed %s\n",
1170 tldap_errstr(talloc_tos(), state->ld, rc)));
1172 return NT_STATUS_LDAP(rc);
1175 rc = pdb_ads_search_fmt(
1176 state, state->domaindn, TLDAP_SCOPE_SUB,
1177 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1178 "(&(objectclass=group)(samaccountname=%s))", name);
1179 if (rc != TLDAP_SUCCESS) {
1180 DEBUG(10, ("Could not find just created alias %s: %s\n",
1181 name, tldap_errstr(talloc_tos(), state->ld, rc)));
1183 return NT_STATUS_LDAP(rc);
1186 if (talloc_array_length(alias) != 1) {
1187 DEBUG(10, ("Got %d alias, expected one\n",
1188 (int)talloc_array_length(alias)));
1190 return NT_STATUS_LDAP(rc);
1193 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1194 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1197 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1200 sid_peek_rid(&sid, rid);
1202 return NT_STATUS_OK;
1205 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1206 const struct dom_sid *sid)
1208 struct pdb_ads_state *state = talloc_get_type_abort(
1209 m->private_data, struct pdb_ads_state);
1210 struct tldap_context *ld;
1211 struct tldap_message **alias;
1212 char *sidstr, *dn = NULL;
1215 ld = pdb_ads_ld(state);
1217 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1220 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1221 if (sidstr == NULL) {
1222 return NT_STATUS_NO_MEMORY;
1225 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1226 NULL, 0, 0, talloc_tos(), &alias,
1227 "(&(objectSid=%s)(objectclass=group)"
1228 "(|(grouptype=%d)(grouptype=%d)))",
1229 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1230 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1231 TALLOC_FREE(sidstr);
1232 if (rc != TLDAP_SUCCESS) {
1233 DEBUG(10, ("ldap_search failed: %s\n",
1234 tldap_errstr(talloc_tos(), state->ld, rc)));
1235 return NT_STATUS_LDAP(rc);
1237 if (talloc_array_length(alias) != 1) {
1238 DEBUG(10, ("Expected 1 alias, got %d\n",
1239 (int)talloc_array_length(alias)));
1240 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1242 if (!tldap_entry_dn(alias[0], &dn)) {
1243 DEBUG(10, ("Could not get DN for alias %s\n",
1244 sid_string_dbg(sid)));
1245 return NT_STATUS_INTERNAL_ERROR;
1248 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
1249 if (rc != TLDAP_SUCCESS) {
1250 DEBUG(10, ("ldap_delete failed: %s\n",
1251 tldap_errstr(talloc_tos(), state->ld, rc)));
1252 return NT_STATUS_LDAP(rc);
1255 return NT_STATUS_OK;
1258 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1259 const struct dom_sid *sid,
1260 struct acct_info *info)
1262 struct pdb_ads_state *state = talloc_get_type_abort(
1263 m->private_data, struct pdb_ads_state);
1264 struct tldap_context *ld;
1265 const char *attrs[3] = { "objectSid", "description",
1267 struct tldap_message **msg;
1270 struct tldap_mod *mods;
1274 ld = pdb_ads_ld(state);
1276 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1279 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1280 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1282 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1283 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1284 &msg, "(&(objectSid=%s)(objectclass=group)"
1285 "(|(grouptype=%d)(grouptype=%d)))",
1286 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1287 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1288 TALLOC_FREE(sidstr);
1289 if (rc != TLDAP_SUCCESS) {
1290 DEBUG(10, ("ldap_search failed %s\n",
1291 tldap_errstr(talloc_tos(), state->ld, rc)));
1292 return NT_STATUS_LDAP(rc);
1294 switch talloc_array_length(msg) {
1296 return NT_STATUS_NO_SUCH_ALIAS;
1300 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1303 if (!tldap_entry_dn(msg[0], &dn)) {
1305 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1312 ok &= tldap_make_mod_fmt(
1313 msg[0], msg, &num_mods, &mods, "description",
1314 "%s", info->acct_desc);
1315 ok &= tldap_make_mod_fmt(
1316 msg[0], msg, &num_mods, &mods, "samAccountName",
1317 "%s", info->acct_name);
1320 return NT_STATUS_NO_MEMORY;
1322 if (num_mods == 0) {
1325 return NT_STATUS_OK;
1328 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1330 if (rc != TLDAP_SUCCESS) {
1331 DEBUG(10, ("ldap_modify failed: %s\n",
1332 tldap_errstr(talloc_tos(), state->ld, rc)));
1333 return NT_STATUS_LDAP(rc);
1335 return NT_STATUS_OK;
1338 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1339 const struct dom_sid *sid,
1340 TALLOC_CTX *mem_ctx, char **pdn)
1342 struct tldap_message **msg;
1346 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1347 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1349 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1350 NULL, 0, 0, talloc_tos(), &msg,
1351 "(objectsid=%s)", sidstr);
1352 TALLOC_FREE(sidstr);
1353 if (rc != TLDAP_SUCCESS) {
1354 DEBUG(10, ("ldap_search failed %s\n",
1355 tldap_errstr(talloc_tos(), state->ld, rc)));
1356 return NT_STATUS_LDAP(rc);
1359 switch talloc_array_length(msg) {
1361 return NT_STATUS_NOT_FOUND;
1365 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1368 if (!tldap_entry_dn(msg[0], &dn)) {
1369 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1372 dn = talloc_strdup(mem_ctx, dn);
1374 return NT_STATUS_NO_MEMORY;
1379 return NT_STATUS_OK;
1382 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1383 const struct dom_sid *alias,
1384 const struct dom_sid *member,
1387 struct pdb_ads_state *state = talloc_get_type_abort(
1388 m->private_data, struct pdb_ads_state);
1389 struct tldap_context *ld;
1390 TALLOC_CTX *frame = talloc_stackframe();
1391 struct tldap_mod *mods;
1393 char *aliasdn, *memberdn;
1396 ld = pdb_ads_ld(state);
1398 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1401 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1402 if (!NT_STATUS_IS_OK(status)) {
1403 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1404 sid_string_dbg(alias), nt_errstr(status)));
1406 return NT_STATUS_NO_SUCH_ALIAS;
1408 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1409 if (!NT_STATUS_IS_OK(status)) {
1410 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1411 sid_string_dbg(member), nt_errstr(status)));
1418 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1419 "member", memberdn)) {
1421 return NT_STATUS_NO_MEMORY;
1424 rc = tldap_modify(ld, aliasdn, 1, mods, NULL, 0, NULL, 0);
1426 if (rc != TLDAP_SUCCESS) {
1427 DEBUG(10, ("ldap_modify failed: %s\n",
1428 tldap_errstr(talloc_tos(), state->ld, rc)));
1429 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1430 return NT_STATUS_MEMBER_IN_ALIAS;
1432 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1433 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1435 return NT_STATUS_LDAP(rc);
1438 return NT_STATUS_OK;
1441 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1442 const struct dom_sid *alias,
1443 const struct dom_sid *member)
1445 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1448 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1449 const struct dom_sid *alias,
1450 const struct dom_sid *member)
1452 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1455 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
1456 struct dom_sid *psid)
1458 const char *attrs[1] = { "objectSid" };
1459 struct tldap_message **msg;
1465 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1466 dnblob->data, dnblob->length, &dn, &len,
1470 rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
1471 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1472 &msg, "(objectclass=*)");
1474 if (talloc_array_length(msg) != 1) {
1475 DEBUG(10, ("Got %d objects, expected one\n",
1476 (int)talloc_array_length(msg)));
1481 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1486 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1487 const struct dom_sid *alias,
1488 TALLOC_CTX *mem_ctx,
1489 struct dom_sid **pmembers,
1490 size_t *pnum_members)
1492 struct pdb_ads_state *state = talloc_get_type_abort(
1493 m->private_data, struct pdb_ads_state);
1494 const char *attrs[1] = { "member" };
1496 struct tldap_message **msg;
1497 int i, rc, num_members;
1499 struct dom_sid *members;
1501 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), alias);
1502 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1504 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1505 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1506 &msg, "(objectsid=%s)", sidstr);
1507 TALLOC_FREE(sidstr);
1508 if (rc != TLDAP_SUCCESS) {
1509 DEBUG(10, ("ldap_search failed %s\n",
1510 tldap_errstr(talloc_tos(), state->ld, rc)));
1511 return NT_STATUS_LDAP(rc);
1513 switch talloc_array_length(msg) {
1515 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1520 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1524 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1525 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1528 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1529 if (members == NULL) {
1530 return NT_STATUS_NO_MEMORY;
1533 for (i=0; i<num_members; i++) {
1534 if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
1535 TALLOC_FREE(members);
1536 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1540 *pmembers = members;
1541 *pnum_members = num_members;
1542 return NT_STATUS_OK;
1545 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1546 TALLOC_CTX *mem_ctx,
1547 const struct dom_sid *domain_sid,
1548 const struct dom_sid *members,
1550 uint32_t **palias_rids,
1551 size_t *pnum_alias_rids)
1553 struct pdb_ads_state *state = talloc_get_type_abort(
1554 m->private_data, struct pdb_ads_state);
1555 const char *attrs[1] = { "objectSid" };
1556 struct tldap_message **msg = NULL;
1557 uint32_t *alias_rids = NULL;
1558 size_t num_alias_rids = 0;
1560 bool got_members = false;
1565 * TODO: Get the filter right so that we only get the aliases from
1566 * either the SAM or BUILTIN
1569 filter = talloc_asprintf(talloc_tos(),
1570 "(&(|(grouptype=%d)(grouptype=%d))"
1571 "(objectclass=group)(|",
1572 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1573 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1574 if (filter == NULL) {
1575 return NT_STATUS_NO_MEMORY;
1578 for (i=0; i<num_members; i++) {
1581 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1582 if (!NT_STATUS_IS_OK(status)) {
1583 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1584 sid_string_dbg(&members[i]),
1585 nt_errstr(status)));
1588 filter = talloc_asprintf_append_buffer(
1589 filter, "(member=%s)", dn);
1591 if (filter == NULL) {
1592 return NT_STATUS_NO_MEMORY;
1601 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1602 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1603 &msg, "%s))", filter);
1604 TALLOC_FREE(filter);
1605 if (rc != TLDAP_SUCCESS) {
1606 DEBUG(10, ("tldap_search failed %s\n",
1607 tldap_errstr(talloc_tos(), state->ld, rc)));
1608 return NT_STATUS_LDAP(rc);
1611 count = talloc_array_length(msg);
1616 alias_rids = talloc_array(mem_ctx, uint32_t, count);
1617 if (alias_rids == NULL) {
1619 return NT_STATUS_NO_MEMORY;
1622 for (i=0; i<count; i++) {
1625 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1626 DEBUG(10, ("Could not pull SID for member %d\n", i));
1629 if (sid_peek_check_rid(domain_sid, &sid,
1630 &alias_rids[num_alias_rids])) {
1631 num_alias_rids += 1;
1636 *palias_rids = alias_rids;
1637 *pnum_alias_rids = 0;
1638 return NT_STATUS_OK;
1641 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1642 const struct dom_sid *domain_sid,
1646 enum lsa_SidType *lsa_attrs)
1648 struct pdb_ads_state *state = talloc_get_type_abort(
1649 m->private_data, struct pdb_ads_state);
1650 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1653 if (num_rids == 0) {
1654 return NT_STATUS_NONE_MAPPED;
1659 for (i=0; i<num_rids; i++) {
1661 struct tldap_message **msg;
1666 lsa_attrs[i] = SID_NAME_UNKNOWN;
1668 sid_compose(&sid, domain_sid, rids[i]);
1670 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
1671 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1673 rc = pdb_ads_search_fmt(state, state->domaindn,
1674 TLDAP_SCOPE_SUB, attrs,
1675 ARRAY_SIZE(attrs), 0, talloc_tos(),
1676 &msg, "(objectsid=%s)", sidstr);
1677 TALLOC_FREE(sidstr);
1678 if (rc != TLDAP_SUCCESS) {
1679 DEBUG(10, ("ldap_search failed %s\n",
1680 tldap_errstr(talloc_tos(), state->ld, rc)));
1684 switch talloc_array_length(msg) {
1686 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1691 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1694 names[i] = tldap_talloc_single_attribute(
1695 msg[0], "samAccountName", talloc_tos());
1696 if (names[i] == NULL) {
1697 DEBUG(10, ("no samAccountName\n"));
1700 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1701 DEBUG(10, ("no samAccountType"));
1704 lsa_attrs[i] = ds_atype_map(attr);
1708 if (num_mapped == 0) {
1709 return NT_STATUS_NONE_MAPPED;
1711 if (num_mapped < num_rids) {
1712 return STATUS_SOME_UNMAPPED;
1714 return NT_STATUS_OK;
1717 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1718 const struct dom_sid *domain_sid,
1720 const char **pp_names,
1722 enum lsa_SidType *attrs)
1724 return NT_STATUS_NOT_IMPLEMENTED;
1727 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1728 enum pdb_policy_type type,
1731 return account_policy_get(type, value)
1732 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1735 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1736 enum pdb_policy_type type,
1739 return account_policy_set(type, value)
1740 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1743 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1746 return NT_STATUS_NOT_IMPLEMENTED;
1749 struct pdb_ads_search_state {
1750 uint32_t acct_flags;
1751 struct samr_displayentry *entries;
1752 uint32_t num_entries;
1757 static bool pdb_ads_next_entry(struct pdb_search *search,
1758 struct samr_displayentry *entry)
1760 struct pdb_ads_search_state *state = talloc_get_type_abort(
1761 search->private_data, struct pdb_ads_search_state);
1763 if (state->current == state->num_entries) {
1767 entry->idx = state->entries[state->current].idx;
1768 entry->rid = state->entries[state->current].rid;
1769 entry->acct_flags = state->entries[state->current].acct_flags;
1771 entry->account_name = talloc_strdup(
1772 search, state->entries[state->current].account_name);
1773 entry->fullname = talloc_strdup(
1774 search, state->entries[state->current].fullname);
1775 entry->description = talloc_strdup(
1776 search, state->entries[state->current].description);
1778 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1779 || (entry->description == NULL)) {
1780 DEBUG(0, ("talloc_strdup failed\n"));
1784 state->current += 1;
1788 static void pdb_ads_search_end(struct pdb_search *search)
1790 struct pdb_ads_search_state *state = talloc_get_type_abort(
1791 search->private_data, struct pdb_ads_search_state);
1795 static bool pdb_ads_search_filter(struct pdb_methods *m,
1796 struct pdb_search *search,
1798 struct pdb_ads_search_state **pstate)
1800 struct pdb_ads_state *state = talloc_get_type_abort(
1801 m->private_data, struct pdb_ads_state);
1802 struct pdb_ads_search_state *sstate;
1803 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1804 "userAccountControl", "description" };
1805 struct tldap_message **users;
1806 int i, rc, num_users;
1808 sstate = talloc_zero(search, struct pdb_ads_search_state);
1809 if (sstate == NULL) {
1813 rc = pdb_ads_search_fmt(
1814 state, state->domaindn, TLDAP_SCOPE_SUB,
1815 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1817 if (rc != TLDAP_SUCCESS) {
1818 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1819 tldap_errstr(talloc_tos(), state->ld, rc)));
1823 num_users = talloc_array_length(users);
1825 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1827 if (sstate->entries == NULL) {
1828 DEBUG(10, ("talloc failed\n"));
1832 sstate->num_entries = 0;
1834 for (i=0; i<num_users; i++) {
1835 struct samr_displayentry *e;
1838 e = &sstate->entries[sstate->num_entries];
1840 e->idx = sstate->num_entries;
1841 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1842 DEBUG(10, ("Could not pull sid\n"));
1845 sid_peek_rid(&sid, &e->rid);
1846 e->acct_flags = ACB_NORMAL;
1847 e->account_name = tldap_talloc_single_attribute(
1848 users[i], "samAccountName", sstate->entries);
1849 if (e->account_name == NULL) {
1852 e->fullname = tldap_talloc_single_attribute(
1853 users[i], "displayName", sstate->entries);
1854 if (e->fullname == NULL) {
1857 e->description = tldap_talloc_single_attribute(
1858 users[i], "description", sstate->entries);
1859 if (e->description == NULL) {
1860 e->description = "";
1863 sstate->num_entries += 1;
1864 if (sstate->num_entries >= num_users) {
1869 search->private_data = sstate;
1870 search->next_entry = pdb_ads_next_entry;
1871 search->search_end = pdb_ads_search_end;
1876 static bool pdb_ads_search_users(struct pdb_methods *m,
1877 struct pdb_search *search,
1880 struct pdb_ads_search_state *sstate;
1883 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1887 sstate->acct_flags = acct_flags;
1891 static bool pdb_ads_search_groups(struct pdb_methods *m,
1892 struct pdb_search *search)
1894 struct pdb_ads_search_state *sstate;
1898 filter = talloc_asprintf(talloc_tos(),
1899 "(&(grouptype=%d)(objectclass=group))",
1900 GTYPE_SECURITY_GLOBAL_GROUP);
1901 if (filter == NULL) {
1904 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1905 TALLOC_FREE(filter);
1909 sstate->acct_flags = 0;
1913 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1914 struct pdb_search *search,
1915 const struct dom_sid *sid)
1917 struct pdb_ads_search_state *sstate;
1921 filter = talloc_asprintf(
1922 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1923 sid_check_is_builtin(sid)
1924 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1925 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1927 if (filter == NULL) {
1930 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1931 TALLOC_FREE(filter);
1935 sstate->acct_flags = 0;
1939 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1940 struct dom_sid *sid)
1942 struct pdb_ads_state *state = talloc_get_type_abort(
1943 m->private_data, struct pdb_ads_state);
1944 sid_compose(sid, &state->domainsid, uid);
1948 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1949 struct dom_sid *sid)
1951 struct pdb_ads_state *state = talloc_get_type_abort(
1952 m->private_data, struct pdb_ads_state);
1953 sid_compose(sid, &state->domainsid, gid);
1957 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
1958 union unid_t *id, enum lsa_SidType *type)
1960 struct pdb_ads_state *state = talloc_get_type_abort(
1961 m->private_data, struct pdb_ads_state);
1962 struct tldap_message **msg;
1968 * This is a big, big hack: Just hard-code the rid as uid/gid.
1971 sid_peek_rid(sid, &rid);
1973 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1974 if (sidstr == NULL) {
1978 rc = pdb_ads_search_fmt(
1979 state, state->domaindn, TLDAP_SCOPE_SUB,
1980 NULL, 0, 0, talloc_tos(), &msg,
1981 "(&(objectsid=%s)(objectclass=user))", sidstr);
1982 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1984 *type = SID_NAME_USER;
1985 TALLOC_FREE(sidstr);
1989 rc = pdb_ads_search_fmt(
1990 state, state->domaindn, TLDAP_SCOPE_SUB,
1991 NULL, 0, 0, talloc_tos(), &msg,
1992 "(&(objectsid=%s)(objectclass=group))", sidstr);
1993 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1995 *type = SID_NAME_DOM_GRP;
1996 TALLOC_FREE(sidstr);
2000 TALLOC_FREE(sidstr);
2004 static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
2006 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2009 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
2014 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
2015 const char *domain, char** pwd,
2016 struct dom_sid *sid,
2017 time_t *pass_last_set_time)
2022 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
2023 const char* domain, const char* pwd,
2024 const struct dom_sid *sid)
2029 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
2035 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
2036 TALLOC_CTX *mem_ctx,
2037 uint32 *num_domains,
2038 struct trustdom_info ***domains)
2042 return NT_STATUS_OK;
2045 static void pdb_ads_init_methods(struct pdb_methods *m)
2048 m->get_domain_info = pdb_ads_get_domain_info;
2049 m->getsampwnam = pdb_ads_getsampwnam;
2050 m->getsampwsid = pdb_ads_getsampwsid;
2051 m->create_user = pdb_ads_create_user;
2052 m->delete_user = pdb_ads_delete_user;
2053 m->add_sam_account = pdb_ads_add_sam_account;
2054 m->update_sam_account = pdb_ads_update_sam_account;
2055 m->delete_sam_account = pdb_ads_delete_sam_account;
2056 m->rename_sam_account = pdb_ads_rename_sam_account;
2057 m->update_login_attempts = pdb_ads_update_login_attempts;
2058 m->getgrsid = pdb_ads_getgrsid;
2059 m->getgrgid = pdb_ads_getgrgid;
2060 m->getgrnam = pdb_ads_getgrnam;
2061 m->create_dom_group = pdb_ads_create_dom_group;
2062 m->delete_dom_group = pdb_ads_delete_dom_group;
2063 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
2064 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
2065 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
2066 m->enum_group_mapping = pdb_ads_enum_group_mapping;
2067 m->enum_group_members = pdb_ads_enum_group_members;
2068 m->enum_group_memberships = pdb_ads_enum_group_memberships;
2069 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
2070 m->add_groupmem = pdb_ads_add_groupmem;
2071 m->del_groupmem = pdb_ads_del_groupmem;
2072 m->create_alias = pdb_ads_create_alias;
2073 m->delete_alias = pdb_ads_delete_alias;
2074 m->get_aliasinfo = pdb_default_get_aliasinfo;
2075 m->set_aliasinfo = pdb_ads_set_aliasinfo;
2076 m->add_aliasmem = pdb_ads_add_aliasmem;
2077 m->del_aliasmem = pdb_ads_del_aliasmem;
2078 m->enum_aliasmem = pdb_ads_enum_aliasmem;
2079 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
2080 m->lookup_rids = pdb_ads_lookup_rids;
2081 m->lookup_names = pdb_ads_lookup_names;
2082 m->get_account_policy = pdb_ads_get_account_policy;
2083 m->set_account_policy = pdb_ads_set_account_policy;
2084 m->get_seq_num = pdb_ads_get_seq_num;
2085 m->search_users = pdb_ads_search_users;
2086 m->search_groups = pdb_ads_search_groups;
2087 m->search_aliases = pdb_ads_search_aliases;
2088 m->uid_to_sid = pdb_ads_uid_to_sid;
2089 m->gid_to_sid = pdb_ads_gid_to_sid;
2090 m->sid_to_id = pdb_ads_sid_to_id;
2091 m->capabilities = pdb_ads_capabilities;
2092 m->new_rid = pdb_ads_new_rid;
2093 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2094 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2095 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2096 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2099 static void free_private_data(void **vp)
2101 struct pdb_ads_state *state = talloc_get_type_abort(
2102 *vp, struct pdb_ads_state);
2104 TALLOC_FREE(state->ld);
2109 this is used to catch debug messages from events
2111 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2112 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
2114 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2115 const char *fmt, va_list ap)
2117 int samba_level = -1;
2120 case TLDAP_DEBUG_FATAL:
2123 case TLDAP_DEBUG_ERROR:
2126 case TLDAP_DEBUG_WARNING:
2129 case TLDAP_DEBUG_TRACE:
2134 if (vasprintf(&s, fmt, ap) == -1) {
2137 DEBUG(samba_level, ("tldap: %s", s));
2141 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2146 if (tldap_connection_ok(state->ld)) {
2149 TALLOC_FREE(state->ld);
2151 status = open_socket_out(
2152 (struct sockaddr_storage *)(void *)&state->socket_address,
2154 if (!NT_STATUS_IS_OK(status)) {
2155 DEBUG(10, ("Could not connect to %s: %s\n",
2156 state->socket_address.sun_path, nt_errstr(status)));
2160 set_blocking(fd, false);
2162 state->ld = tldap_context_create(state, fd);
2163 if (state->ld == NULL) {
2167 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2172 int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2173 int scope, const char *attrs[], int num_attrs,
2175 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2176 const char *fmt, ...)
2178 struct tldap_context *ld;
2182 ld = pdb_ads_ld(state);
2184 return TLDAP_SERVER_DOWN;
2188 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2189 mem_ctx, res, fmt, ap);
2192 if (ret != TLDAP_SERVER_DOWN) {
2197 ld = pdb_ads_ld(state);
2199 return TLDAP_SERVER_DOWN;
2203 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2204 mem_ctx, res, fmt, ap);
2209 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2210 const char *location)
2212 const char *domain_attrs[2] = { "objectSid", "objectGUID" };
2213 const char *ncname_attrs[1] = { "netbiosname" };
2214 struct tldap_context *ld;
2215 struct tldap_message *rootdse, **domain, **ncname;
2216 TALLOC_CTX *frame = talloc_stackframe();
2221 ZERO_STRUCT(state->socket_address);
2222 state->socket_address.sun_family = AF_UNIX;
2223 strlcpy(state->socket_address.sun_path, location,
2224 sizeof(state->socket_address.sun_path));
2226 ld = pdb_ads_ld(state);
2228 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2232 rc = tldap_fetch_rootdse(ld);
2233 if (rc != TLDAP_SUCCESS) {
2234 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2235 tldap_errstr(talloc_tos(), state->ld, rc)));
2236 status = NT_STATUS_LDAP(rc);
2239 rootdse = tldap_rootdse(state->ld);
2241 state->domaindn = tldap_talloc_single_attribute(
2242 rootdse, "defaultNamingContext", state);
2243 if (state->domaindn == NULL) {
2244 DEBUG(10, ("Could not get defaultNamingContext\n"));
2245 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2248 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2250 state->configdn = tldap_talloc_single_attribute(
2251 rootdse, "configurationNamingContext", state);
2252 if (state->domaindn == NULL) {
2253 DEBUG(10, ("Could not get configurationNamingContext\n"));
2254 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2257 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2260 * Figure out our domain's SID
2262 rc = pdb_ads_search_fmt(
2263 state, state->domaindn, TLDAP_SCOPE_BASE,
2264 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2265 talloc_tos(), &domain, "(objectclass=*)");
2266 if (rc != TLDAP_SUCCESS) {
2267 DEBUG(10, ("Could not retrieve domain: %s\n",
2268 tldap_errstr(talloc_tos(), state->ld, rc)));
2269 status = NT_STATUS_LDAP(rc);
2273 num_domains = talloc_array_length(domain);
2274 if (num_domains != 1) {
2275 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2276 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2279 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2280 DEBUG(10, ("Could not retrieve domain SID\n"));
2281 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2284 if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) {
2285 DEBUG(10, ("Could not retrieve domain GUID\n"));
2286 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2289 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2292 * Figure out our domain's short name
2294 rc = pdb_ads_search_fmt(
2295 state, state->configdn, TLDAP_SCOPE_SUB,
2296 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2297 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2298 if (rc != TLDAP_SUCCESS) {
2299 DEBUG(10, ("Could not retrieve ncname: %s\n",
2300 tldap_errstr(talloc_tos(), state->ld, rc)));
2301 status = NT_STATUS_LDAP(rc);
2304 if (talloc_array_length(ncname) != 1) {
2305 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2309 state->netbiosname = tldap_talloc_single_attribute(
2310 ncname[0], "netbiosname", state);
2311 if (state->netbiosname == NULL) {
2312 DEBUG(10, ("Could not get netbiosname\n"));
2313 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2316 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2318 if (!strequal(lp_workgroup(), state->netbiosname)) {
2319 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2320 state->netbiosname, lp_workgroup()));
2321 status = NT_STATUS_NO_SUCH_DOMAIN;
2325 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2327 status = NT_STATUS_OK;
2333 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2334 const char *location)
2336 struct pdb_methods *m;
2337 struct pdb_ads_state *state;
2341 m = talloc(NULL, struct pdb_methods);
2343 return NT_STATUS_NO_MEMORY;
2345 state = talloc_zero(m, struct pdb_ads_state);
2346 if (state == NULL) {
2349 m->private_data = state;
2350 m->free_private_data = free_private_data;
2351 pdb_ads_init_methods(m);
2353 if (location == NULL) {
2354 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2358 if (location == NULL) {
2362 status = pdb_ads_connect(state, location);
2363 if (!NT_STATUS_IS_OK(status)) {
2364 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2369 return NT_STATUS_OK;
2371 status = NT_STATUS_NO_MEMORY;
2377 NTSTATUS pdb_ads_init(void);
2378 NTSTATUS pdb_ads_init(void)
2380 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",