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 = nt_time_to_unix(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 if (tldap_pull_uint32(entry, "codePage", &i)) {
313 pdb_set_code_page(sam, i, PDB_SET);
316 if (tldap_get_single_valueblob(entry, "logonHours", &blob)) {
318 if (blob.length > MAX_HOURS_LEN) {
319 status = NT_STATUS_INVALID_PARAMETER;
322 pdb_set_logon_divs(sam, blob.length * 8, PDB_SET);
323 pdb_set_hours_len(sam, blob.length, PDB_SET);
324 pdb_set_hours(sam, blob.data, blob.length, PDB_SET);
328 pdb_set_logon_divs(sam, sizeof(hours)/8, PDB_SET);
329 pdb_set_hours_len(sam, sizeof(hours), PDB_SET);
330 memset(hours, 0xff, sizeof(hours));
331 pdb_set_hours(sam, hours, sizeof(hours), PDB_SET);
334 status = NT_STATUS_OK;
340 static bool pdb_ads_make_time_mod(struct tldap_message *existing,
342 struct tldap_mod **pmods, int *pnum_mods,
343 const char *attrib, time_t t)
347 unix_to_nt_time(&nt_time, t);
349 return tldap_make_mod_fmt(
350 existing, mem_ctx, pmods, pnum_mods, attrib,
354 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
355 struct tldap_message *existing,
357 struct tldap_mod **pmods, int *pnum_mods,
364 /* TODO: All fields :-) */
366 ret &= tldap_make_mod_fmt(
367 existing, mem_ctx, pmods, pnum_mods, "displayName",
368 "%s", pdb_get_fullname(sam));
370 pw = pdb_get_plaintext_passwd(sam);
373 * If we have the plain text pw, this is probably about to be
374 * set. Is this true always?
381 pw_quote = talloc_asprintf(talloc_tos(), "\"%s\"", pw);
382 if (pw_quote == NULL) {
387 ret &= convert_string_talloc(talloc_tos(),
389 pw_quote, strlen(pw_quote),
390 &pw_utf16, &pw_utf16_len, false);
394 blob = data_blob_const(pw_utf16, pw_utf16_len);
396 ret &= tldap_add_mod_blobs(mem_ctx, pmods, pnum_mods,
398 "unicodePwd", &blob, 1);
399 TALLOC_FREE(pw_utf16);
400 TALLOC_FREE(pw_quote);
403 ret &= tldap_make_mod_fmt(
404 existing, mem_ctx, pmods, pnum_mods, "userAccountControl",
405 "%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
407 ret &= tldap_make_mod_fmt(
408 existing, mem_ctx, pmods, pnum_mods, "homeDirectory",
409 "%s", pdb_get_homedir(sam));
411 ret &= tldap_make_mod_fmt(
412 existing, mem_ctx, pmods, pnum_mods, "homeDrive",
413 "%s", pdb_get_dir_drive(sam));
415 ret &= tldap_make_mod_fmt(
416 existing, mem_ctx, pmods, pnum_mods, "scriptPath",
417 "%s", pdb_get_logon_script(sam));
419 ret &= tldap_make_mod_fmt(
420 existing, mem_ctx, pmods, pnum_mods, "profilePath",
421 "%s", pdb_get_profile_path(sam));
423 ret &= tldap_make_mod_fmt(
424 existing, mem_ctx, pmods, pnum_mods, "comment",
425 "%s", pdb_get_comment(sam));
427 ret &= tldap_make_mod_fmt(
428 existing, mem_ctx, pmods, pnum_mods, "description",
429 "%s", pdb_get_acct_desc(sam));
431 ret &= tldap_make_mod_fmt(
432 existing, mem_ctx, pmods, pnum_mods, "userWorkstations",
433 "%s", pdb_get_workstations(sam));
435 ret &= tldap_make_mod_fmt(
436 existing, mem_ctx, pmods, pnum_mods, "userParameters",
437 "%s", pdb_get_munged_dial(sam));
439 ret &= tldap_make_mod_fmt(
440 existing, mem_ctx, pmods, pnum_mods, "countryCode",
441 "%i", (int)pdb_get_country_code(sam));
443 ret &= tldap_make_mod_fmt(
444 existing, mem_ctx, pmods, pnum_mods, "codePage",
445 "%i", (int)pdb_get_code_page(sam));
447 ret &= pdb_ads_make_time_mod(
448 existing, mem_ctx, pmods, pnum_mods, "accountExpires",
449 (int)pdb_get_kickoff_time(sam));
451 ret &= tldap_make_mod_blob(
452 existing, mem_ctx, pmods, pnum_mods, "logonHours",
453 data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam)));
459 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
462 struct pdb_ads_samu_private **presult)
464 const char * attrs[] = {
465 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
466 "sAMAccountName", "displayName", "homeDirectory",
467 "homeDrive", "scriptPath", "profilePath", "description",
468 "userWorkstations", "comment", "userParameters", "objectSid",
469 "primaryGroupID", "userAccountControl", "logonHours",
470 "badPwdCount", "logonCount", "countryCode", "codePage",
471 "unicodePwd", "dBCSPwd" };
472 struct tldap_message **users;
474 struct pdb_ads_samu_private *result;
476 result = talloc(mem_ctx, struct pdb_ads_samu_private);
477 if (result == NULL) {
478 return NT_STATUS_NO_MEMORY;
481 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
482 attrs, ARRAY_SIZE(attrs), 0, result,
483 &users, "%s", filter);
484 if (rc != TLDAP_SUCCESS) {
485 DEBUG(10, ("ldap_search failed %s\n",
486 tldap_errstr(talloc_tos(), state->ld, rc)));
488 return NT_STATUS_LDAP(rc);
491 count = talloc_array_length(users);
493 DEBUG(10, ("Expected 1 user, got %d\n", count));
495 return NT_STATUS_NO_SUCH_USER;
498 result->ldapmsg = users[0];
499 if (!tldap_entry_dn(result->ldapmsg, &result->dn)) {
500 DEBUG(10, ("Could not extract dn\n"));
502 return NT_STATUS_INTERNAL_DB_CORRUPTION;
509 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
510 struct pdb_ads_state *state,
511 struct samu *sam_acct,
514 struct pdb_ads_samu_private *priv;
517 status = pdb_ads_getsamupriv(state, filter, sam_acct, &priv);
518 if (!NT_STATUS_IS_OK(status)) {
519 DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n",
524 status = pdb_ads_init_sam_from_priv(m, sam_acct, priv);
525 if (!NT_STATUS_IS_OK(status)) {
526 DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n",
532 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
536 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
537 struct samu *sam_acct,
538 const char *username)
540 struct pdb_ads_state *state = talloc_get_type_abort(
541 m->private_data, struct pdb_ads_state);
544 filter = talloc_asprintf(
545 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
547 NT_STATUS_HAVE_NO_MEMORY(filter);
549 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
552 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
553 struct samu *sam_acct,
554 const struct dom_sid *sid)
556 struct pdb_ads_state *state = talloc_get_type_abort(
557 m->private_data, struct pdb_ads_state);
558 char *sidstr, *filter;
560 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
561 NT_STATUS_HAVE_NO_MEMORY(sidstr);
563 filter = talloc_asprintf(
564 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
566 NT_STATUS_HAVE_NO_MEMORY(filter);
568 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
571 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
573 const char *name, uint32 acct_flags,
576 struct pdb_ads_state *state = talloc_get_type_abort(
577 m->private_data, struct pdb_ads_state);
578 struct tldap_context *ld;
579 const char *attrs[1] = { "objectSid" };
580 struct tldap_mod *mods = NULL;
582 struct tldap_message **user;
588 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
591 return NT_STATUS_NO_MEMORY;
594 ld = pdb_ads_ld(state);
596 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
599 /* TODO: Create machines etc */
602 ok &= tldap_make_mod_fmt(
603 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "user");
604 ok &= tldap_make_mod_fmt(
605 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
608 return NT_STATUS_NO_MEMORY;
612 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
613 if (rc != TLDAP_SUCCESS) {
614 DEBUG(10, ("ldap_add failed %s\n",
615 tldap_errstr(talloc_tos(), ld, rc)));
617 return NT_STATUS_LDAP(rc);
620 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
621 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
623 "(&(objectclass=user)(samaccountname=%s))",
625 if (rc != TLDAP_SUCCESS) {
626 DEBUG(10, ("Could not find just created user %s: %s\n",
627 name, tldap_errstr(talloc_tos(), state->ld, rc)));
629 return NT_STATUS_LDAP(rc);
632 if (talloc_array_length(user) != 1) {
633 DEBUG(10, ("Got %d users, expected one\n",
634 (int)talloc_array_length(user)));
636 return NT_STATUS_LDAP(rc);
639 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
640 DEBUG(10, ("Could not fetch objectSid from user %s\n",
643 return NT_STATUS_INTERNAL_DB_CORRUPTION;
646 sid_peek_rid(&sid, rid);
651 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
655 struct pdb_ads_state *state = talloc_get_type_abort(
656 m->private_data, struct pdb_ads_state);
658 struct tldap_context *ld;
662 ld = pdb_ads_ld(state);
664 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
667 status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
669 if (!NT_STATUS_IS_OK(status)) {
673 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
675 if (rc != TLDAP_SUCCESS) {
676 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
677 tldap_errstr(talloc_tos(), ld, rc)));
678 return NT_STATUS_LDAP(rc);
683 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
684 struct samu *sampass)
686 return NT_STATUS_NOT_IMPLEMENTED;
689 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
692 struct pdb_ads_state *state = talloc_get_type_abort(
693 m->private_data, struct pdb_ads_state);
694 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
695 struct tldap_context *ld;
696 struct tldap_mod *mods = NULL;
697 int rc, num_mods = 0;
699 ld = pdb_ads_ld(state);
701 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
704 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
705 &mods, &num_mods, sam)) {
706 return NT_STATUS_NO_MEMORY;
710 /* Nothing to do, just return success */
714 rc = tldap_modify(ld, priv->dn, mods, num_mods, NULL, 0,
717 if (rc != TLDAP_SUCCESS) {
718 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
719 tldap_errstr(talloc_tos(), ld, rc)));
720 return NT_STATUS_LDAP(rc);
726 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
727 struct samu *username)
729 return NT_STATUS_NOT_IMPLEMENTED;
732 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
733 struct samu *oldname,
736 return NT_STATUS_NOT_IMPLEMENTED;
739 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
740 struct samu *sam_acct,
743 return NT_STATUS_NOT_IMPLEMENTED;
746 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
749 struct pdb_ads_state *state = talloc_get_type_abort(
750 m->private_data, struct pdb_ads_state);
751 const char *attrs[4] = { "objectSid", "description", "samAccountName",
754 struct tldap_message **group;
758 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
759 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
760 &group, "%s", filter);
761 if (rc != TLDAP_SUCCESS) {
762 DEBUG(10, ("ldap_search failed %s\n",
763 tldap_errstr(talloc_tos(), state->ld, rc)));
764 return NT_STATUS_LDAP(rc);
766 if (talloc_array_length(group) != 1) {
767 DEBUG(10, ("Expected 1 user, got %d\n",
768 (int)talloc_array_length(group)));
769 return NT_STATUS_INTERNAL_DB_CORRUPTION;
772 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
773 return NT_STATUS_INTERNAL_DB_CORRUPTION;
775 map->gid = pdb_ads_sid2gid(&map->sid);
777 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
778 return NT_STATUS_INTERNAL_DB_CORRUPTION;
781 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
782 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
783 map->sid_name_use = SID_NAME_ALIAS;
785 case GTYPE_SECURITY_GLOBAL_GROUP:
786 map->sid_name_use = SID_NAME_DOM_GRP;
789 return NT_STATUS_INTERNAL_DB_CORRUPTION;
792 str = tldap_talloc_single_attribute(group[0], "samAccountName",
795 return NT_STATUS_INTERNAL_DB_CORRUPTION;
797 fstrcpy(map->nt_name, str);
800 str = tldap_talloc_single_attribute(group[0], "description",
803 fstrcpy(map->comment, str);
806 map->comment[0] = '\0';
813 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
819 filter = talloc_asprintf(talloc_tos(),
820 "(&(objectsid=%s)(objectclass=group))",
821 sid_string_talloc(talloc_tos(), &sid));
822 if (filter == NULL) {
823 return NT_STATUS_NO_MEMORY;
826 status = pdb_ads_getgrfilter(m, map, filter);
831 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
835 pdb_ads_gid_to_sid(m, gid, &sid);
836 return pdb_ads_getgrsid(m, map, sid);
839 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
845 filter = talloc_asprintf(talloc_tos(),
846 "(&(samaccountname=%s)(objectclass=group))",
848 if (filter == NULL) {
849 return NT_STATUS_NO_MEMORY;
852 status = pdb_ads_getgrfilter(m, map, filter);
857 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
858 TALLOC_CTX *mem_ctx, const char *name,
861 TALLOC_CTX *frame = talloc_stackframe();
862 struct pdb_ads_state *state = talloc_get_type_abort(
863 m->private_data, struct pdb_ads_state);
864 struct tldap_context *ld;
865 const char *attrs[1] = { "objectSid" };
867 struct tldap_mod *mods = NULL;
868 struct tldap_message **alias;
874 ld = pdb_ads_ld(state);
876 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
879 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
883 return NT_STATUS_NO_MEMORY;
886 ok &= tldap_make_mod_fmt(
887 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
889 ok &= tldap_make_mod_fmt(
890 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group");
891 ok &= tldap_make_mod_fmt(
892 NULL, talloc_tos(), &mods, &num_mods, "groupType",
893 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
897 return NT_STATUS_NO_MEMORY;
900 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
901 if (rc != TLDAP_SUCCESS) {
902 DEBUG(10, ("ldap_add failed %s\n",
903 tldap_errstr(talloc_tos(), state->ld, rc)));
905 return NT_STATUS_LDAP(rc);
908 rc = pdb_ads_search_fmt(
909 state, state->domaindn, TLDAP_SCOPE_SUB,
910 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
911 "(&(objectclass=group)(samaccountname=%s))", name);
912 if (rc != TLDAP_SUCCESS) {
913 DEBUG(10, ("Could not find just created alias %s: %s\n",
914 name, tldap_errstr(talloc_tos(), state->ld, rc)));
916 return NT_STATUS_LDAP(rc);
919 if (talloc_array_length(alias) != 1) {
920 DEBUG(10, ("Got %d alias, expected one\n",
921 (int)talloc_array_length(alias)));
923 return NT_STATUS_LDAP(rc);
926 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
927 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
930 return NT_STATUS_INTERNAL_DB_CORRUPTION;
933 sid_peek_rid(&sid, rid);
938 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
939 TALLOC_CTX *mem_ctx, uint32 rid)
941 struct pdb_ads_state *state = talloc_get_type_abort(
942 m->private_data, struct pdb_ads_state);
943 struct tldap_context *ld;
946 struct tldap_message **msg;
950 sid_compose(&sid, &state->domainsid, rid);
952 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
953 NT_STATUS_HAVE_NO_MEMORY(sidstr);
955 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
956 NULL, 0, 0, talloc_tos(), &msg,
957 ("(&(objectSid=%s)(objectClass=group))"),
960 if (rc != TLDAP_SUCCESS) {
961 DEBUG(10, ("ldap_search failed %s\n",
962 tldap_errstr(talloc_tos(), state->ld, rc)));
963 return NT_STATUS_LDAP(rc);
966 switch talloc_array_length(msg) {
968 return NT_STATUS_NO_SUCH_GROUP;
972 return NT_STATUS_INTERNAL_DB_CORRUPTION;
975 if (!tldap_entry_dn(msg[0], &dn)) {
977 return NT_STATUS_INTERNAL_DB_CORRUPTION;
980 ld = pdb_ads_ld(state);
983 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
986 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
988 if (rc != TLDAP_SUCCESS) {
989 DEBUG(10, ("ldap_delete failed: %s\n",
990 tldap_errstr(talloc_tos(), state->ld, rc)));
991 return NT_STATUS_LDAP(rc);
997 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
1000 return NT_STATUS_NOT_IMPLEMENTED;
1003 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
1006 return NT_STATUS_NOT_IMPLEMENTED;
1009 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
1012 return NT_STATUS_NOT_IMPLEMENTED;
1015 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
1016 const struct dom_sid *sid,
1017 enum lsa_SidType sid_name_use,
1018 GROUP_MAP **pp_rmap,
1019 size_t *p_num_entries,
1022 return NT_STATUS_NOT_IMPLEMENTED;
1025 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
1026 TALLOC_CTX *mem_ctx,
1027 const struct dom_sid *group,
1029 size_t *pnum_members)
1031 struct pdb_ads_state *state = talloc_get_type_abort(
1032 m->private_data, struct pdb_ads_state);
1033 const char *attrs[1] = { "member" };
1035 struct tldap_message **msg;
1036 int i, rc, num_members;
1040 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), group);
1041 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1043 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1044 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1045 &msg, "(objectsid=%s)", sidstr);
1046 TALLOC_FREE(sidstr);
1047 if (rc != TLDAP_SUCCESS) {
1048 DEBUG(10, ("ldap_search failed %s\n",
1049 tldap_errstr(talloc_tos(), state->ld, rc)));
1050 return NT_STATUS_LDAP(rc);
1052 switch talloc_array_length(msg) {
1054 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1059 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1063 if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
1066 return NT_STATUS_OK;
1069 members = talloc_array(mem_ctx, uint32_t, num_members);
1070 if (members == NULL) {
1071 return NT_STATUS_NO_MEMORY;
1074 for (i=0; i<num_members; i++) {
1076 if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
1077 || !sid_peek_rid(&sid, &members[i])) {
1078 TALLOC_FREE(members);
1079 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1083 *pmembers = members;
1084 *pnum_members = num_members;
1085 return NT_STATUS_OK;
1088 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
1089 TALLOC_CTX *mem_ctx,
1091 struct dom_sid **pp_sids,
1093 size_t *p_num_groups)
1095 struct pdb_ads_state *state = talloc_get_type_abort(
1096 m->private_data, struct pdb_ads_state);
1097 struct pdb_ads_samu_private *priv;
1098 const char *attrs[1] = { "objectSid" };
1099 struct tldap_message **groups;
1102 struct dom_sid *group_sids;
1105 priv = pdb_ads_get_samu_private(m, user);
1107 rc = pdb_ads_search_fmt(
1108 state, state->domaindn, TLDAP_SCOPE_SUB,
1109 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
1110 "(&(member=%s)(grouptype=%d)(objectclass=group))",
1111 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
1112 if (rc != TLDAP_SUCCESS) {
1113 DEBUG(10, ("ldap_search failed %s\n",
1114 tldap_errstr(talloc_tos(), state->ld, rc)));
1115 return NT_STATUS_LDAP(rc);
1117 count = talloc_array_length(groups);
1120 * This happens for artificial samu users
1122 DEBUG(10, ("Could not get pdb_ads_samu_private\n"));
1126 group_sids = talloc_array(mem_ctx, struct dom_sid, count+1);
1127 if (group_sids == NULL) {
1128 return NT_STATUS_NO_MEMORY;
1130 gids = talloc_array(mem_ctx, gid_t, count+1);
1132 TALLOC_FREE(group_sids);
1133 return NT_STATUS_NO_MEMORY;
1136 sid_copy(&group_sids[0], pdb_get_group_sid(user));
1137 if (!sid_to_gid(&group_sids[0], &gids[0])) {
1139 TALLOC_FREE(group_sids);
1140 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1144 for (i=0; i<count; i++) {
1145 if (!tldap_pull_binsid(groups[i], "objectSid",
1146 &group_sids[num_groups])) {
1149 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
1152 if (num_groups == count) {
1157 *pp_sids = group_sids;
1159 *p_num_groups = num_groups;
1160 return NT_STATUS_OK;
1163 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
1164 TALLOC_CTX *mem_ctx,
1167 return NT_STATUS_NOT_IMPLEMENTED;
1170 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
1171 TALLOC_CTX *mem_ctx,
1172 uint32 grouprid, uint32 memberrid,
1175 struct pdb_ads_state *state = talloc_get_type_abort(
1176 m->private_data, struct pdb_ads_state);
1177 TALLOC_CTX *frame = talloc_stackframe();
1178 struct tldap_context *ld;
1179 struct dom_sid groupsid, membersid;
1180 char *groupdn, *memberdn;
1181 struct tldap_mod *mods;
1186 ld = pdb_ads_ld(state);
1188 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1191 sid_compose(&groupsid, &state->domainsid, grouprid);
1192 sid_compose(&membersid, &state->domainsid, memberrid);
1194 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
1195 if (!NT_STATUS_IS_OK(status)) {
1197 return NT_STATUS_NO_SUCH_GROUP;
1199 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
1200 if (!NT_STATUS_IS_OK(status)) {
1202 return NT_STATUS_NO_SUCH_USER;
1208 if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op,
1209 "member", memberdn)) {
1211 return NT_STATUS_NO_MEMORY;
1214 rc = tldap_modify(ld, groupdn, mods, num_mods, NULL, 0, NULL, 0);
1216 if (rc != TLDAP_SUCCESS) {
1217 DEBUG(10, ("ldap_modify failed: %s\n",
1218 tldap_errstr(talloc_tos(), state->ld, rc)));
1219 if ((mod_op == TLDAP_MOD_ADD) &&
1220 (rc == TLDAP_ALREADY_EXISTS)) {
1221 return NT_STATUS_MEMBER_IN_GROUP;
1223 if ((mod_op == TLDAP_MOD_DELETE) &&
1224 (rc == TLDAP_UNWILLING_TO_PERFORM)) {
1225 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1227 return NT_STATUS_LDAP(rc);
1230 return NT_STATUS_OK;
1233 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
1234 TALLOC_CTX *mem_ctx,
1235 uint32 group_rid, uint32 member_rid)
1237 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1241 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
1242 TALLOC_CTX *mem_ctx,
1243 uint32 group_rid, uint32 member_rid)
1245 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1249 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
1250 const char *name, uint32 *rid)
1252 TALLOC_CTX *frame = talloc_stackframe();
1253 struct pdb_ads_state *state = talloc_get_type_abort(
1254 m->private_data, struct pdb_ads_state);
1255 struct tldap_context *ld;
1256 const char *attrs[1] = { "objectSid" };
1258 struct tldap_mod *mods = NULL;
1259 struct tldap_message **alias;
1265 ld = pdb_ads_ld(state);
1267 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1270 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1274 return NT_STATUS_NO_MEMORY;
1277 ok &= tldap_make_mod_fmt(
1278 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
1280 ok &= tldap_make_mod_fmt(
1281 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group");
1282 ok &= tldap_make_mod_fmt(
1283 NULL, talloc_tos(), &mods, &num_mods, "groupType",
1284 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1288 return NT_STATUS_NO_MEMORY;
1291 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1292 if (rc != TLDAP_SUCCESS) {
1293 DEBUG(10, ("ldap_add failed %s\n",
1294 tldap_errstr(talloc_tos(), state->ld, rc)));
1296 return NT_STATUS_LDAP(rc);
1299 rc = pdb_ads_search_fmt(
1300 state, state->domaindn, TLDAP_SCOPE_SUB,
1301 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1302 "(&(objectclass=group)(samaccountname=%s))", name);
1303 if (rc != TLDAP_SUCCESS) {
1304 DEBUG(10, ("Could not find just created alias %s: %s\n",
1305 name, tldap_errstr(talloc_tos(), state->ld, rc)));
1307 return NT_STATUS_LDAP(rc);
1310 if (talloc_array_length(alias) != 1) {
1311 DEBUG(10, ("Got %d alias, expected one\n",
1312 (int)talloc_array_length(alias)));
1314 return NT_STATUS_LDAP(rc);
1317 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1318 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1321 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1324 sid_peek_rid(&sid, rid);
1326 return NT_STATUS_OK;
1329 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1330 const struct dom_sid *sid)
1332 struct pdb_ads_state *state = talloc_get_type_abort(
1333 m->private_data, struct pdb_ads_state);
1334 struct tldap_context *ld;
1335 struct tldap_message **alias;
1336 char *sidstr, *dn = NULL;
1339 ld = pdb_ads_ld(state);
1341 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1344 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1345 if (sidstr == NULL) {
1346 return NT_STATUS_NO_MEMORY;
1349 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1350 NULL, 0, 0, talloc_tos(), &alias,
1351 "(&(objectSid=%s)(objectclass=group)"
1352 "(|(grouptype=%d)(grouptype=%d)))",
1353 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1354 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1355 TALLOC_FREE(sidstr);
1356 if (rc != TLDAP_SUCCESS) {
1357 DEBUG(10, ("ldap_search failed: %s\n",
1358 tldap_errstr(talloc_tos(), state->ld, rc)));
1359 return NT_STATUS_LDAP(rc);
1361 if (talloc_array_length(alias) != 1) {
1362 DEBUG(10, ("Expected 1 alias, got %d\n",
1363 (int)talloc_array_length(alias)));
1364 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1366 if (!tldap_entry_dn(alias[0], &dn)) {
1367 DEBUG(10, ("Could not get DN for alias %s\n",
1368 sid_string_dbg(sid)));
1369 return NT_STATUS_INTERNAL_ERROR;
1372 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
1373 if (rc != TLDAP_SUCCESS) {
1374 DEBUG(10, ("ldap_delete failed: %s\n",
1375 tldap_errstr(talloc_tos(), state->ld, rc)));
1376 return NT_STATUS_LDAP(rc);
1379 return NT_STATUS_OK;
1382 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1383 const struct dom_sid *sid,
1384 struct acct_info *info)
1386 struct pdb_ads_state *state = talloc_get_type_abort(
1387 m->private_data, struct pdb_ads_state);
1388 struct tldap_context *ld;
1389 const char *attrs[3] = { "objectSid", "description",
1391 struct tldap_message **msg;
1394 struct tldap_mod *mods;
1398 ld = pdb_ads_ld(state);
1400 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1403 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1404 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1406 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1407 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1408 &msg, "(&(objectSid=%s)(objectclass=group)"
1409 "(|(grouptype=%d)(grouptype=%d)))",
1410 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1411 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1412 TALLOC_FREE(sidstr);
1413 if (rc != TLDAP_SUCCESS) {
1414 DEBUG(10, ("ldap_search failed %s\n",
1415 tldap_errstr(talloc_tos(), state->ld, rc)));
1416 return NT_STATUS_LDAP(rc);
1418 switch talloc_array_length(msg) {
1420 return NT_STATUS_NO_SUCH_ALIAS;
1424 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1427 if (!tldap_entry_dn(msg[0], &dn)) {
1429 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1436 ok &= tldap_make_mod_fmt(
1437 msg[0], msg, &mods, &num_mods, "description",
1438 "%s", info->acct_desc);
1439 ok &= tldap_make_mod_fmt(
1440 msg[0], msg, &mods, &num_mods, "samAccountName",
1441 "%s", info->acct_name);
1444 return NT_STATUS_NO_MEMORY;
1446 if (num_mods == 0) {
1449 return NT_STATUS_OK;
1452 rc = tldap_modify(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1454 if (rc != TLDAP_SUCCESS) {
1455 DEBUG(10, ("ldap_modify failed: %s\n",
1456 tldap_errstr(talloc_tos(), state->ld, rc)));
1457 return NT_STATUS_LDAP(rc);
1459 return NT_STATUS_OK;
1462 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1463 const struct dom_sid *sid,
1464 TALLOC_CTX *mem_ctx, char **pdn)
1466 struct tldap_message **msg;
1470 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1471 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1473 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1474 NULL, 0, 0, talloc_tos(), &msg,
1475 "(objectsid=%s)", sidstr);
1476 TALLOC_FREE(sidstr);
1477 if (rc != TLDAP_SUCCESS) {
1478 DEBUG(10, ("ldap_search failed %s\n",
1479 tldap_errstr(talloc_tos(), state->ld, rc)));
1480 return NT_STATUS_LDAP(rc);
1483 switch talloc_array_length(msg) {
1485 return NT_STATUS_NOT_FOUND;
1489 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1492 if (!tldap_entry_dn(msg[0], &dn)) {
1493 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1496 dn = talloc_strdup(mem_ctx, dn);
1498 return NT_STATUS_NO_MEMORY;
1503 return NT_STATUS_OK;
1506 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1507 const struct dom_sid *alias,
1508 const struct dom_sid *member,
1511 struct pdb_ads_state *state = talloc_get_type_abort(
1512 m->private_data, struct pdb_ads_state);
1513 struct tldap_context *ld;
1514 TALLOC_CTX *frame = talloc_stackframe();
1515 struct tldap_mod *mods;
1518 char *aliasdn, *memberdn;
1521 ld = pdb_ads_ld(state);
1523 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1526 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1527 if (!NT_STATUS_IS_OK(status)) {
1528 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1529 sid_string_dbg(alias), nt_errstr(status)));
1531 return NT_STATUS_NO_SUCH_ALIAS;
1533 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1534 if (!NT_STATUS_IS_OK(status)) {
1535 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1536 sid_string_dbg(member), nt_errstr(status)));
1544 if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op,
1545 "member", memberdn)) {
1547 return NT_STATUS_NO_MEMORY;
1550 rc = tldap_modify(ld, aliasdn, mods, num_mods, NULL, 0, NULL, 0);
1552 if (rc != TLDAP_SUCCESS) {
1553 DEBUG(10, ("ldap_modify failed: %s\n",
1554 tldap_errstr(talloc_tos(), state->ld, rc)));
1555 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1556 return NT_STATUS_MEMBER_IN_ALIAS;
1558 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1559 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1561 return NT_STATUS_LDAP(rc);
1564 return NT_STATUS_OK;
1567 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1568 const struct dom_sid *alias,
1569 const struct dom_sid *member)
1571 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1574 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1575 const struct dom_sid *alias,
1576 const struct dom_sid *member)
1578 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1581 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
1582 struct dom_sid *psid)
1584 const char *attrs[1] = { "objectSid" };
1585 struct tldap_message **msg;
1591 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1592 dnblob->data, dnblob->length, &dn, &len,
1596 rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
1597 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1598 &msg, "(objectclass=*)");
1600 if (talloc_array_length(msg) != 1) {
1601 DEBUG(10, ("Got %d objects, expected one\n",
1602 (int)talloc_array_length(msg)));
1607 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1612 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1613 const struct dom_sid *alias,
1614 TALLOC_CTX *mem_ctx,
1615 struct dom_sid **pmembers,
1616 size_t *pnum_members)
1618 struct pdb_ads_state *state = talloc_get_type_abort(
1619 m->private_data, struct pdb_ads_state);
1620 const char *attrs[1] = { "member" };
1622 struct tldap_message **msg;
1623 int i, rc, num_members;
1625 struct dom_sid *members;
1627 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), alias);
1628 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1630 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1631 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1632 &msg, "(objectsid=%s)", sidstr);
1633 TALLOC_FREE(sidstr);
1634 if (rc != TLDAP_SUCCESS) {
1635 DEBUG(10, ("ldap_search failed %s\n",
1636 tldap_errstr(talloc_tos(), state->ld, rc)));
1637 return NT_STATUS_LDAP(rc);
1639 switch talloc_array_length(msg) {
1641 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1646 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1650 if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
1651 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1654 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1655 if (members == NULL) {
1656 return NT_STATUS_NO_MEMORY;
1659 for (i=0; i<num_members; i++) {
1660 if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
1661 TALLOC_FREE(members);
1662 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1666 *pmembers = members;
1667 *pnum_members = num_members;
1668 return NT_STATUS_OK;
1671 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1672 TALLOC_CTX *mem_ctx,
1673 const struct dom_sid *domain_sid,
1674 const struct dom_sid *members,
1676 uint32_t **palias_rids,
1677 size_t *pnum_alias_rids)
1679 struct pdb_ads_state *state = talloc_get_type_abort(
1680 m->private_data, struct pdb_ads_state);
1681 const char *attrs[1] = { "objectSid" };
1682 struct tldap_message **msg = NULL;
1683 uint32_t *alias_rids = NULL;
1684 size_t num_alias_rids = 0;
1686 bool got_members = false;
1691 * TODO: Get the filter right so that we only get the aliases from
1692 * either the SAM or BUILTIN
1695 filter = talloc_asprintf(talloc_tos(),
1696 "(&(|(grouptype=%d)(grouptype=%d))"
1697 "(objectclass=group)(|",
1698 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1699 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1700 if (filter == NULL) {
1701 return NT_STATUS_NO_MEMORY;
1704 for (i=0; i<num_members; i++) {
1707 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1708 if (!NT_STATUS_IS_OK(status)) {
1709 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1710 sid_string_dbg(&members[i]),
1711 nt_errstr(status)));
1714 filter = talloc_asprintf_append_buffer(
1715 filter, "(member=%s)", dn);
1717 if (filter == NULL) {
1718 return NT_STATUS_NO_MEMORY;
1727 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1728 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1729 &msg, "%s))", filter);
1730 TALLOC_FREE(filter);
1731 if (rc != TLDAP_SUCCESS) {
1732 DEBUG(10, ("tldap_search failed %s\n",
1733 tldap_errstr(talloc_tos(), state->ld, rc)));
1734 return NT_STATUS_LDAP(rc);
1737 count = talloc_array_length(msg);
1742 alias_rids = talloc_array(mem_ctx, uint32_t, count);
1743 if (alias_rids == NULL) {
1745 return NT_STATUS_NO_MEMORY;
1748 for (i=0; i<count; i++) {
1751 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1752 DEBUG(10, ("Could not pull SID for member %d\n", i));
1755 if (sid_peek_check_rid(domain_sid, &sid,
1756 &alias_rids[num_alias_rids])) {
1757 num_alias_rids += 1;
1762 *palias_rids = alias_rids;
1763 *pnum_alias_rids = 0;
1764 return NT_STATUS_OK;
1767 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1768 const struct dom_sid *domain_sid,
1772 enum lsa_SidType *lsa_attrs)
1774 struct pdb_ads_state *state = talloc_get_type_abort(
1775 m->private_data, struct pdb_ads_state);
1776 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1779 if (num_rids == 0) {
1780 return NT_STATUS_NONE_MAPPED;
1785 for (i=0; i<num_rids; i++) {
1787 struct tldap_message **msg;
1792 lsa_attrs[i] = SID_NAME_UNKNOWN;
1794 sid_compose(&sid, domain_sid, rids[i]);
1796 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
1797 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1799 rc = pdb_ads_search_fmt(state, state->domaindn,
1800 TLDAP_SCOPE_SUB, attrs,
1801 ARRAY_SIZE(attrs), 0, talloc_tos(),
1802 &msg, "(objectsid=%s)", sidstr);
1803 TALLOC_FREE(sidstr);
1804 if (rc != TLDAP_SUCCESS) {
1805 DEBUG(10, ("ldap_search failed %s\n",
1806 tldap_errstr(talloc_tos(), state->ld, rc)));
1810 switch talloc_array_length(msg) {
1812 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1817 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1820 names[i] = tldap_talloc_single_attribute(
1821 msg[0], "samAccountName", talloc_tos());
1822 if (names[i] == NULL) {
1823 DEBUG(10, ("no samAccountName\n"));
1826 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1827 DEBUG(10, ("no samAccountType"));
1830 lsa_attrs[i] = ds_atype_map(attr);
1834 if (num_mapped == 0) {
1835 return NT_STATUS_NONE_MAPPED;
1837 if (num_mapped < num_rids) {
1838 return STATUS_SOME_UNMAPPED;
1840 return NT_STATUS_OK;
1843 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1844 const struct dom_sid *domain_sid,
1846 const char **pp_names,
1848 enum lsa_SidType *attrs)
1850 return NT_STATUS_NOT_IMPLEMENTED;
1853 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1854 enum pdb_policy_type type,
1857 return account_policy_get(type, value)
1858 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1861 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1862 enum pdb_policy_type type,
1865 return account_policy_set(type, value)
1866 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1869 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1872 return NT_STATUS_NOT_IMPLEMENTED;
1875 struct pdb_ads_search_state {
1876 uint32_t acct_flags;
1877 struct samr_displayentry *entries;
1878 uint32_t num_entries;
1883 static bool pdb_ads_next_entry(struct pdb_search *search,
1884 struct samr_displayentry *entry)
1886 struct pdb_ads_search_state *state = talloc_get_type_abort(
1887 search->private_data, struct pdb_ads_search_state);
1889 if (state->current == state->num_entries) {
1893 entry->idx = state->entries[state->current].idx;
1894 entry->rid = state->entries[state->current].rid;
1895 entry->acct_flags = state->entries[state->current].acct_flags;
1897 entry->account_name = talloc_strdup(
1898 search, state->entries[state->current].account_name);
1899 entry->fullname = talloc_strdup(
1900 search, state->entries[state->current].fullname);
1901 entry->description = talloc_strdup(
1902 search, state->entries[state->current].description);
1904 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1905 || (entry->description == NULL)) {
1906 DEBUG(0, ("talloc_strdup failed\n"));
1910 state->current += 1;
1914 static void pdb_ads_search_end(struct pdb_search *search)
1916 struct pdb_ads_search_state *state = talloc_get_type_abort(
1917 search->private_data, struct pdb_ads_search_state);
1921 static bool pdb_ads_search_filter(struct pdb_methods *m,
1922 struct pdb_search *search,
1924 struct pdb_ads_search_state **pstate)
1926 struct pdb_ads_state *state = talloc_get_type_abort(
1927 m->private_data, struct pdb_ads_state);
1928 struct pdb_ads_search_state *sstate;
1929 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1930 "userAccountControl", "description" };
1931 struct tldap_message **users;
1932 int i, rc, num_users;
1934 sstate = talloc_zero(search, struct pdb_ads_search_state);
1935 if (sstate == NULL) {
1939 rc = pdb_ads_search_fmt(
1940 state, state->domaindn, TLDAP_SCOPE_SUB,
1941 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1943 if (rc != TLDAP_SUCCESS) {
1944 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1945 tldap_errstr(talloc_tos(), state->ld, rc)));
1949 num_users = talloc_array_length(users);
1951 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1953 if (sstate->entries == NULL) {
1954 DEBUG(10, ("talloc failed\n"));
1958 sstate->num_entries = 0;
1960 for (i=0; i<num_users; i++) {
1961 struct samr_displayentry *e;
1965 e = &sstate->entries[sstate->num_entries];
1967 e->idx = sstate->num_entries;
1968 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1969 DEBUG(10, ("Could not pull sid\n"));
1972 sid_peek_rid(&sid, &e->rid);
1974 if (tldap_pull_uint32(users[i], "userAccountControl", &ctrl)) {
1975 e->acct_flags = ds_uf2acb(ctrl);
1976 if (e->acct_flags & (ACB_WSTRUST|ACB_SVRTRUST)) {
1977 e->acct_flags |= ACB_NORMAL;
1980 e->acct_flags = ACB_NORMAL;
1983 if (e->rid == DOMAIN_RID_GUEST) {
1985 * Guest is specially crafted in s3. Make
1986 * QueryDisplayInfo match QueryUserInfo
1988 e->account_name = lp_guestaccount();
1989 e->fullname = lp_guestaccount();
1990 e->description = "";
1991 e->acct_flags = ACB_NORMAL;
1993 e->account_name = tldap_talloc_single_attribute(
1994 users[i], "samAccountName", sstate->entries);
1995 e->fullname = tldap_talloc_single_attribute(
1996 users[i], "displayName", sstate->entries);
1997 e->description = tldap_talloc_single_attribute(
1998 users[i], "description", sstate->entries);
2000 if (e->account_name == NULL) {
2003 if (e->fullname == NULL) {
2006 if (e->description == NULL) {
2007 e->description = "";
2010 sstate->num_entries += 1;
2011 if (sstate->num_entries >= num_users) {
2016 search->private_data = sstate;
2017 search->next_entry = pdb_ads_next_entry;
2018 search->search_end = pdb_ads_search_end;
2023 static bool pdb_ads_search_users(struct pdb_methods *m,
2024 struct pdb_search *search,
2027 struct pdb_ads_search_state *sstate;
2031 if (acct_flags & ACB_NORMAL) {
2032 filter = talloc_asprintf(
2034 "(&(objectclass=user)(sAMAccountType=%d))",
2035 ATYPE_NORMAL_ACCOUNT);
2036 } else if (acct_flags & ACB_WSTRUST) {
2037 filter = talloc_asprintf(
2039 "(&(objectclass=user)(sAMAccountType=%d))",
2040 ATYPE_WORKSTATION_TRUST);
2042 filter = talloc_strdup(talloc_tos(), "(objectclass=user)");
2044 if (filter == NULL) {
2048 ret = pdb_ads_search_filter(m, search, filter, &sstate);
2049 TALLOC_FREE(filter);
2053 sstate->acct_flags = acct_flags;
2057 static bool pdb_ads_search_groups(struct pdb_methods *m,
2058 struct pdb_search *search)
2060 struct pdb_ads_search_state *sstate;
2064 filter = talloc_asprintf(talloc_tos(),
2065 "(&(grouptype=%d)(objectclass=group))",
2066 GTYPE_SECURITY_GLOBAL_GROUP);
2067 if (filter == NULL) {
2070 ret = pdb_ads_search_filter(m, search, filter, &sstate);
2071 TALLOC_FREE(filter);
2075 sstate->acct_flags = 0;
2079 static bool pdb_ads_search_aliases(struct pdb_methods *m,
2080 struct pdb_search *search,
2081 const struct dom_sid *sid)
2083 struct pdb_ads_search_state *sstate;
2087 filter = talloc_asprintf(
2088 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
2089 sid_check_is_builtin(sid)
2090 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2091 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
2093 if (filter == NULL) {
2096 ret = pdb_ads_search_filter(m, search, filter, &sstate);
2097 TALLOC_FREE(filter);
2101 sstate->acct_flags = 0;
2105 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
2106 struct dom_sid *sid)
2108 struct pdb_ads_state *state = talloc_get_type_abort(
2109 m->private_data, struct pdb_ads_state);
2110 sid_compose(sid, &state->domainsid, uid);
2114 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
2115 struct dom_sid *sid)
2117 struct pdb_ads_state *state = talloc_get_type_abort(
2118 m->private_data, struct pdb_ads_state);
2119 sid_compose(sid, &state->domainsid, gid);
2123 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2124 union unid_t *id, enum lsa_SidType *type)
2126 struct pdb_ads_state *state = talloc_get_type_abort(
2127 m->private_data, struct pdb_ads_state);
2128 struct tldap_message **msg;
2134 * This is a big, big hack: Just hard-code the rid as uid/gid.
2137 sid_peek_rid(sid, &rid);
2139 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
2140 if (sidstr == NULL) {
2144 rc = pdb_ads_search_fmt(
2145 state, state->domaindn, TLDAP_SCOPE_SUB,
2146 NULL, 0, 0, talloc_tos(), &msg,
2147 "(&(objectsid=%s)(objectclass=user))", sidstr);
2148 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
2150 *type = SID_NAME_USER;
2151 TALLOC_FREE(sidstr);
2155 rc = pdb_ads_search_fmt(
2156 state, state->domaindn, TLDAP_SCOPE_SUB,
2157 NULL, 0, 0, talloc_tos(), &msg,
2158 "(&(objectsid=%s)(objectclass=group))", sidstr);
2159 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
2161 *type = SID_NAME_DOM_GRP;
2162 TALLOC_FREE(sidstr);
2166 TALLOC_FREE(sidstr);
2170 static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
2172 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2175 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
2180 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
2181 const char *domain, char** pwd,
2182 struct dom_sid *sid,
2183 time_t *pass_last_set_time)
2188 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
2189 const char* domain, const char* pwd,
2190 const struct dom_sid *sid)
2195 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
2201 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
2202 TALLOC_CTX *mem_ctx,
2203 uint32 *num_domains,
2204 struct trustdom_info ***domains)
2208 return NT_STATUS_OK;
2211 static void pdb_ads_init_methods(struct pdb_methods *m)
2214 m->get_domain_info = pdb_ads_get_domain_info;
2215 m->getsampwnam = pdb_ads_getsampwnam;
2216 m->getsampwsid = pdb_ads_getsampwsid;
2217 m->create_user = pdb_ads_create_user;
2218 m->delete_user = pdb_ads_delete_user;
2219 m->add_sam_account = pdb_ads_add_sam_account;
2220 m->update_sam_account = pdb_ads_update_sam_account;
2221 m->delete_sam_account = pdb_ads_delete_sam_account;
2222 m->rename_sam_account = pdb_ads_rename_sam_account;
2223 m->update_login_attempts = pdb_ads_update_login_attempts;
2224 m->getgrsid = pdb_ads_getgrsid;
2225 m->getgrgid = pdb_ads_getgrgid;
2226 m->getgrnam = pdb_ads_getgrnam;
2227 m->create_dom_group = pdb_ads_create_dom_group;
2228 m->delete_dom_group = pdb_ads_delete_dom_group;
2229 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
2230 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
2231 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
2232 m->enum_group_mapping = pdb_ads_enum_group_mapping;
2233 m->enum_group_members = pdb_ads_enum_group_members;
2234 m->enum_group_memberships = pdb_ads_enum_group_memberships;
2235 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
2236 m->add_groupmem = pdb_ads_add_groupmem;
2237 m->del_groupmem = pdb_ads_del_groupmem;
2238 m->create_alias = pdb_ads_create_alias;
2239 m->delete_alias = pdb_ads_delete_alias;
2240 m->get_aliasinfo = pdb_default_get_aliasinfo;
2241 m->set_aliasinfo = pdb_ads_set_aliasinfo;
2242 m->add_aliasmem = pdb_ads_add_aliasmem;
2243 m->del_aliasmem = pdb_ads_del_aliasmem;
2244 m->enum_aliasmem = pdb_ads_enum_aliasmem;
2245 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
2246 m->lookup_rids = pdb_ads_lookup_rids;
2247 m->lookup_names = pdb_ads_lookup_names;
2248 m->get_account_policy = pdb_ads_get_account_policy;
2249 m->set_account_policy = pdb_ads_set_account_policy;
2250 m->get_seq_num = pdb_ads_get_seq_num;
2251 m->search_users = pdb_ads_search_users;
2252 m->search_groups = pdb_ads_search_groups;
2253 m->search_aliases = pdb_ads_search_aliases;
2254 m->uid_to_sid = pdb_ads_uid_to_sid;
2255 m->gid_to_sid = pdb_ads_gid_to_sid;
2256 m->sid_to_id = pdb_ads_sid_to_id;
2257 m->capabilities = pdb_ads_capabilities;
2258 m->new_rid = pdb_ads_new_rid;
2259 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2260 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2261 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2262 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2265 static void free_private_data(void **vp)
2267 struct pdb_ads_state *state = talloc_get_type_abort(
2268 *vp, struct pdb_ads_state);
2270 TALLOC_FREE(state->ld);
2275 this is used to catch debug messages from events
2277 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2278 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
2280 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2281 const char *fmt, va_list ap)
2283 int samba_level = -1;
2286 case TLDAP_DEBUG_FATAL:
2289 case TLDAP_DEBUG_ERROR:
2292 case TLDAP_DEBUG_WARNING:
2295 case TLDAP_DEBUG_TRACE:
2300 if (vasprintf(&s, fmt, ap) == -1) {
2303 DEBUG(samba_level, ("tldap: %s", s));
2307 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2312 if (tldap_connection_ok(state->ld)) {
2315 TALLOC_FREE(state->ld);
2317 status = open_socket_out(
2318 (struct sockaddr_storage *)(void *)&state->socket_address,
2320 if (!NT_STATUS_IS_OK(status)) {
2321 DEBUG(10, ("Could not connect to %s: %s\n",
2322 state->socket_address.sun_path, nt_errstr(status)));
2326 set_blocking(fd, false);
2328 state->ld = tldap_context_create(state, fd);
2329 if (state->ld == NULL) {
2333 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2338 int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2339 int scope, const char *attrs[], int num_attrs,
2341 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2342 const char *fmt, ...)
2344 struct tldap_context *ld;
2348 ld = pdb_ads_ld(state);
2350 return TLDAP_SERVER_DOWN;
2354 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2355 mem_ctx, res, fmt, ap);
2358 if (ret != TLDAP_SERVER_DOWN) {
2363 ld = pdb_ads_ld(state);
2365 return TLDAP_SERVER_DOWN;
2369 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2370 mem_ctx, res, fmt, ap);
2375 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2376 const char *location)
2378 const char *domain_attrs[2] = { "objectSid", "objectGUID" };
2379 const char *ncname_attrs[1] = { "netbiosname" };
2380 struct tldap_context *ld;
2381 struct tldap_message *rootdse, **domain, **ncname;
2382 TALLOC_CTX *frame = talloc_stackframe();
2387 ZERO_STRUCT(state->socket_address);
2388 state->socket_address.sun_family = AF_UNIX;
2389 strlcpy(state->socket_address.sun_path, location,
2390 sizeof(state->socket_address.sun_path));
2392 ld = pdb_ads_ld(state);
2394 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2398 rc = tldap_fetch_rootdse(ld);
2399 if (rc != TLDAP_SUCCESS) {
2400 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2401 tldap_errstr(talloc_tos(), state->ld, rc)));
2402 status = NT_STATUS_LDAP(rc);
2405 rootdse = tldap_rootdse(state->ld);
2407 state->domaindn = tldap_talloc_single_attribute(
2408 rootdse, "defaultNamingContext", state);
2409 if (state->domaindn == NULL) {
2410 DEBUG(10, ("Could not get defaultNamingContext\n"));
2411 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2414 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2416 state->configdn = tldap_talloc_single_attribute(
2417 rootdse, "configurationNamingContext", state);
2418 if (state->domaindn == NULL) {
2419 DEBUG(10, ("Could not get configurationNamingContext\n"));
2420 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2423 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2426 * Figure out our domain's SID
2428 rc = pdb_ads_search_fmt(
2429 state, state->domaindn, TLDAP_SCOPE_BASE,
2430 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2431 talloc_tos(), &domain, "(objectclass=*)");
2432 if (rc != TLDAP_SUCCESS) {
2433 DEBUG(10, ("Could not retrieve domain: %s\n",
2434 tldap_errstr(talloc_tos(), state->ld, rc)));
2435 status = NT_STATUS_LDAP(rc);
2439 num_domains = talloc_array_length(domain);
2440 if (num_domains != 1) {
2441 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2442 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2445 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2446 DEBUG(10, ("Could not retrieve domain SID\n"));
2447 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2450 if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) {
2451 DEBUG(10, ("Could not retrieve domain GUID\n"));
2452 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2455 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2458 * Figure out our domain's short name
2460 rc = pdb_ads_search_fmt(
2461 state, state->configdn, TLDAP_SCOPE_SUB,
2462 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2463 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2464 if (rc != TLDAP_SUCCESS) {
2465 DEBUG(10, ("Could not retrieve ncname: %s\n",
2466 tldap_errstr(talloc_tos(), state->ld, rc)));
2467 status = NT_STATUS_LDAP(rc);
2470 if (talloc_array_length(ncname) != 1) {
2471 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2475 state->netbiosname = tldap_talloc_single_attribute(
2476 ncname[0], "netbiosname", state);
2477 if (state->netbiosname == NULL) {
2478 DEBUG(10, ("Could not get netbiosname\n"));
2479 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2482 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2484 if (!strequal(lp_workgroup(), state->netbiosname)) {
2485 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2486 state->netbiosname, lp_workgroup()));
2487 status = NT_STATUS_NO_SUCH_DOMAIN;
2491 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2493 status = NT_STATUS_OK;
2499 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2500 const char *location)
2502 struct pdb_methods *m;
2503 struct pdb_ads_state *state;
2507 m = talloc(NULL, struct pdb_methods);
2509 return NT_STATUS_NO_MEMORY;
2511 state = talloc_zero(m, struct pdb_ads_state);
2512 if (state == NULL) {
2515 m->private_data = state;
2516 m->free_private_data = free_private_data;
2517 pdb_ads_init_methods(m);
2519 if (location == NULL) {
2520 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2524 if (location == NULL) {
2528 status = pdb_ads_connect(state, location);
2529 if (!NT_STATUS_IS_OK(status)) {
2530 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2535 return NT_STATUS_OK;
2537 status = NT_STATUS_NO_MEMORY;
2543 NTSTATUS pdb_ads_init(void);
2544 NTSTATUS pdb_ads_init(void)
2546 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",