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 bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
46 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
47 struct dom_sid *psid);
48 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
49 const struct dom_sid *sid,
50 TALLOC_CTX *mem_ctx, char **pdn);
51 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state);
52 static int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
53 int scope, const char *attrs[], int num_attrs,
55 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
56 const char *fmt, ...);
57 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
60 struct pdb_ads_samu_private **presult);
62 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
67 if (!tldap_pull_uint64(msg, attr, &tmp)) {
70 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
74 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
77 sid_peek_rid(sid, &rid);
81 static char *pdb_ads_domaindn2dns(TALLOC_CTX *mem_ctx, char *dn)
85 result = talloc_string_sub2(mem_ctx, dn, "DC=", "", false, false,
91 while ((p = strchr_m(result, ',')) != NULL) {
98 static struct pdb_domain_info *pdb_ads_get_domain_info(
99 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
101 struct pdb_ads_state *state = talloc_get_type_abort(
102 m->private_data, struct pdb_ads_state);
103 struct pdb_domain_info *info;
104 struct tldap_message *rootdse;
107 info = talloc(mem_ctx, struct pdb_domain_info);
111 info->name = talloc_strdup(info, state->netbiosname);
112 if (info->name == NULL) {
115 info->dns_domain = pdb_ads_domaindn2dns(info, state->domaindn);
116 if (info->dns_domain == NULL) {
120 rootdse = tldap_rootdse(state->ld);
121 tmp = tldap_talloc_single_attribute(rootdse, "rootDomainNamingContext",
126 info->dns_forest = pdb_ads_domaindn2dns(info, tmp);
128 if (info->dns_forest == NULL) {
131 info->sid = state->domainsid;
132 info->guid = state->domainguid;
140 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
141 struct pdb_methods *m, struct samu *sam)
143 struct pdb_ads_state *state = talloc_get_type_abort(
144 m->private_data, struct pdb_ads_state);
145 struct pdb_ads_samu_private *result;
146 char *sidstr, *filter;
149 result = (struct pdb_ads_samu_private *)
150 pdb_get_backend_private_data(sam, m);
152 if (result != NULL) {
153 return talloc_get_type_abort(
154 result, struct pdb_ads_samu_private);
157 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), pdb_get_user_sid(sam));
158 if (sidstr == NULL) {
162 filter = talloc_asprintf(
163 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
165 if (filter == NULL) {
169 status = pdb_ads_getsamupriv(state, filter, sam, &result);
171 if (!NT_STATUS_IS_OK(status)) {
178 static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m,
180 struct pdb_ads_samu_private *priv)
182 struct pdb_ads_state *state = talloc_get_type_abort(
183 m->private_data, struct pdb_ads_state);
184 TALLOC_CTX *frame = talloc_stackframe();
185 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
186 struct tldap_message *entry = priv->ldapmsg;
194 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
196 DEBUG(10, ("no samAccountName\n"));
199 pdb_set_username(sam, str, PDB_SET);
201 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
202 pdb_set_logon_time(sam, tmp_time, PDB_SET);
204 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
205 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
207 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
208 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
210 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
211 pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
214 str = tldap_talloc_single_attribute(entry, "displayName",
217 pdb_set_fullname(sam, str, PDB_SET);
220 str = tldap_talloc_single_attribute(entry, "homeDirectory",
223 pdb_set_homedir(sam, str, PDB_SET);
226 str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
228 pdb_set_dir_drive(sam, str, PDB_SET);
231 str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
233 pdb_set_logon_script(sam, str, PDB_SET);
236 str = tldap_talloc_single_attribute(entry, "profilePath",
239 pdb_set_profile_path(sam, str, PDB_SET);
242 str = tldap_talloc_single_attribute(entry, "profilePath",
245 pdb_set_profile_path(sam, str, PDB_SET);
248 str = tldap_talloc_single_attribute(entry, "comment",
251 pdb_set_comment(sam, str, PDB_SET);
254 str = tldap_talloc_single_attribute(entry, "description",
257 pdb_set_acct_desc(sam, str, PDB_SET);
260 str = tldap_talloc_single_attribute(entry, "userWorkstations",
263 pdb_set_workstations(sam, str, PDB_SET);
266 str = tldap_talloc_single_attribute(entry, "userParameters",
269 pdb_set_munged_dial(sam, str, PDB_SET);
272 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
273 DEBUG(10, ("Could not pull SID\n"));
276 pdb_set_user_sid(sam, &sid, PDB_SET);
278 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
279 DEBUG(10, ("Could not pull userAccountControl\n"));
282 pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
284 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
285 if (blob.length != NT_HASH_LEN) {
286 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
287 (int)blob.length, NT_HASH_LEN));
290 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
293 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
294 if (blob.length != LM_HASH_LEN) {
295 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
296 (int)blob.length, LM_HASH_LEN));
299 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
302 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
303 sid_compose(&sid, &state->domainsid, n);
304 pdb_set_group_sid(sam, &sid, PDB_SET);
308 if (tldap_pull_uint32(entry, "countryCode", &i)) {
309 pdb_set_country_code(sam, i, PDB_SET);
312 status = NT_STATUS_OK;
318 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
319 struct tldap_message *existing,
321 struct tldap_mod **pmods, int *pnum_mods,
328 /* TODO: All fields :-) */
330 ret &= tldap_make_mod_fmt(
331 existing, mem_ctx, pmods, pnum_mods, "displayName",
332 "%s", pdb_get_fullname(sam));
334 pw = pdb_get_plaintext_passwd(sam);
337 * If we have the plain text pw, this is probably about to be
338 * set. Is this true always?
345 pw_quote = talloc_asprintf(talloc_tos(), "\"%s\"", pw);
346 if (pw_quote == NULL) {
351 ret &= convert_string_talloc(talloc_tos(),
353 pw_quote, strlen(pw_quote),
354 &pw_utf16, &pw_utf16_len, false);
358 blob = data_blob_const(pw_utf16, pw_utf16_len);
360 ret &= tldap_add_mod_blobs(mem_ctx, pmods, pnum_mods,
362 "unicodePwd", &blob, 1);
363 TALLOC_FREE(pw_utf16);
364 TALLOC_FREE(pw_quote);
367 ret &= tldap_make_mod_fmt(
368 existing, mem_ctx, pmods, pnum_mods, "userAccountControl",
369 "%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
371 ret &= tldap_make_mod_fmt(
372 existing, mem_ctx, pmods, pnum_mods, "homeDirectory",
373 "%s", pdb_get_homedir(sam));
375 ret &= tldap_make_mod_fmt(
376 existing, mem_ctx, pmods, pnum_mods, "homeDrive",
377 "%s", pdb_get_dir_drive(sam));
379 ret &= tldap_make_mod_fmt(
380 existing, mem_ctx, pmods, pnum_mods, "scriptPath",
381 "%s", pdb_get_logon_script(sam));
383 ret &= tldap_make_mod_fmt(
384 existing, mem_ctx, pmods, pnum_mods, "profilePath",
385 "%s", pdb_get_profile_path(sam));
387 ret &= tldap_make_mod_fmt(
388 existing, mem_ctx, pmods, pnum_mods, "comment",
389 "%s", pdb_get_comment(sam));
391 ret &= tldap_make_mod_fmt(
392 existing, mem_ctx, pmods, pnum_mods, "description",
393 "%s", pdb_get_acct_desc(sam));
395 ret &= tldap_make_mod_fmt(
396 existing, mem_ctx, pmods, pnum_mods, "userWorkstations",
397 "%s", pdb_get_workstations(sam));
399 ret &= tldap_make_mod_fmt(
400 existing, mem_ctx, pmods, pnum_mods, "userParameters",
401 "%s", pdb_get_munged_dial(sam));
403 ret &= tldap_make_mod_fmt(
404 existing, mem_ctx, pmods, pnum_mods, "countryCode",
405 "%i", (int)pdb_get_country_code(sam));
411 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
414 struct pdb_ads_samu_private **presult)
416 const char * attrs[] = {
417 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
418 "sAMAccountName", "displayName", "homeDirectory",
419 "homeDrive", "scriptPath", "profilePath", "description",
420 "userWorkstations", "comment", "userParameters", "objectSid",
421 "primaryGroupID", "userAccountControl", "logonHours",
422 "badPwdCount", "logonCount", "countryCode", "codePage",
423 "unicodePwd", "dBCSPwd" };
424 struct tldap_message **users;
426 struct pdb_ads_samu_private *result;
428 result = talloc(mem_ctx, struct pdb_ads_samu_private);
429 if (result == NULL) {
430 return NT_STATUS_NO_MEMORY;
433 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
434 attrs, ARRAY_SIZE(attrs), 0, result,
435 &users, "%s", filter);
436 if (rc != TLDAP_SUCCESS) {
437 DEBUG(10, ("ldap_search failed %s\n",
438 tldap_errstr(talloc_tos(), state->ld, rc)));
440 return NT_STATUS_LDAP(rc);
443 count = talloc_array_length(users);
445 DEBUG(10, ("Expected 1 user, got %d\n", count));
447 return NT_STATUS_INTERNAL_DB_CORRUPTION;
450 result->ldapmsg = users[0];
451 if (!tldap_entry_dn(result->ldapmsg, &result->dn)) {
452 DEBUG(10, ("Could not extract dn\n"));
454 return NT_STATUS_INTERNAL_DB_CORRUPTION;
461 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
462 struct pdb_ads_state *state,
463 struct samu *sam_acct,
466 struct pdb_ads_samu_private *priv;
469 status = pdb_ads_getsamupriv(state, filter, sam_acct, &priv);
470 if (!NT_STATUS_IS_OK(status)) {
471 DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n",
476 status = pdb_ads_init_sam_from_priv(m, sam_acct, priv);
477 if (!NT_STATUS_IS_OK(status)) {
478 DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n",
484 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
488 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
489 struct samu *sam_acct,
490 const char *username)
492 struct pdb_ads_state *state = talloc_get_type_abort(
493 m->private_data, struct pdb_ads_state);
496 filter = talloc_asprintf(
497 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
499 NT_STATUS_HAVE_NO_MEMORY(filter);
501 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
504 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
505 struct samu *sam_acct,
506 const struct dom_sid *sid)
508 struct pdb_ads_state *state = talloc_get_type_abort(
509 m->private_data, struct pdb_ads_state);
510 char *sidstr, *filter;
512 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
513 NT_STATUS_HAVE_NO_MEMORY(sidstr);
515 filter = talloc_asprintf(
516 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
518 NT_STATUS_HAVE_NO_MEMORY(filter);
520 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
523 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
525 const char *name, uint32 acct_flags,
528 struct pdb_ads_state *state = talloc_get_type_abort(
529 m->private_data, struct pdb_ads_state);
530 struct tldap_context *ld;
531 const char *attrs[1] = { "objectSid" };
532 struct tldap_mod *mods = NULL;
534 struct tldap_message **user;
540 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
543 return NT_STATUS_NO_MEMORY;
546 ld = pdb_ads_ld(state);
548 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
551 /* TODO: Create machines etc */
554 ok &= tldap_make_mod_fmt(
555 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "user");
556 ok &= tldap_make_mod_fmt(
557 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
560 return NT_STATUS_NO_MEMORY;
564 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
565 if (rc != TLDAP_SUCCESS) {
566 DEBUG(10, ("ldap_add failed %s\n",
567 tldap_errstr(talloc_tos(), ld, rc)));
569 return NT_STATUS_LDAP(rc);
572 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
573 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
575 "(&(objectclass=user)(samaccountname=%s))",
577 if (rc != TLDAP_SUCCESS) {
578 DEBUG(10, ("Could not find just created user %s: %s\n",
579 name, tldap_errstr(talloc_tos(), state->ld, rc)));
581 return NT_STATUS_LDAP(rc);
584 if (talloc_array_length(user) != 1) {
585 DEBUG(10, ("Got %d users, expected one\n",
586 (int)talloc_array_length(user)));
588 return NT_STATUS_LDAP(rc);
591 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
592 DEBUG(10, ("Could not fetch objectSid from user %s\n",
595 return NT_STATUS_INTERNAL_DB_CORRUPTION;
598 sid_peek_rid(&sid, rid);
603 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
607 struct pdb_ads_state *state = talloc_get_type_abort(
608 m->private_data, struct pdb_ads_state);
610 struct tldap_context *ld;
614 ld = pdb_ads_ld(state);
616 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
619 status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
621 if (!NT_STATUS_IS_OK(status)) {
625 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
627 if (rc != TLDAP_SUCCESS) {
628 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
629 tldap_errstr(talloc_tos(), ld, rc)));
630 return NT_STATUS_LDAP(rc);
635 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
636 struct samu *sampass)
638 return NT_STATUS_NOT_IMPLEMENTED;
641 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
644 struct pdb_ads_state *state = talloc_get_type_abort(
645 m->private_data, struct pdb_ads_state);
646 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
647 struct tldap_context *ld;
648 struct tldap_mod *mods = NULL;
649 int rc, num_mods = 0;
651 ld = pdb_ads_ld(state);
653 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
656 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
657 &mods, &num_mods, sam)) {
658 return NT_STATUS_NO_MEMORY;
662 /* Nothing to do, just return success */
666 rc = tldap_modify(ld, priv->dn, mods, num_mods, NULL, 0,
669 if (rc != TLDAP_SUCCESS) {
670 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
671 tldap_errstr(talloc_tos(), ld, rc)));
672 return NT_STATUS_LDAP(rc);
678 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
679 struct samu *username)
681 return NT_STATUS_NOT_IMPLEMENTED;
684 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
685 struct samu *oldname,
688 return NT_STATUS_NOT_IMPLEMENTED;
691 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
692 struct samu *sam_acct,
695 return NT_STATUS_NOT_IMPLEMENTED;
698 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
701 struct pdb_ads_state *state = talloc_get_type_abort(
702 m->private_data, struct pdb_ads_state);
703 const char *attrs[4] = { "objectSid", "description", "samAccountName",
706 struct tldap_message **group;
710 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
711 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
712 &group, "%s", filter);
713 if (rc != TLDAP_SUCCESS) {
714 DEBUG(10, ("ldap_search failed %s\n",
715 tldap_errstr(talloc_tos(), state->ld, rc)));
716 return NT_STATUS_LDAP(rc);
718 if (talloc_array_length(group) != 1) {
719 DEBUG(10, ("Expected 1 user, got %d\n",
720 (int)talloc_array_length(group)));
721 return NT_STATUS_INTERNAL_DB_CORRUPTION;
724 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
725 return NT_STATUS_INTERNAL_DB_CORRUPTION;
727 map->gid = pdb_ads_sid2gid(&map->sid);
729 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
730 return NT_STATUS_INTERNAL_DB_CORRUPTION;
733 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
734 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
735 map->sid_name_use = SID_NAME_ALIAS;
737 case GTYPE_SECURITY_GLOBAL_GROUP:
738 map->sid_name_use = SID_NAME_DOM_GRP;
741 return NT_STATUS_INTERNAL_DB_CORRUPTION;
744 str = tldap_talloc_single_attribute(group[0], "samAccountName",
747 return NT_STATUS_INTERNAL_DB_CORRUPTION;
749 fstrcpy(map->nt_name, str);
752 str = tldap_talloc_single_attribute(group[0], "description",
755 fstrcpy(map->comment, str);
758 map->comment[0] = '\0';
765 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
771 filter = talloc_asprintf(talloc_tos(),
772 "(&(objectsid=%s)(objectclass=group))",
773 sid_string_talloc(talloc_tos(), &sid));
774 if (filter == NULL) {
775 return NT_STATUS_NO_MEMORY;
778 status = pdb_ads_getgrfilter(m, map, filter);
783 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
787 pdb_ads_gid_to_sid(m, gid, &sid);
788 return pdb_ads_getgrsid(m, map, sid);
791 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
797 filter = talloc_asprintf(talloc_tos(),
798 "(&(samaccountname=%s)(objectclass=group))",
800 if (filter == NULL) {
801 return NT_STATUS_NO_MEMORY;
804 status = pdb_ads_getgrfilter(m, map, filter);
809 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
810 TALLOC_CTX *mem_ctx, const char *name,
813 TALLOC_CTX *frame = talloc_stackframe();
814 struct pdb_ads_state *state = talloc_get_type_abort(
815 m->private_data, struct pdb_ads_state);
816 struct tldap_context *ld;
817 const char *attrs[1] = { "objectSid" };
819 struct tldap_mod *mods = NULL;
820 struct tldap_message **alias;
826 ld = pdb_ads_ld(state);
828 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
831 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
835 return NT_STATUS_NO_MEMORY;
838 ok &= tldap_make_mod_fmt(
839 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
841 ok &= tldap_make_mod_fmt(
842 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group");
843 ok &= tldap_make_mod_fmt(
844 NULL, talloc_tos(), &mods, &num_mods, "groupType",
845 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
849 return NT_STATUS_NO_MEMORY;
852 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
853 if (rc != TLDAP_SUCCESS) {
854 DEBUG(10, ("ldap_add failed %s\n",
855 tldap_errstr(talloc_tos(), state->ld, rc)));
857 return NT_STATUS_LDAP(rc);
860 rc = pdb_ads_search_fmt(
861 state, state->domaindn, TLDAP_SCOPE_SUB,
862 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
863 "(&(objectclass=group)(samaccountname=%s))", name);
864 if (rc != TLDAP_SUCCESS) {
865 DEBUG(10, ("Could not find just created alias %s: %s\n",
866 name, tldap_errstr(talloc_tos(), state->ld, rc)));
868 return NT_STATUS_LDAP(rc);
871 if (talloc_array_length(alias) != 1) {
872 DEBUG(10, ("Got %d alias, expected one\n",
873 (int)talloc_array_length(alias)));
875 return NT_STATUS_LDAP(rc);
878 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
879 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
882 return NT_STATUS_INTERNAL_DB_CORRUPTION;
885 sid_peek_rid(&sid, rid);
890 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
891 TALLOC_CTX *mem_ctx, uint32 rid)
893 struct pdb_ads_state *state = talloc_get_type_abort(
894 m->private_data, struct pdb_ads_state);
895 struct tldap_context *ld;
898 struct tldap_message **msg;
902 sid_compose(&sid, &state->domainsid, rid);
904 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
905 NT_STATUS_HAVE_NO_MEMORY(sidstr);
907 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
908 NULL, 0, 0, talloc_tos(), &msg,
909 ("(&(objectSid=%s)(objectClass=group))"),
912 if (rc != TLDAP_SUCCESS) {
913 DEBUG(10, ("ldap_search failed %s\n",
914 tldap_errstr(talloc_tos(), state->ld, rc)));
915 return NT_STATUS_LDAP(rc);
918 switch talloc_array_length(msg) {
920 return NT_STATUS_NO_SUCH_GROUP;
924 return NT_STATUS_INTERNAL_DB_CORRUPTION;
927 if (!tldap_entry_dn(msg[0], &dn)) {
929 return NT_STATUS_INTERNAL_DB_CORRUPTION;
932 ld = pdb_ads_ld(state);
935 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
938 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
940 if (rc != TLDAP_SUCCESS) {
941 DEBUG(10, ("ldap_delete failed: %s\n",
942 tldap_errstr(talloc_tos(), state->ld, rc)));
943 return NT_STATUS_LDAP(rc);
949 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
952 return NT_STATUS_NOT_IMPLEMENTED;
955 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
958 return NT_STATUS_NOT_IMPLEMENTED;
961 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
964 return NT_STATUS_NOT_IMPLEMENTED;
967 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
968 const struct dom_sid *sid,
969 enum lsa_SidType sid_name_use,
971 size_t *p_num_entries,
974 return NT_STATUS_NOT_IMPLEMENTED;
977 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
979 const struct dom_sid *group,
981 size_t *pnum_members)
983 struct pdb_ads_state *state = talloc_get_type_abort(
984 m->private_data, struct pdb_ads_state);
985 const char *attrs[1] = { "member" };
987 struct tldap_message **msg;
988 int i, rc, num_members;
992 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), group);
993 NT_STATUS_HAVE_NO_MEMORY(sidstr);
995 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
996 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
997 &msg, "(objectsid=%s)", sidstr);
999 if (rc != TLDAP_SUCCESS) {
1000 DEBUG(10, ("ldap_search failed %s\n",
1001 tldap_errstr(talloc_tos(), state->ld, rc)));
1002 return NT_STATUS_LDAP(rc);
1004 switch talloc_array_length(msg) {
1006 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1011 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1015 if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
1016 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1019 members = talloc_array(mem_ctx, uint32_t, num_members);
1020 if (members == NULL) {
1021 return NT_STATUS_NO_MEMORY;
1024 for (i=0; i<num_members; i++) {
1026 if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
1027 || !sid_peek_rid(&sid, &members[i])) {
1028 TALLOC_FREE(members);
1029 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1033 *pmembers = members;
1034 *pnum_members = num_members;
1035 return NT_STATUS_OK;
1038 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
1039 TALLOC_CTX *mem_ctx,
1041 struct dom_sid **pp_sids,
1043 size_t *p_num_groups)
1045 struct pdb_ads_state *state = talloc_get_type_abort(
1046 m->private_data, struct pdb_ads_state);
1047 struct pdb_ads_samu_private *priv;
1048 const char *attrs[1] = { "objectSid" };
1049 struct tldap_message **groups;
1052 struct dom_sid *group_sids;
1055 priv = pdb_ads_get_samu_private(m, user);
1057 rc = pdb_ads_search_fmt(
1058 state, state->domaindn, TLDAP_SCOPE_SUB,
1059 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
1060 "(&(member=%s)(grouptype=%d)(objectclass=group))",
1061 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
1062 if (rc != TLDAP_SUCCESS) {
1063 DEBUG(10, ("ldap_search failed %s\n",
1064 tldap_errstr(talloc_tos(), state->ld, rc)));
1065 return NT_STATUS_LDAP(rc);
1067 count = talloc_array_length(groups);
1070 * This happens for artificial samu users
1072 DEBUG(10, ("Could not get pdb_ads_samu_private\n"));
1076 group_sids = talloc_array(mem_ctx, struct dom_sid, count+1);
1077 if (group_sids == NULL) {
1078 return NT_STATUS_NO_MEMORY;
1080 gids = talloc_array(mem_ctx, gid_t, count+1);
1082 TALLOC_FREE(group_sids);
1083 return NT_STATUS_NO_MEMORY;
1086 sid_copy(&group_sids[0], pdb_get_group_sid(user));
1087 if (!sid_to_gid(&group_sids[0], &gids[0])) {
1089 TALLOC_FREE(group_sids);
1090 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1094 for (i=0; i<count; i++) {
1095 if (!tldap_pull_binsid(groups[i], "objectSid",
1096 &group_sids[num_groups])) {
1099 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
1102 if (num_groups == count) {
1107 *pp_sids = group_sids;
1109 *p_num_groups = num_groups;
1110 return NT_STATUS_OK;
1113 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
1114 TALLOC_CTX *mem_ctx,
1117 return NT_STATUS_NOT_IMPLEMENTED;
1120 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
1121 TALLOC_CTX *mem_ctx,
1122 uint32 grouprid, uint32 memberrid,
1125 struct pdb_ads_state *state = talloc_get_type_abort(
1126 m->private_data, struct pdb_ads_state);
1127 TALLOC_CTX *frame = talloc_stackframe();
1128 struct tldap_context *ld;
1129 struct dom_sid groupsid, membersid;
1130 char *groupdn, *memberdn;
1131 struct tldap_mod *mods;
1136 ld = pdb_ads_ld(state);
1138 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1141 sid_compose(&groupsid, &state->domainsid, grouprid);
1142 sid_compose(&membersid, &state->domainsid, memberrid);
1144 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
1145 if (!NT_STATUS_IS_OK(status)) {
1147 return NT_STATUS_NO_SUCH_GROUP;
1149 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
1150 if (!NT_STATUS_IS_OK(status)) {
1152 return NT_STATUS_NO_SUCH_USER;
1158 if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op,
1159 "member", memberdn)) {
1161 return NT_STATUS_NO_MEMORY;
1164 rc = tldap_modify(ld, groupdn, mods, num_mods, NULL, 0, NULL, 0);
1166 if (rc != TLDAP_SUCCESS) {
1167 DEBUG(10, ("ldap_modify failed: %s\n",
1168 tldap_errstr(talloc_tos(), state->ld, rc)));
1169 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1170 return NT_STATUS_MEMBER_IN_GROUP;
1172 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1173 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1175 return NT_STATUS_LDAP(rc);
1178 return NT_STATUS_OK;
1181 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
1182 TALLOC_CTX *mem_ctx,
1183 uint32 group_rid, uint32 member_rid)
1185 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1189 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
1190 TALLOC_CTX *mem_ctx,
1191 uint32 group_rid, uint32 member_rid)
1193 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1197 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
1198 const char *name, uint32 *rid)
1200 TALLOC_CTX *frame = talloc_stackframe();
1201 struct pdb_ads_state *state = talloc_get_type_abort(
1202 m->private_data, struct pdb_ads_state);
1203 struct tldap_context *ld;
1204 const char *attrs[1] = { "objectSid" };
1206 struct tldap_mod *mods = NULL;
1207 struct tldap_message **alias;
1213 ld = pdb_ads_ld(state);
1215 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1218 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1222 return NT_STATUS_NO_MEMORY;
1225 ok &= tldap_make_mod_fmt(
1226 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
1228 ok &= tldap_make_mod_fmt(
1229 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group");
1230 ok &= tldap_make_mod_fmt(
1231 NULL, talloc_tos(), &mods, &num_mods, "groupType",
1232 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1236 return NT_STATUS_NO_MEMORY;
1239 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1240 if (rc != TLDAP_SUCCESS) {
1241 DEBUG(10, ("ldap_add failed %s\n",
1242 tldap_errstr(talloc_tos(), state->ld, rc)));
1244 return NT_STATUS_LDAP(rc);
1247 rc = pdb_ads_search_fmt(
1248 state, state->domaindn, TLDAP_SCOPE_SUB,
1249 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1250 "(&(objectclass=group)(samaccountname=%s))", name);
1251 if (rc != TLDAP_SUCCESS) {
1252 DEBUG(10, ("Could not find just created alias %s: %s\n",
1253 name, tldap_errstr(talloc_tos(), state->ld, rc)));
1255 return NT_STATUS_LDAP(rc);
1258 if (talloc_array_length(alias) != 1) {
1259 DEBUG(10, ("Got %d alias, expected one\n",
1260 (int)talloc_array_length(alias)));
1262 return NT_STATUS_LDAP(rc);
1265 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1266 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1269 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1272 sid_peek_rid(&sid, rid);
1274 return NT_STATUS_OK;
1277 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1278 const struct dom_sid *sid)
1280 struct pdb_ads_state *state = talloc_get_type_abort(
1281 m->private_data, struct pdb_ads_state);
1282 struct tldap_context *ld;
1283 struct tldap_message **alias;
1284 char *sidstr, *dn = NULL;
1287 ld = pdb_ads_ld(state);
1289 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1292 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1293 if (sidstr == NULL) {
1294 return NT_STATUS_NO_MEMORY;
1297 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1298 NULL, 0, 0, talloc_tos(), &alias,
1299 "(&(objectSid=%s)(objectclass=group)"
1300 "(|(grouptype=%d)(grouptype=%d)))",
1301 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1302 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1303 TALLOC_FREE(sidstr);
1304 if (rc != TLDAP_SUCCESS) {
1305 DEBUG(10, ("ldap_search failed: %s\n",
1306 tldap_errstr(talloc_tos(), state->ld, rc)));
1307 return NT_STATUS_LDAP(rc);
1309 if (talloc_array_length(alias) != 1) {
1310 DEBUG(10, ("Expected 1 alias, got %d\n",
1311 (int)talloc_array_length(alias)));
1312 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1314 if (!tldap_entry_dn(alias[0], &dn)) {
1315 DEBUG(10, ("Could not get DN for alias %s\n",
1316 sid_string_dbg(sid)));
1317 return NT_STATUS_INTERNAL_ERROR;
1320 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
1321 if (rc != TLDAP_SUCCESS) {
1322 DEBUG(10, ("ldap_delete failed: %s\n",
1323 tldap_errstr(talloc_tos(), state->ld, rc)));
1324 return NT_STATUS_LDAP(rc);
1327 return NT_STATUS_OK;
1330 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1331 const struct dom_sid *sid,
1332 struct acct_info *info)
1334 struct pdb_ads_state *state = talloc_get_type_abort(
1335 m->private_data, struct pdb_ads_state);
1336 struct tldap_context *ld;
1337 const char *attrs[3] = { "objectSid", "description",
1339 struct tldap_message **msg;
1342 struct tldap_mod *mods;
1346 ld = pdb_ads_ld(state);
1348 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1351 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1352 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1354 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1355 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1356 &msg, "(&(objectSid=%s)(objectclass=group)"
1357 "(|(grouptype=%d)(grouptype=%d)))",
1358 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1359 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1360 TALLOC_FREE(sidstr);
1361 if (rc != TLDAP_SUCCESS) {
1362 DEBUG(10, ("ldap_search failed %s\n",
1363 tldap_errstr(talloc_tos(), state->ld, rc)));
1364 return NT_STATUS_LDAP(rc);
1366 switch talloc_array_length(msg) {
1368 return NT_STATUS_NO_SUCH_ALIAS;
1372 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1375 if (!tldap_entry_dn(msg[0], &dn)) {
1377 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1384 ok &= tldap_make_mod_fmt(
1385 msg[0], msg, &mods, &num_mods, "description",
1386 "%s", info->acct_desc);
1387 ok &= tldap_make_mod_fmt(
1388 msg[0], msg, &mods, &num_mods, "samAccountName",
1389 "%s", info->acct_name);
1392 return NT_STATUS_NO_MEMORY;
1394 if (num_mods == 0) {
1397 return NT_STATUS_OK;
1400 rc = tldap_modify(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1402 if (rc != TLDAP_SUCCESS) {
1403 DEBUG(10, ("ldap_modify failed: %s\n",
1404 tldap_errstr(talloc_tos(), state->ld, rc)));
1405 return NT_STATUS_LDAP(rc);
1407 return NT_STATUS_OK;
1410 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1411 const struct dom_sid *sid,
1412 TALLOC_CTX *mem_ctx, char **pdn)
1414 struct tldap_message **msg;
1418 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1419 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1421 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1422 NULL, 0, 0, talloc_tos(), &msg,
1423 "(objectsid=%s)", sidstr);
1424 TALLOC_FREE(sidstr);
1425 if (rc != TLDAP_SUCCESS) {
1426 DEBUG(10, ("ldap_search failed %s\n",
1427 tldap_errstr(talloc_tos(), state->ld, rc)));
1428 return NT_STATUS_LDAP(rc);
1431 switch talloc_array_length(msg) {
1433 return NT_STATUS_NOT_FOUND;
1437 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1440 if (!tldap_entry_dn(msg[0], &dn)) {
1441 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1444 dn = talloc_strdup(mem_ctx, dn);
1446 return NT_STATUS_NO_MEMORY;
1451 return NT_STATUS_OK;
1454 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1455 const struct dom_sid *alias,
1456 const struct dom_sid *member,
1459 struct pdb_ads_state *state = talloc_get_type_abort(
1460 m->private_data, struct pdb_ads_state);
1461 struct tldap_context *ld;
1462 TALLOC_CTX *frame = talloc_stackframe();
1463 struct tldap_mod *mods;
1466 char *aliasdn, *memberdn;
1469 ld = pdb_ads_ld(state);
1471 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1474 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1475 if (!NT_STATUS_IS_OK(status)) {
1476 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1477 sid_string_dbg(alias), nt_errstr(status)));
1479 return NT_STATUS_NO_SUCH_ALIAS;
1481 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1482 if (!NT_STATUS_IS_OK(status)) {
1483 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1484 sid_string_dbg(member), nt_errstr(status)));
1492 if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op,
1493 "member", memberdn)) {
1495 return NT_STATUS_NO_MEMORY;
1498 rc = tldap_modify(ld, aliasdn, mods, num_mods, NULL, 0, NULL, 0);
1500 if (rc != TLDAP_SUCCESS) {
1501 DEBUG(10, ("ldap_modify failed: %s\n",
1502 tldap_errstr(talloc_tos(), state->ld, rc)));
1503 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1504 return NT_STATUS_MEMBER_IN_ALIAS;
1506 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1507 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1509 return NT_STATUS_LDAP(rc);
1512 return NT_STATUS_OK;
1515 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1516 const struct dom_sid *alias,
1517 const struct dom_sid *member)
1519 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1522 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1523 const struct dom_sid *alias,
1524 const struct dom_sid *member)
1526 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1529 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
1530 struct dom_sid *psid)
1532 const char *attrs[1] = { "objectSid" };
1533 struct tldap_message **msg;
1539 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1540 dnblob->data, dnblob->length, &dn, &len,
1544 rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
1545 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1546 &msg, "(objectclass=*)");
1548 if (talloc_array_length(msg) != 1) {
1549 DEBUG(10, ("Got %d objects, expected one\n",
1550 (int)talloc_array_length(msg)));
1555 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1560 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1561 const struct dom_sid *alias,
1562 TALLOC_CTX *mem_ctx,
1563 struct dom_sid **pmembers,
1564 size_t *pnum_members)
1566 struct pdb_ads_state *state = talloc_get_type_abort(
1567 m->private_data, struct pdb_ads_state);
1568 const char *attrs[1] = { "member" };
1570 struct tldap_message **msg;
1571 int i, rc, num_members;
1573 struct dom_sid *members;
1575 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), alias);
1576 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1578 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1579 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1580 &msg, "(objectsid=%s)", sidstr);
1581 TALLOC_FREE(sidstr);
1582 if (rc != TLDAP_SUCCESS) {
1583 DEBUG(10, ("ldap_search failed %s\n",
1584 tldap_errstr(talloc_tos(), state->ld, rc)));
1585 return NT_STATUS_LDAP(rc);
1587 switch talloc_array_length(msg) {
1589 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1594 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1598 if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
1599 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1602 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1603 if (members == NULL) {
1604 return NT_STATUS_NO_MEMORY;
1607 for (i=0; i<num_members; i++) {
1608 if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
1609 TALLOC_FREE(members);
1610 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1614 *pmembers = members;
1615 *pnum_members = num_members;
1616 return NT_STATUS_OK;
1619 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1620 TALLOC_CTX *mem_ctx,
1621 const struct dom_sid *domain_sid,
1622 const struct dom_sid *members,
1624 uint32_t **palias_rids,
1625 size_t *pnum_alias_rids)
1627 struct pdb_ads_state *state = talloc_get_type_abort(
1628 m->private_data, struct pdb_ads_state);
1629 const char *attrs[1] = { "objectSid" };
1630 struct tldap_message **msg = NULL;
1631 uint32_t *alias_rids = NULL;
1632 size_t num_alias_rids = 0;
1634 bool got_members = false;
1639 * TODO: Get the filter right so that we only get the aliases from
1640 * either the SAM or BUILTIN
1643 filter = talloc_asprintf(talloc_tos(),
1644 "(&(|(grouptype=%d)(grouptype=%d))"
1645 "(objectclass=group)(|",
1646 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1647 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1648 if (filter == NULL) {
1649 return NT_STATUS_NO_MEMORY;
1652 for (i=0; i<num_members; i++) {
1655 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1656 if (!NT_STATUS_IS_OK(status)) {
1657 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1658 sid_string_dbg(&members[i]),
1659 nt_errstr(status)));
1662 filter = talloc_asprintf_append_buffer(
1663 filter, "(member=%s)", dn);
1665 if (filter == NULL) {
1666 return NT_STATUS_NO_MEMORY;
1675 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1676 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1677 &msg, "%s))", filter);
1678 TALLOC_FREE(filter);
1679 if (rc != TLDAP_SUCCESS) {
1680 DEBUG(10, ("tldap_search failed %s\n",
1681 tldap_errstr(talloc_tos(), state->ld, rc)));
1682 return NT_STATUS_LDAP(rc);
1685 count = talloc_array_length(msg);
1690 alias_rids = talloc_array(mem_ctx, uint32_t, count);
1691 if (alias_rids == NULL) {
1693 return NT_STATUS_NO_MEMORY;
1696 for (i=0; i<count; i++) {
1699 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1700 DEBUG(10, ("Could not pull SID for member %d\n", i));
1703 if (sid_peek_check_rid(domain_sid, &sid,
1704 &alias_rids[num_alias_rids])) {
1705 num_alias_rids += 1;
1710 *palias_rids = alias_rids;
1711 *pnum_alias_rids = 0;
1712 return NT_STATUS_OK;
1715 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1716 const struct dom_sid *domain_sid,
1720 enum lsa_SidType *lsa_attrs)
1722 struct pdb_ads_state *state = talloc_get_type_abort(
1723 m->private_data, struct pdb_ads_state);
1724 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1727 if (num_rids == 0) {
1728 return NT_STATUS_NONE_MAPPED;
1733 for (i=0; i<num_rids; i++) {
1735 struct tldap_message **msg;
1740 lsa_attrs[i] = SID_NAME_UNKNOWN;
1742 sid_compose(&sid, domain_sid, rids[i]);
1744 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
1745 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1747 rc = pdb_ads_search_fmt(state, state->domaindn,
1748 TLDAP_SCOPE_SUB, attrs,
1749 ARRAY_SIZE(attrs), 0, talloc_tos(),
1750 &msg, "(objectsid=%s)", sidstr);
1751 TALLOC_FREE(sidstr);
1752 if (rc != TLDAP_SUCCESS) {
1753 DEBUG(10, ("ldap_search failed %s\n",
1754 tldap_errstr(talloc_tos(), state->ld, rc)));
1758 switch talloc_array_length(msg) {
1760 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1765 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1768 names[i] = tldap_talloc_single_attribute(
1769 msg[0], "samAccountName", talloc_tos());
1770 if (names[i] == NULL) {
1771 DEBUG(10, ("no samAccountName\n"));
1774 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1775 DEBUG(10, ("no samAccountType"));
1778 lsa_attrs[i] = ds_atype_map(attr);
1782 if (num_mapped == 0) {
1783 return NT_STATUS_NONE_MAPPED;
1785 if (num_mapped < num_rids) {
1786 return STATUS_SOME_UNMAPPED;
1788 return NT_STATUS_OK;
1791 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1792 const struct dom_sid *domain_sid,
1794 const char **pp_names,
1796 enum lsa_SidType *attrs)
1798 return NT_STATUS_NOT_IMPLEMENTED;
1801 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1802 enum pdb_policy_type type,
1805 return account_policy_get(type, value)
1806 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1809 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1810 enum pdb_policy_type type,
1813 return account_policy_set(type, value)
1814 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1817 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1820 return NT_STATUS_NOT_IMPLEMENTED;
1823 struct pdb_ads_search_state {
1824 uint32_t acct_flags;
1825 struct samr_displayentry *entries;
1826 uint32_t num_entries;
1831 static bool pdb_ads_next_entry(struct pdb_search *search,
1832 struct samr_displayentry *entry)
1834 struct pdb_ads_search_state *state = talloc_get_type_abort(
1835 search->private_data, struct pdb_ads_search_state);
1837 if (state->current == state->num_entries) {
1841 entry->idx = state->entries[state->current].idx;
1842 entry->rid = state->entries[state->current].rid;
1843 entry->acct_flags = state->entries[state->current].acct_flags;
1845 entry->account_name = talloc_strdup(
1846 search, state->entries[state->current].account_name);
1847 entry->fullname = talloc_strdup(
1848 search, state->entries[state->current].fullname);
1849 entry->description = talloc_strdup(
1850 search, state->entries[state->current].description);
1852 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1853 || (entry->description == NULL)) {
1854 DEBUG(0, ("talloc_strdup failed\n"));
1858 state->current += 1;
1862 static void pdb_ads_search_end(struct pdb_search *search)
1864 struct pdb_ads_search_state *state = talloc_get_type_abort(
1865 search->private_data, struct pdb_ads_search_state);
1869 static bool pdb_ads_search_filter(struct pdb_methods *m,
1870 struct pdb_search *search,
1872 struct pdb_ads_search_state **pstate)
1874 struct pdb_ads_state *state = talloc_get_type_abort(
1875 m->private_data, struct pdb_ads_state);
1876 struct pdb_ads_search_state *sstate;
1877 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1878 "userAccountControl", "description" };
1879 struct tldap_message **users;
1880 int i, rc, num_users;
1882 sstate = talloc_zero(search, struct pdb_ads_search_state);
1883 if (sstate == NULL) {
1887 rc = pdb_ads_search_fmt(
1888 state, state->domaindn, TLDAP_SCOPE_SUB,
1889 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1891 if (rc != TLDAP_SUCCESS) {
1892 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1893 tldap_errstr(talloc_tos(), state->ld, rc)));
1897 num_users = talloc_array_length(users);
1899 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1901 if (sstate->entries == NULL) {
1902 DEBUG(10, ("talloc failed\n"));
1906 sstate->num_entries = 0;
1908 for (i=0; i<num_users; i++) {
1909 struct samr_displayentry *e;
1912 e = &sstate->entries[sstate->num_entries];
1914 e->idx = sstate->num_entries;
1915 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1916 DEBUG(10, ("Could not pull sid\n"));
1919 sid_peek_rid(&sid, &e->rid);
1920 e->acct_flags = ACB_NORMAL;
1921 e->account_name = tldap_talloc_single_attribute(
1922 users[i], "samAccountName", sstate->entries);
1923 if (e->account_name == NULL) {
1926 e->fullname = tldap_talloc_single_attribute(
1927 users[i], "displayName", sstate->entries);
1928 if (e->fullname == NULL) {
1931 e->description = tldap_talloc_single_attribute(
1932 users[i], "description", sstate->entries);
1933 if (e->description == NULL) {
1934 e->description = "";
1937 sstate->num_entries += 1;
1938 if (sstate->num_entries >= num_users) {
1943 search->private_data = sstate;
1944 search->next_entry = pdb_ads_next_entry;
1945 search->search_end = pdb_ads_search_end;
1950 static bool pdb_ads_search_users(struct pdb_methods *m,
1951 struct pdb_search *search,
1954 struct pdb_ads_search_state *sstate;
1958 if (acct_flags & ACB_NORMAL) {
1959 filter = talloc_asprintf(
1961 "(&(objectclass=user)(sAMAccountType=%d))",
1962 ATYPE_NORMAL_ACCOUNT);
1963 } else if (acct_flags & ACB_WSTRUST) {
1964 filter = talloc_asprintf(
1966 "(&(objectclass=user)(sAMAccountType=%d))",
1967 ATYPE_WORKSTATION_TRUST);
1969 filter = talloc_strdup(talloc_tos(), "(objectclass=user)");
1971 if (filter == NULL) {
1975 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1976 TALLOC_FREE(filter);
1980 sstate->acct_flags = acct_flags;
1984 static bool pdb_ads_search_groups(struct pdb_methods *m,
1985 struct pdb_search *search)
1987 struct pdb_ads_search_state *sstate;
1991 filter = talloc_asprintf(talloc_tos(),
1992 "(&(grouptype=%d)(objectclass=group))",
1993 GTYPE_SECURITY_GLOBAL_GROUP);
1994 if (filter == NULL) {
1997 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1998 TALLOC_FREE(filter);
2002 sstate->acct_flags = 0;
2006 static bool pdb_ads_search_aliases(struct pdb_methods *m,
2007 struct pdb_search *search,
2008 const struct dom_sid *sid)
2010 struct pdb_ads_search_state *sstate;
2014 filter = talloc_asprintf(
2015 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
2016 sid_check_is_builtin(sid)
2017 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2018 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
2020 if (filter == NULL) {
2023 ret = pdb_ads_search_filter(m, search, filter, &sstate);
2024 TALLOC_FREE(filter);
2028 sstate->acct_flags = 0;
2032 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
2033 struct dom_sid *sid)
2035 struct pdb_ads_state *state = talloc_get_type_abort(
2036 m->private_data, struct pdb_ads_state);
2037 sid_compose(sid, &state->domainsid, uid);
2041 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
2042 struct dom_sid *sid)
2044 struct pdb_ads_state *state = talloc_get_type_abort(
2045 m->private_data, struct pdb_ads_state);
2046 sid_compose(sid, &state->domainsid, gid);
2050 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2051 union unid_t *id, enum lsa_SidType *type)
2053 struct pdb_ads_state *state = talloc_get_type_abort(
2054 m->private_data, struct pdb_ads_state);
2055 struct tldap_message **msg;
2061 * This is a big, big hack: Just hard-code the rid as uid/gid.
2064 sid_peek_rid(sid, &rid);
2066 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
2067 if (sidstr == NULL) {
2071 rc = pdb_ads_search_fmt(
2072 state, state->domaindn, TLDAP_SCOPE_SUB,
2073 NULL, 0, 0, talloc_tos(), &msg,
2074 "(&(objectsid=%s)(objectclass=user))", sidstr);
2075 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
2077 *type = SID_NAME_USER;
2078 TALLOC_FREE(sidstr);
2082 rc = pdb_ads_search_fmt(
2083 state, state->domaindn, TLDAP_SCOPE_SUB,
2084 NULL, 0, 0, talloc_tos(), &msg,
2085 "(&(objectsid=%s)(objectclass=group))", sidstr);
2086 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
2088 *type = SID_NAME_DOM_GRP;
2089 TALLOC_FREE(sidstr);
2093 TALLOC_FREE(sidstr);
2097 static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
2099 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2102 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
2107 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
2108 const char *domain, char** pwd,
2109 struct dom_sid *sid,
2110 time_t *pass_last_set_time)
2115 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
2116 const char* domain, const char* pwd,
2117 const struct dom_sid *sid)
2122 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
2128 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
2129 TALLOC_CTX *mem_ctx,
2130 uint32 *num_domains,
2131 struct trustdom_info ***domains)
2135 return NT_STATUS_OK;
2138 static void pdb_ads_init_methods(struct pdb_methods *m)
2141 m->get_domain_info = pdb_ads_get_domain_info;
2142 m->getsampwnam = pdb_ads_getsampwnam;
2143 m->getsampwsid = pdb_ads_getsampwsid;
2144 m->create_user = pdb_ads_create_user;
2145 m->delete_user = pdb_ads_delete_user;
2146 m->add_sam_account = pdb_ads_add_sam_account;
2147 m->update_sam_account = pdb_ads_update_sam_account;
2148 m->delete_sam_account = pdb_ads_delete_sam_account;
2149 m->rename_sam_account = pdb_ads_rename_sam_account;
2150 m->update_login_attempts = pdb_ads_update_login_attempts;
2151 m->getgrsid = pdb_ads_getgrsid;
2152 m->getgrgid = pdb_ads_getgrgid;
2153 m->getgrnam = pdb_ads_getgrnam;
2154 m->create_dom_group = pdb_ads_create_dom_group;
2155 m->delete_dom_group = pdb_ads_delete_dom_group;
2156 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
2157 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
2158 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
2159 m->enum_group_mapping = pdb_ads_enum_group_mapping;
2160 m->enum_group_members = pdb_ads_enum_group_members;
2161 m->enum_group_memberships = pdb_ads_enum_group_memberships;
2162 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
2163 m->add_groupmem = pdb_ads_add_groupmem;
2164 m->del_groupmem = pdb_ads_del_groupmem;
2165 m->create_alias = pdb_ads_create_alias;
2166 m->delete_alias = pdb_ads_delete_alias;
2167 m->get_aliasinfo = pdb_default_get_aliasinfo;
2168 m->set_aliasinfo = pdb_ads_set_aliasinfo;
2169 m->add_aliasmem = pdb_ads_add_aliasmem;
2170 m->del_aliasmem = pdb_ads_del_aliasmem;
2171 m->enum_aliasmem = pdb_ads_enum_aliasmem;
2172 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
2173 m->lookup_rids = pdb_ads_lookup_rids;
2174 m->lookup_names = pdb_ads_lookup_names;
2175 m->get_account_policy = pdb_ads_get_account_policy;
2176 m->set_account_policy = pdb_ads_set_account_policy;
2177 m->get_seq_num = pdb_ads_get_seq_num;
2178 m->search_users = pdb_ads_search_users;
2179 m->search_groups = pdb_ads_search_groups;
2180 m->search_aliases = pdb_ads_search_aliases;
2181 m->uid_to_sid = pdb_ads_uid_to_sid;
2182 m->gid_to_sid = pdb_ads_gid_to_sid;
2183 m->sid_to_id = pdb_ads_sid_to_id;
2184 m->capabilities = pdb_ads_capabilities;
2185 m->new_rid = pdb_ads_new_rid;
2186 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2187 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2188 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2189 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2192 static void free_private_data(void **vp)
2194 struct pdb_ads_state *state = talloc_get_type_abort(
2195 *vp, struct pdb_ads_state);
2197 TALLOC_FREE(state->ld);
2202 this is used to catch debug messages from events
2204 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2205 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
2207 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2208 const char *fmt, va_list ap)
2210 int samba_level = -1;
2213 case TLDAP_DEBUG_FATAL:
2216 case TLDAP_DEBUG_ERROR:
2219 case TLDAP_DEBUG_WARNING:
2222 case TLDAP_DEBUG_TRACE:
2227 if (vasprintf(&s, fmt, ap) == -1) {
2230 DEBUG(samba_level, ("tldap: %s", s));
2234 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2239 if (tldap_connection_ok(state->ld)) {
2242 TALLOC_FREE(state->ld);
2244 status = open_socket_out(
2245 (struct sockaddr_storage *)(void *)&state->socket_address,
2247 if (!NT_STATUS_IS_OK(status)) {
2248 DEBUG(10, ("Could not connect to %s: %s\n",
2249 state->socket_address.sun_path, nt_errstr(status)));
2253 set_blocking(fd, false);
2255 state->ld = tldap_context_create(state, fd);
2256 if (state->ld == NULL) {
2260 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2265 int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2266 int scope, const char *attrs[], int num_attrs,
2268 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2269 const char *fmt, ...)
2271 struct tldap_context *ld;
2275 ld = pdb_ads_ld(state);
2277 return TLDAP_SERVER_DOWN;
2281 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2282 mem_ctx, res, fmt, ap);
2285 if (ret != TLDAP_SERVER_DOWN) {
2290 ld = pdb_ads_ld(state);
2292 return TLDAP_SERVER_DOWN;
2296 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2297 mem_ctx, res, fmt, ap);
2302 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2303 const char *location)
2305 const char *domain_attrs[2] = { "objectSid", "objectGUID" };
2306 const char *ncname_attrs[1] = { "netbiosname" };
2307 struct tldap_context *ld;
2308 struct tldap_message *rootdse, **domain, **ncname;
2309 TALLOC_CTX *frame = talloc_stackframe();
2314 ZERO_STRUCT(state->socket_address);
2315 state->socket_address.sun_family = AF_UNIX;
2316 strlcpy(state->socket_address.sun_path, location,
2317 sizeof(state->socket_address.sun_path));
2319 ld = pdb_ads_ld(state);
2321 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2325 rc = tldap_fetch_rootdse(ld);
2326 if (rc != TLDAP_SUCCESS) {
2327 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2328 tldap_errstr(talloc_tos(), state->ld, rc)));
2329 status = NT_STATUS_LDAP(rc);
2332 rootdse = tldap_rootdse(state->ld);
2334 state->domaindn = tldap_talloc_single_attribute(
2335 rootdse, "defaultNamingContext", state);
2336 if (state->domaindn == NULL) {
2337 DEBUG(10, ("Could not get defaultNamingContext\n"));
2338 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2341 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2343 state->configdn = tldap_talloc_single_attribute(
2344 rootdse, "configurationNamingContext", state);
2345 if (state->domaindn == NULL) {
2346 DEBUG(10, ("Could not get configurationNamingContext\n"));
2347 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2350 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2353 * Figure out our domain's SID
2355 rc = pdb_ads_search_fmt(
2356 state, state->domaindn, TLDAP_SCOPE_BASE,
2357 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2358 talloc_tos(), &domain, "(objectclass=*)");
2359 if (rc != TLDAP_SUCCESS) {
2360 DEBUG(10, ("Could not retrieve domain: %s\n",
2361 tldap_errstr(talloc_tos(), state->ld, rc)));
2362 status = NT_STATUS_LDAP(rc);
2366 num_domains = talloc_array_length(domain);
2367 if (num_domains != 1) {
2368 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2369 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2372 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2373 DEBUG(10, ("Could not retrieve domain SID\n"));
2374 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2377 if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) {
2378 DEBUG(10, ("Could not retrieve domain GUID\n"));
2379 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2382 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2385 * Figure out our domain's short name
2387 rc = pdb_ads_search_fmt(
2388 state, state->configdn, TLDAP_SCOPE_SUB,
2389 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2390 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2391 if (rc != TLDAP_SUCCESS) {
2392 DEBUG(10, ("Could not retrieve ncname: %s\n",
2393 tldap_errstr(talloc_tos(), state->ld, rc)));
2394 status = NT_STATUS_LDAP(rc);
2397 if (talloc_array_length(ncname) != 1) {
2398 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2402 state->netbiosname = tldap_talloc_single_attribute(
2403 ncname[0], "netbiosname", state);
2404 if (state->netbiosname == NULL) {
2405 DEBUG(10, ("Could not get netbiosname\n"));
2406 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2409 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2411 if (!strequal(lp_workgroup(), state->netbiosname)) {
2412 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2413 state->netbiosname, lp_workgroup()));
2414 status = NT_STATUS_NO_SUCH_DOMAIN;
2418 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2420 status = NT_STATUS_OK;
2426 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2427 const char *location)
2429 struct pdb_methods *m;
2430 struct pdb_ads_state *state;
2434 m = talloc(NULL, struct pdb_methods);
2436 return NT_STATUS_NO_MEMORY;
2438 state = talloc_zero(m, struct pdb_ads_state);
2439 if (state == NULL) {
2442 m->private_data = state;
2443 m->free_private_data = free_private_data;
2444 pdb_ads_init_methods(m);
2446 if (location == NULL) {
2447 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2451 if (location == NULL) {
2455 status = pdb_ads_connect(state, location);
2456 if (!NT_STATUS_IS_OK(status)) {
2457 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2462 return NT_STATUS_OK;
2464 status = NT_STATUS_NO_MEMORY;
2470 NTSTATUS pdb_ads_init(void);
2471 NTSTATUS pdb_ads_init(void)
2473 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",