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"
28 #include "../libds/common/flag_mapping.h"
30 struct pdb_ads_state {
31 struct sockaddr_un socket_address;
32 struct tldap_context *ld;
33 struct dom_sid domainsid;
34 struct GUID domainguid;
40 struct pdb_ads_samu_private {
42 struct tldap_message *ldapmsg;
45 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
47 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
48 struct dom_sid *psid);
49 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
50 const struct dom_sid *sid,
51 TALLOC_CTX *mem_ctx, char **pdn);
52 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state);
53 static int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
54 int scope, const char *attrs[], int num_attrs,
56 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
57 const char *fmt, ...);
58 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
61 struct pdb_ads_samu_private **presult);
63 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
68 if (!tldap_pull_uint64(msg, attr, &tmp)) {
71 *ptime = nt_time_to_unix(tmp);
75 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
78 sid_peek_rid(sid, &rid);
82 static char *pdb_ads_domaindn2dns(TALLOC_CTX *mem_ctx, char *dn)
86 result = talloc_string_sub2(mem_ctx, dn, "DC=", "", false, false,
92 while ((p = strchr_m(result, ',')) != NULL) {
99 static struct pdb_domain_info *pdb_ads_get_domain_info(
100 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
102 struct pdb_ads_state *state = talloc_get_type_abort(
103 m->private_data, struct pdb_ads_state);
104 struct pdb_domain_info *info;
105 struct tldap_message *rootdse;
108 info = talloc(mem_ctx, struct pdb_domain_info);
112 info->name = talloc_strdup(info, state->netbiosname);
113 if (info->name == NULL) {
116 info->dns_domain = pdb_ads_domaindn2dns(info, state->domaindn);
117 if (info->dns_domain == NULL) {
121 rootdse = tldap_rootdse(state->ld);
122 tmp = tldap_talloc_single_attribute(rootdse, "rootDomainNamingContext",
127 info->dns_forest = pdb_ads_domaindn2dns(info, tmp);
129 if (info->dns_forest == NULL) {
132 info->sid = state->domainsid;
133 info->guid = state->domainguid;
141 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
142 struct pdb_methods *m, struct samu *sam)
144 struct pdb_ads_state *state = talloc_get_type_abort(
145 m->private_data, struct pdb_ads_state);
146 struct pdb_ads_samu_private *result;
147 char *sidstr, *filter;
150 result = (struct pdb_ads_samu_private *)
151 pdb_get_backend_private_data(sam, m);
153 if (result != NULL) {
154 return talloc_get_type_abort(
155 result, struct pdb_ads_samu_private);
158 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), pdb_get_user_sid(sam));
159 if (sidstr == NULL) {
163 filter = talloc_asprintf(
164 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
166 if (filter == NULL) {
170 status = pdb_ads_getsamupriv(state, filter, sam, &result);
172 if (!NT_STATUS_IS_OK(status)) {
179 static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m,
181 struct pdb_ads_samu_private *priv)
183 struct pdb_ads_state *state = talloc_get_type_abort(
184 m->private_data, struct pdb_ads_state);
185 TALLOC_CTX *frame = talloc_stackframe();
186 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
187 struct tldap_message *entry = priv->ldapmsg;
195 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
197 DEBUG(10, ("no samAccountName\n"));
200 pdb_set_username(sam, str, PDB_SET);
202 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
203 pdb_set_logon_time(sam, tmp_time, PDB_SET);
205 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
206 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
208 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
209 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
211 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
212 pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
215 str = tldap_talloc_single_attribute(entry, "displayName",
218 pdb_set_fullname(sam, str, PDB_SET);
221 str = tldap_talloc_single_attribute(entry, "homeDirectory",
224 pdb_set_homedir(sam, str, PDB_SET);
227 str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
229 pdb_set_dir_drive(sam, str, PDB_SET);
232 str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
234 pdb_set_logon_script(sam, str, PDB_SET);
237 str = tldap_talloc_single_attribute(entry, "profilePath",
240 pdb_set_profile_path(sam, str, PDB_SET);
243 str = tldap_talloc_single_attribute(entry, "profilePath",
246 pdb_set_profile_path(sam, str, PDB_SET);
249 str = tldap_talloc_single_attribute(entry, "comment",
252 pdb_set_comment(sam, str, PDB_SET);
255 str = tldap_talloc_single_attribute(entry, "description",
258 pdb_set_acct_desc(sam, str, PDB_SET);
261 str = tldap_talloc_single_attribute(entry, "userWorkstations",
264 pdb_set_workstations(sam, str, PDB_SET);
267 str = tldap_talloc_single_attribute(entry, "userParameters",
270 pdb_set_munged_dial(sam, str, PDB_SET);
273 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
274 DEBUG(10, ("Could not pull SID\n"));
277 pdb_set_user_sid(sam, &sid, PDB_SET);
279 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
280 DEBUG(10, ("Could not pull userAccountControl\n"));
283 pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
285 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
286 if (blob.length != NT_HASH_LEN) {
287 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
288 (int)blob.length, NT_HASH_LEN));
291 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
294 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
295 if (blob.length != LM_HASH_LEN) {
296 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
297 (int)blob.length, LM_HASH_LEN));
300 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
303 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
304 sid_compose(&sid, &state->domainsid, n);
305 pdb_set_group_sid(sam, &sid, PDB_SET);
309 if (tldap_pull_uint32(entry, "countryCode", &i)) {
310 pdb_set_country_code(sam, i, PDB_SET);
313 if (tldap_pull_uint32(entry, "codePage", &i)) {
314 pdb_set_code_page(sam, i, PDB_SET);
317 if (tldap_get_single_valueblob(entry, "logonHours", &blob)) {
319 if (blob.length > MAX_HOURS_LEN) {
320 status = NT_STATUS_INVALID_PARAMETER;
323 pdb_set_logon_divs(sam, blob.length * 8, PDB_SET);
324 pdb_set_hours_len(sam, blob.length, PDB_SET);
325 pdb_set_hours(sam, blob.data, blob.length, PDB_SET);
329 pdb_set_logon_divs(sam, sizeof(hours)/8, PDB_SET);
330 pdb_set_hours_len(sam, sizeof(hours), PDB_SET);
331 memset(hours, 0xff, sizeof(hours));
332 pdb_set_hours(sam, hours, sizeof(hours), PDB_SET);
335 status = NT_STATUS_OK;
341 static bool pdb_ads_make_time_mod(struct tldap_message *existing,
343 struct tldap_mod **pmods, int *pnum_mods,
344 const char *attrib, time_t t)
348 unix_to_nt_time(&nt_time, t);
350 return tldap_make_mod_fmt(
351 existing, mem_ctx, pmods, pnum_mods, attrib,
355 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
356 struct tldap_message *existing,
358 struct tldap_mod **pmods, int *pnum_mods,
365 /* TODO: All fields :-) */
367 ret &= tldap_make_mod_fmt(
368 existing, mem_ctx, pmods, pnum_mods, "displayName",
369 "%s", pdb_get_fullname(sam));
371 pw = pdb_get_plaintext_passwd(sam);
374 * If we have the plain text pw, this is probably about to be
375 * set. Is this true always?
382 pw_quote = talloc_asprintf(talloc_tos(), "\"%s\"", pw);
383 if (pw_quote == NULL) {
388 ret &= convert_string_talloc(talloc_tos(),
390 pw_quote, strlen(pw_quote),
391 &pw_utf16, &pw_utf16_len);
395 blob = data_blob_const(pw_utf16, pw_utf16_len);
397 ret &= tldap_add_mod_blobs(mem_ctx, pmods, pnum_mods,
399 "unicodePwd", &blob, 1);
400 TALLOC_FREE(pw_utf16);
401 TALLOC_FREE(pw_quote);
404 ret &= tldap_make_mod_fmt(
405 existing, mem_ctx, pmods, pnum_mods, "userAccountControl",
406 "%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
408 ret &= tldap_make_mod_fmt(
409 existing, mem_ctx, pmods, pnum_mods, "homeDirectory",
410 "%s", pdb_get_homedir(sam));
412 ret &= tldap_make_mod_fmt(
413 existing, mem_ctx, pmods, pnum_mods, "homeDrive",
414 "%s", pdb_get_dir_drive(sam));
416 ret &= tldap_make_mod_fmt(
417 existing, mem_ctx, pmods, pnum_mods, "scriptPath",
418 "%s", pdb_get_logon_script(sam));
420 ret &= tldap_make_mod_fmt(
421 existing, mem_ctx, pmods, pnum_mods, "profilePath",
422 "%s", pdb_get_profile_path(sam));
424 ret &= tldap_make_mod_fmt(
425 existing, mem_ctx, pmods, pnum_mods, "comment",
426 "%s", pdb_get_comment(sam));
428 ret &= tldap_make_mod_fmt(
429 existing, mem_ctx, pmods, pnum_mods, "description",
430 "%s", pdb_get_acct_desc(sam));
432 ret &= tldap_make_mod_fmt(
433 existing, mem_ctx, pmods, pnum_mods, "userWorkstations",
434 "%s", pdb_get_workstations(sam));
436 ret &= tldap_make_mod_fmt(
437 existing, mem_ctx, pmods, pnum_mods, "userParameters",
438 "%s", pdb_get_munged_dial(sam));
440 ret &= tldap_make_mod_fmt(
441 existing, mem_ctx, pmods, pnum_mods, "countryCode",
442 "%i", (int)pdb_get_country_code(sam));
444 ret &= tldap_make_mod_fmt(
445 existing, mem_ctx, pmods, pnum_mods, "codePage",
446 "%i", (int)pdb_get_code_page(sam));
448 ret &= pdb_ads_make_time_mod(
449 existing, mem_ctx, pmods, pnum_mods, "accountExpires",
450 (int)pdb_get_kickoff_time(sam));
452 ret &= tldap_make_mod_blob(
453 existing, mem_ctx, pmods, pnum_mods, "logonHours",
454 data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam)));
460 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
463 struct pdb_ads_samu_private **presult)
465 const char * attrs[] = {
466 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
467 "sAMAccountName", "displayName", "homeDirectory",
468 "homeDrive", "scriptPath", "profilePath", "description",
469 "userWorkstations", "comment", "userParameters", "objectSid",
470 "primaryGroupID", "userAccountControl", "logonHours",
471 "badPwdCount", "logonCount", "countryCode", "codePage",
472 "unicodePwd", "dBCSPwd" };
473 struct tldap_message **users;
475 struct pdb_ads_samu_private *result;
477 result = talloc(mem_ctx, struct pdb_ads_samu_private);
478 if (result == NULL) {
479 return NT_STATUS_NO_MEMORY;
482 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
483 attrs, ARRAY_SIZE(attrs), 0, result,
484 &users, "%s", filter);
485 if (rc != TLDAP_SUCCESS) {
486 DEBUG(10, ("ldap_search failed %s\n",
487 tldap_errstr(talloc_tos(), state->ld, rc)));
489 return NT_STATUS_LDAP(rc);
492 count = talloc_array_length(users);
494 DEBUG(10, ("Expected 1 user, got %d\n", count));
496 return NT_STATUS_NO_SUCH_USER;
499 result->ldapmsg = users[0];
500 if (!tldap_entry_dn(result->ldapmsg, &result->dn)) {
501 DEBUG(10, ("Could not extract dn\n"));
503 return NT_STATUS_INTERNAL_DB_CORRUPTION;
510 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
511 struct pdb_ads_state *state,
512 struct samu *sam_acct,
515 struct pdb_ads_samu_private *priv;
518 status = pdb_ads_getsamupriv(state, filter, sam_acct, &priv);
519 if (!NT_STATUS_IS_OK(status)) {
520 DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n",
525 status = pdb_ads_init_sam_from_priv(m, sam_acct, priv);
526 if (!NT_STATUS_IS_OK(status)) {
527 DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n",
533 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
537 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
538 struct samu *sam_acct,
539 const char *username)
541 struct pdb_ads_state *state = talloc_get_type_abort(
542 m->private_data, struct pdb_ads_state);
545 filter = talloc_asprintf(
546 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
548 NT_STATUS_HAVE_NO_MEMORY(filter);
550 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
553 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
554 struct samu *sam_acct,
555 const struct dom_sid *sid)
557 struct pdb_ads_state *state = talloc_get_type_abort(
558 m->private_data, struct pdb_ads_state);
559 char *sidstr, *filter;
561 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
562 NT_STATUS_HAVE_NO_MEMORY(sidstr);
564 filter = talloc_asprintf(
565 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
567 NT_STATUS_HAVE_NO_MEMORY(filter);
569 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
572 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
574 const char *name, uint32 acct_flags,
577 struct pdb_ads_state *state = talloc_get_type_abort(
578 m->private_data, struct pdb_ads_state);
579 struct tldap_context *ld;
580 const char *attrs[1] = { "objectSid" };
581 struct tldap_mod *mods = NULL;
583 struct tldap_message **user;
589 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
592 return NT_STATUS_NO_MEMORY;
595 ld = pdb_ads_ld(state);
597 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
600 /* TODO: Create machines etc */
603 ok &= tldap_make_mod_fmt(
604 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "user");
605 ok &= tldap_make_mod_fmt(
606 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
609 return NT_STATUS_NO_MEMORY;
613 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
614 if (rc != TLDAP_SUCCESS) {
615 DEBUG(10, ("ldap_add failed %s\n",
616 tldap_errstr(talloc_tos(), ld, rc)));
618 return NT_STATUS_LDAP(rc);
621 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
622 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
624 "(&(objectclass=user)(samaccountname=%s))",
626 if (rc != TLDAP_SUCCESS) {
627 DEBUG(10, ("Could not find just created user %s: %s\n",
628 name, tldap_errstr(talloc_tos(), state->ld, rc)));
630 return NT_STATUS_LDAP(rc);
633 if (talloc_array_length(user) != 1) {
634 DEBUG(10, ("Got %d users, expected one\n",
635 (int)talloc_array_length(user)));
637 return NT_STATUS_LDAP(rc);
640 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
641 DEBUG(10, ("Could not fetch objectSid from user %s\n",
644 return NT_STATUS_INTERNAL_DB_CORRUPTION;
647 sid_peek_rid(&sid, rid);
652 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
656 struct pdb_ads_state *state = talloc_get_type_abort(
657 m->private_data, struct pdb_ads_state);
659 struct tldap_context *ld;
663 ld = pdb_ads_ld(state);
665 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
668 status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
670 if (!NT_STATUS_IS_OK(status)) {
674 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
676 if (rc != TLDAP_SUCCESS) {
677 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
678 tldap_errstr(talloc_tos(), ld, rc)));
679 return NT_STATUS_LDAP(rc);
684 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
685 struct samu *sampass)
687 return NT_STATUS_NOT_IMPLEMENTED;
690 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
693 struct pdb_ads_state *state = talloc_get_type_abort(
694 m->private_data, struct pdb_ads_state);
695 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
696 struct tldap_context *ld;
697 struct tldap_mod *mods = NULL;
698 int rc, num_mods = 0;
700 ld = pdb_ads_ld(state);
702 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
705 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
706 &mods, &num_mods, sam)) {
707 return NT_STATUS_NO_MEMORY;
711 /* Nothing to do, just return success */
715 rc = tldap_modify(ld, priv->dn, mods, num_mods, NULL, 0,
718 if (rc != TLDAP_SUCCESS) {
719 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
720 tldap_errstr(talloc_tos(), ld, rc)));
721 return NT_STATUS_LDAP(rc);
727 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
728 struct samu *username)
730 return NT_STATUS_NOT_IMPLEMENTED;
733 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
734 struct samu *oldname,
737 return NT_STATUS_NOT_IMPLEMENTED;
740 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
741 struct samu *sam_acct,
744 return NT_STATUS_NOT_IMPLEMENTED;
747 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
750 struct tldap_message **pmsg)
752 struct pdb_ads_state *state = talloc_get_type_abort(
753 m->private_data, struct pdb_ads_state);
754 const char *attrs[4] = { "objectSid", "description", "samAccountName",
757 struct tldap_message **group;
761 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
762 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
763 &group, "%s", filter);
764 if (rc != TLDAP_SUCCESS) {
765 DEBUG(10, ("ldap_search failed %s\n",
766 tldap_errstr(talloc_tos(), state->ld, rc)));
767 return NT_STATUS_LDAP(rc);
769 if (talloc_array_length(group) != 1) {
770 DEBUG(10, ("Expected 1 group, got %d\n",
771 (int)talloc_array_length(group)));
772 return NT_STATUS_INTERNAL_DB_CORRUPTION;
775 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
776 return NT_STATUS_INTERNAL_DB_CORRUPTION;
778 map->gid = pdb_ads_sid2gid(&map->sid);
780 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
781 return NT_STATUS_INTERNAL_DB_CORRUPTION;
784 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
785 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
786 map->sid_name_use = SID_NAME_ALIAS;
788 case GTYPE_SECURITY_GLOBAL_GROUP:
789 map->sid_name_use = SID_NAME_DOM_GRP;
792 return NT_STATUS_INTERNAL_DB_CORRUPTION;
795 str = tldap_talloc_single_attribute(group[0], "samAccountName",
798 return NT_STATUS_INTERNAL_DB_CORRUPTION;
800 fstrcpy(map->nt_name, str);
803 str = tldap_talloc_single_attribute(group[0], "description",
806 fstrcpy(map->comment, str);
809 map->comment[0] = '\0';
813 *pmsg = talloc_move(mem_ctx, &group[0]);
819 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
825 filter = talloc_asprintf(talloc_tos(),
826 "(&(objectsid=%s)(objectclass=group))",
827 sid_string_talloc(talloc_tos(), &sid));
828 if (filter == NULL) {
829 return NT_STATUS_NO_MEMORY;
832 status = pdb_ads_getgrfilter(m, map, filter, NULL, NULL);
837 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
841 pdb_ads_gid_to_sid(m, gid, &sid);
842 return pdb_ads_getgrsid(m, map, sid);
845 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
851 filter = talloc_asprintf(talloc_tos(),
852 "(&(samaccountname=%s)(objectclass=group))",
854 if (filter == NULL) {
855 return NT_STATUS_NO_MEMORY;
858 status = pdb_ads_getgrfilter(m, map, filter, NULL, NULL);
863 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
864 TALLOC_CTX *mem_ctx, const char *name,
867 TALLOC_CTX *frame = talloc_stackframe();
868 struct pdb_ads_state *state = talloc_get_type_abort(
869 m->private_data, struct pdb_ads_state);
870 struct tldap_context *ld;
871 const char *attrs[1] = { "objectSid" };
873 struct tldap_mod *mods = NULL;
874 struct tldap_message **alias;
880 ld = pdb_ads_ld(state);
882 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
885 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
889 return NT_STATUS_NO_MEMORY;
892 ok &= tldap_make_mod_fmt(
893 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
895 ok &= tldap_make_mod_fmt(
896 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group");
897 ok &= tldap_make_mod_fmt(
898 NULL, talloc_tos(), &mods, &num_mods, "groupType",
899 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
903 return NT_STATUS_NO_MEMORY;
906 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
907 if (rc != TLDAP_SUCCESS) {
908 DEBUG(10, ("ldap_add failed %s\n",
909 tldap_errstr(talloc_tos(), state->ld, rc)));
911 return NT_STATUS_LDAP(rc);
914 rc = pdb_ads_search_fmt(
915 state, state->domaindn, TLDAP_SCOPE_SUB,
916 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
917 "(&(objectclass=group)(samaccountname=%s))", name);
918 if (rc != TLDAP_SUCCESS) {
919 DEBUG(10, ("Could not find just created alias %s: %s\n",
920 name, tldap_errstr(talloc_tos(), state->ld, rc)));
922 return NT_STATUS_LDAP(rc);
925 if (talloc_array_length(alias) != 1) {
926 DEBUG(10, ("Got %d alias, expected one\n",
927 (int)talloc_array_length(alias)));
929 return NT_STATUS_LDAP(rc);
932 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
933 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
936 return NT_STATUS_INTERNAL_DB_CORRUPTION;
939 sid_peek_rid(&sid, rid);
944 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
945 TALLOC_CTX *mem_ctx, uint32 rid)
947 struct pdb_ads_state *state = talloc_get_type_abort(
948 m->private_data, struct pdb_ads_state);
949 struct tldap_context *ld;
952 struct tldap_message **msg;
956 sid_compose(&sid, &state->domainsid, rid);
958 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
959 NT_STATUS_HAVE_NO_MEMORY(sidstr);
961 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
962 NULL, 0, 0, talloc_tos(), &msg,
963 ("(&(objectSid=%s)(objectClass=group))"),
966 if (rc != TLDAP_SUCCESS) {
967 DEBUG(10, ("ldap_search failed %s\n",
968 tldap_errstr(talloc_tos(), state->ld, rc)));
969 return NT_STATUS_LDAP(rc);
972 switch talloc_array_length(msg) {
974 return NT_STATUS_NO_SUCH_GROUP;
978 return NT_STATUS_INTERNAL_DB_CORRUPTION;
981 if (!tldap_entry_dn(msg[0], &dn)) {
983 return NT_STATUS_INTERNAL_DB_CORRUPTION;
986 ld = pdb_ads_ld(state);
989 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
992 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
994 if (rc != TLDAP_SUCCESS) {
995 DEBUG(10, ("ldap_delete failed: %s\n",
996 tldap_errstr(talloc_tos(), state->ld, rc)));
997 return NT_STATUS_LDAP(rc);
1000 return NT_STATUS_OK;
1003 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
1006 return NT_STATUS_NOT_IMPLEMENTED;
1009 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
1012 struct pdb_ads_state *state = talloc_get_type_abort(
1013 m->private_data, struct pdb_ads_state);
1014 struct tldap_context *ld;
1015 struct tldap_mod *mods = NULL;
1017 struct tldap_message *existing;
1019 GROUP_MAP existing_map;
1020 int rc, num_mods = 0;
1024 ld = pdb_ads_ld(state);
1026 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1029 filter = talloc_asprintf(talloc_tos(),
1030 "(&(objectsid=%s)(objectclass=group))",
1031 sid_string_talloc(talloc_tos(), &map->sid));
1032 if (filter == NULL) {
1033 return NT_STATUS_NO_MEMORY;
1035 status = pdb_ads_getgrfilter(m, &existing_map, filter,
1036 talloc_tos(), &existing);
1037 TALLOC_FREE(filter);
1039 if (!tldap_entry_dn(existing, &dn)) {
1040 return NT_STATUS_LDAP(TLDAP_DECODING_ERROR);
1045 ret &= tldap_make_mod_fmt(
1046 existing, talloc_tos(), &mods, &num_mods, "description",
1047 "%s", map->comment);
1048 ret &= tldap_make_mod_fmt(
1049 existing, talloc_tos(), &mods, &num_mods, "samaccountname",
1050 "%s", map->nt_name);
1053 return NT_STATUS_NO_MEMORY;
1056 if (num_mods == 0) {
1057 TALLOC_FREE(existing);
1058 return NT_STATUS_OK;
1061 rc = tldap_modify(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1062 if (rc != TLDAP_SUCCESS) {
1063 DEBUG(10, ("ldap_modify for %s failed: %s\n", dn,
1064 tldap_errstr(talloc_tos(), ld, rc)));
1065 TALLOC_FREE(existing);
1066 return NT_STATUS_LDAP(rc);
1068 TALLOC_FREE(existing);
1069 return NT_STATUS_OK;
1072 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
1075 return NT_STATUS_NOT_IMPLEMENTED;
1078 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
1079 const struct dom_sid *sid,
1080 enum lsa_SidType sid_name_use,
1081 GROUP_MAP **pp_rmap,
1082 size_t *p_num_entries,
1085 return NT_STATUS_NOT_IMPLEMENTED;
1088 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
1089 TALLOC_CTX *mem_ctx,
1090 const struct dom_sid *group,
1092 size_t *pnum_members)
1094 struct pdb_ads_state *state = talloc_get_type_abort(
1095 m->private_data, struct pdb_ads_state);
1096 const char *attrs[1] = { "member" };
1098 struct tldap_message **msg;
1099 int i, rc, num_members;
1103 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), group);
1104 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1106 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1107 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1108 &msg, "(objectsid=%s)", sidstr);
1109 TALLOC_FREE(sidstr);
1110 if (rc != TLDAP_SUCCESS) {
1111 DEBUG(10, ("ldap_search failed %s\n",
1112 tldap_errstr(talloc_tos(), state->ld, rc)));
1113 return NT_STATUS_LDAP(rc);
1115 switch talloc_array_length(msg) {
1117 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1122 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1126 if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
1129 return NT_STATUS_OK;
1132 members = talloc_array(mem_ctx, uint32_t, num_members);
1133 if (members == NULL) {
1134 return NT_STATUS_NO_MEMORY;
1137 for (i=0; i<num_members; i++) {
1139 if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
1140 || !sid_peek_rid(&sid, &members[i])) {
1141 TALLOC_FREE(members);
1142 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1146 *pmembers = members;
1147 *pnum_members = num_members;
1148 return NT_STATUS_OK;
1151 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
1152 TALLOC_CTX *mem_ctx,
1154 struct dom_sid **pp_sids,
1156 uint32_t *p_num_groups)
1158 struct pdb_ads_state *state = talloc_get_type_abort(
1159 m->private_data, struct pdb_ads_state);
1160 struct pdb_ads_samu_private *priv;
1161 const char *attrs[1] = { "objectSid" };
1162 struct tldap_message **groups;
1165 struct dom_sid *group_sids;
1168 priv = pdb_ads_get_samu_private(m, user);
1170 rc = pdb_ads_search_fmt(
1171 state, state->domaindn, TLDAP_SCOPE_SUB,
1172 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
1173 "(&(member=%s)(grouptype=%d)(objectclass=group))",
1174 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
1175 if (rc != TLDAP_SUCCESS) {
1176 DEBUG(10, ("ldap_search failed %s\n",
1177 tldap_errstr(talloc_tos(), state->ld, rc)));
1178 return NT_STATUS_LDAP(rc);
1180 count = talloc_array_length(groups);
1183 * This happens for artificial samu users
1185 DEBUG(10, ("Could not get pdb_ads_samu_private\n"));
1189 group_sids = talloc_array(mem_ctx, struct dom_sid, count+1);
1190 if (group_sids == NULL) {
1191 return NT_STATUS_NO_MEMORY;
1193 gids = talloc_array(mem_ctx, gid_t, count+1);
1195 TALLOC_FREE(group_sids);
1196 return NT_STATUS_NO_MEMORY;
1199 sid_copy(&group_sids[0], pdb_get_group_sid(user));
1200 if (!sid_to_gid(&group_sids[0], &gids[0])) {
1202 TALLOC_FREE(group_sids);
1203 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1207 for (i=0; i<count; i++) {
1208 if (!tldap_pull_binsid(groups[i], "objectSid",
1209 &group_sids[num_groups])) {
1212 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
1215 if (num_groups == count) {
1220 *pp_sids = group_sids;
1222 *p_num_groups = num_groups;
1223 return NT_STATUS_OK;
1226 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
1227 TALLOC_CTX *mem_ctx,
1230 return NT_STATUS_NOT_IMPLEMENTED;
1233 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
1234 TALLOC_CTX *mem_ctx,
1235 uint32 grouprid, uint32 memberrid,
1238 struct pdb_ads_state *state = talloc_get_type_abort(
1239 m->private_data, struct pdb_ads_state);
1240 TALLOC_CTX *frame = talloc_stackframe();
1241 struct tldap_context *ld;
1242 struct dom_sid groupsid, membersid;
1243 char *groupdn, *memberdn;
1244 struct tldap_mod *mods;
1249 ld = pdb_ads_ld(state);
1251 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1254 sid_compose(&groupsid, &state->domainsid, grouprid);
1255 sid_compose(&membersid, &state->domainsid, memberrid);
1257 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
1258 if (!NT_STATUS_IS_OK(status)) {
1260 return NT_STATUS_NO_SUCH_GROUP;
1262 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
1263 if (!NT_STATUS_IS_OK(status)) {
1265 return NT_STATUS_NO_SUCH_USER;
1271 if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op,
1272 "member", memberdn)) {
1274 return NT_STATUS_NO_MEMORY;
1277 rc = tldap_modify(ld, groupdn, mods, num_mods, NULL, 0, NULL, 0);
1279 if (rc != TLDAP_SUCCESS) {
1280 DEBUG(10, ("ldap_modify failed: %s\n",
1281 tldap_errstr(talloc_tos(), state->ld, rc)));
1282 if ((mod_op == TLDAP_MOD_ADD) &&
1283 (rc == TLDAP_ALREADY_EXISTS)) {
1284 return NT_STATUS_MEMBER_IN_GROUP;
1286 if ((mod_op == TLDAP_MOD_DELETE) &&
1287 (rc == TLDAP_UNWILLING_TO_PERFORM)) {
1288 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1290 return NT_STATUS_LDAP(rc);
1293 return NT_STATUS_OK;
1296 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
1297 TALLOC_CTX *mem_ctx,
1298 uint32 group_rid, uint32 member_rid)
1300 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1304 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
1305 TALLOC_CTX *mem_ctx,
1306 uint32 group_rid, uint32 member_rid)
1308 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1312 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
1313 const char *name, uint32 *rid)
1315 TALLOC_CTX *frame = talloc_stackframe();
1316 struct pdb_ads_state *state = talloc_get_type_abort(
1317 m->private_data, struct pdb_ads_state);
1318 struct tldap_context *ld;
1319 const char *attrs[1] = { "objectSid" };
1321 struct tldap_mod *mods = NULL;
1322 struct tldap_message **alias;
1328 ld = pdb_ads_ld(state);
1330 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1333 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1337 return NT_STATUS_NO_MEMORY;
1340 ok &= tldap_make_mod_fmt(
1341 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
1343 ok &= tldap_make_mod_fmt(
1344 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group");
1345 ok &= tldap_make_mod_fmt(
1346 NULL, talloc_tos(), &mods, &num_mods, "groupType",
1347 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1351 return NT_STATUS_NO_MEMORY;
1354 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1355 if (rc != TLDAP_SUCCESS) {
1356 DEBUG(10, ("ldap_add failed %s\n",
1357 tldap_errstr(talloc_tos(), state->ld, rc)));
1359 return NT_STATUS_LDAP(rc);
1362 rc = pdb_ads_search_fmt(
1363 state, state->domaindn, TLDAP_SCOPE_SUB,
1364 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1365 "(&(objectclass=group)(samaccountname=%s))", name);
1366 if (rc != TLDAP_SUCCESS) {
1367 DEBUG(10, ("Could not find just created alias %s: %s\n",
1368 name, tldap_errstr(talloc_tos(), state->ld, rc)));
1370 return NT_STATUS_LDAP(rc);
1373 if (talloc_array_length(alias) != 1) {
1374 DEBUG(10, ("Got %d alias, expected one\n",
1375 (int)talloc_array_length(alias)));
1377 return NT_STATUS_LDAP(rc);
1380 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1381 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1384 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1387 sid_peek_rid(&sid, rid);
1389 return NT_STATUS_OK;
1392 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1393 const struct dom_sid *sid)
1395 struct pdb_ads_state *state = talloc_get_type_abort(
1396 m->private_data, struct pdb_ads_state);
1397 struct tldap_context *ld;
1398 struct tldap_message **alias;
1399 char *sidstr, *dn = NULL;
1402 ld = pdb_ads_ld(state);
1404 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1407 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1408 if (sidstr == NULL) {
1409 return NT_STATUS_NO_MEMORY;
1412 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1413 NULL, 0, 0, talloc_tos(), &alias,
1414 "(&(objectSid=%s)(objectclass=group)"
1415 "(|(grouptype=%d)(grouptype=%d)))",
1416 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1417 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1418 TALLOC_FREE(sidstr);
1419 if (rc != TLDAP_SUCCESS) {
1420 DEBUG(10, ("ldap_search failed: %s\n",
1421 tldap_errstr(talloc_tos(), state->ld, rc)));
1422 return NT_STATUS_LDAP(rc);
1424 if (talloc_array_length(alias) != 1) {
1425 DEBUG(10, ("Expected 1 alias, got %d\n",
1426 (int)talloc_array_length(alias)));
1427 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1429 if (!tldap_entry_dn(alias[0], &dn)) {
1430 DEBUG(10, ("Could not get DN for alias %s\n",
1431 sid_string_dbg(sid)));
1432 return NT_STATUS_INTERNAL_ERROR;
1435 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
1436 if (rc != TLDAP_SUCCESS) {
1437 DEBUG(10, ("ldap_delete failed: %s\n",
1438 tldap_errstr(talloc_tos(), state->ld, rc)));
1439 return NT_STATUS_LDAP(rc);
1442 return NT_STATUS_OK;
1445 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1446 const struct dom_sid *sid,
1447 struct acct_info *info)
1449 struct pdb_ads_state *state = talloc_get_type_abort(
1450 m->private_data, struct pdb_ads_state);
1451 struct tldap_context *ld;
1452 const char *attrs[3] = { "objectSid", "description",
1454 struct tldap_message **msg;
1457 struct tldap_mod *mods;
1461 ld = pdb_ads_ld(state);
1463 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1466 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1467 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1469 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1470 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1471 &msg, "(&(objectSid=%s)(objectclass=group)"
1472 "(|(grouptype=%d)(grouptype=%d)))",
1473 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1474 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1475 TALLOC_FREE(sidstr);
1476 if (rc != TLDAP_SUCCESS) {
1477 DEBUG(10, ("ldap_search failed %s\n",
1478 tldap_errstr(talloc_tos(), state->ld, rc)));
1479 return NT_STATUS_LDAP(rc);
1481 switch talloc_array_length(msg) {
1483 return NT_STATUS_NO_SUCH_ALIAS;
1487 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1490 if (!tldap_entry_dn(msg[0], &dn)) {
1492 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1499 ok &= tldap_make_mod_fmt(
1500 msg[0], msg, &mods, &num_mods, "description",
1501 "%s", info->acct_desc);
1502 ok &= tldap_make_mod_fmt(
1503 msg[0], msg, &mods, &num_mods, "samAccountName",
1504 "%s", info->acct_name);
1507 return NT_STATUS_NO_MEMORY;
1509 if (num_mods == 0) {
1512 return NT_STATUS_OK;
1515 rc = tldap_modify(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1517 if (rc != TLDAP_SUCCESS) {
1518 DEBUG(10, ("ldap_modify failed: %s\n",
1519 tldap_errstr(talloc_tos(), state->ld, rc)));
1520 return NT_STATUS_LDAP(rc);
1522 return NT_STATUS_OK;
1525 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1526 const struct dom_sid *sid,
1527 TALLOC_CTX *mem_ctx, char **pdn)
1529 struct tldap_message **msg;
1533 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1534 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1536 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1537 NULL, 0, 0, talloc_tos(), &msg,
1538 "(objectsid=%s)", sidstr);
1539 TALLOC_FREE(sidstr);
1540 if (rc != TLDAP_SUCCESS) {
1541 DEBUG(10, ("ldap_search failed %s\n",
1542 tldap_errstr(talloc_tos(), state->ld, rc)));
1543 return NT_STATUS_LDAP(rc);
1546 switch talloc_array_length(msg) {
1548 return NT_STATUS_NOT_FOUND;
1552 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1555 if (!tldap_entry_dn(msg[0], &dn)) {
1556 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1559 dn = talloc_strdup(mem_ctx, dn);
1561 return NT_STATUS_NO_MEMORY;
1566 return NT_STATUS_OK;
1569 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1570 const struct dom_sid *alias,
1571 const struct dom_sid *member,
1574 struct pdb_ads_state *state = talloc_get_type_abort(
1575 m->private_data, struct pdb_ads_state);
1576 struct tldap_context *ld;
1577 TALLOC_CTX *frame = talloc_stackframe();
1578 struct tldap_mod *mods;
1581 char *aliasdn, *memberdn;
1584 ld = pdb_ads_ld(state);
1586 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1589 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1590 if (!NT_STATUS_IS_OK(status)) {
1591 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1592 sid_string_dbg(alias), nt_errstr(status)));
1594 return NT_STATUS_NO_SUCH_ALIAS;
1596 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1597 if (!NT_STATUS_IS_OK(status)) {
1598 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1599 sid_string_dbg(member), nt_errstr(status)));
1607 if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op,
1608 "member", memberdn)) {
1610 return NT_STATUS_NO_MEMORY;
1613 rc = tldap_modify(ld, aliasdn, mods, num_mods, NULL, 0, NULL, 0);
1615 if (rc != TLDAP_SUCCESS) {
1616 DEBUG(10, ("ldap_modify failed: %s\n",
1617 tldap_errstr(talloc_tos(), state->ld, rc)));
1618 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1619 return NT_STATUS_MEMBER_IN_ALIAS;
1621 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1622 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1624 return NT_STATUS_LDAP(rc);
1627 return NT_STATUS_OK;
1630 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1631 const struct dom_sid *alias,
1632 const struct dom_sid *member)
1634 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1637 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1638 const struct dom_sid *alias,
1639 const struct dom_sid *member)
1641 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1644 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
1645 struct dom_sid *psid)
1647 const char *attrs[1] = { "objectSid" };
1648 struct tldap_message **msg;
1654 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1655 dnblob->data, dnblob->length, &dn, &len)) {
1658 rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
1659 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1660 &msg, "(objectclass=*)");
1662 if (talloc_array_length(msg) != 1) {
1663 DEBUG(10, ("Got %d objects, expected one\n",
1664 (int)talloc_array_length(msg)));
1669 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1674 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1675 const struct dom_sid *alias,
1676 TALLOC_CTX *mem_ctx,
1677 struct dom_sid **pmembers,
1678 size_t *pnum_members)
1680 struct pdb_ads_state *state = talloc_get_type_abort(
1681 m->private_data, struct pdb_ads_state);
1682 const char *attrs[1] = { "member" };
1684 struct tldap_message **msg;
1685 int i, rc, num_members;
1687 struct dom_sid *members;
1689 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), alias);
1690 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1692 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1693 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1694 &msg, "(objectsid=%s)", sidstr);
1695 TALLOC_FREE(sidstr);
1696 if (rc != TLDAP_SUCCESS) {
1697 DEBUG(10, ("ldap_search failed %s\n",
1698 tldap_errstr(talloc_tos(), state->ld, rc)));
1699 return NT_STATUS_LDAP(rc);
1701 switch talloc_array_length(msg) {
1703 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1708 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1712 if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
1715 return NT_STATUS_OK;
1718 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1719 if (members == NULL) {
1720 return NT_STATUS_NO_MEMORY;
1723 for (i=0; i<num_members; i++) {
1724 if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
1725 TALLOC_FREE(members);
1726 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1730 *pmembers = members;
1731 *pnum_members = num_members;
1732 return NT_STATUS_OK;
1735 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1736 TALLOC_CTX *mem_ctx,
1737 const struct dom_sid *domain_sid,
1738 const struct dom_sid *members,
1740 uint32_t **palias_rids,
1741 size_t *pnum_alias_rids)
1743 struct pdb_ads_state *state = talloc_get_type_abort(
1744 m->private_data, struct pdb_ads_state);
1745 const char *attrs[1] = { "objectSid" };
1746 struct tldap_message **msg = NULL;
1747 uint32_t *alias_rids = NULL;
1748 size_t num_alias_rids = 0;
1750 bool got_members = false;
1755 * TODO: Get the filter right so that we only get the aliases from
1756 * either the SAM or BUILTIN
1759 filter = talloc_asprintf(talloc_tos(),
1760 "(&(|(grouptype=%d)(grouptype=%d))"
1761 "(objectclass=group)(|",
1762 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1763 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1764 if (filter == NULL) {
1765 return NT_STATUS_NO_MEMORY;
1768 for (i=0; i<num_members; i++) {
1771 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1772 if (!NT_STATUS_IS_OK(status)) {
1773 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1774 sid_string_dbg(&members[i]),
1775 nt_errstr(status)));
1778 filter = talloc_asprintf_append_buffer(
1779 filter, "(member=%s)", dn);
1781 if (filter == NULL) {
1782 return NT_STATUS_NO_MEMORY;
1791 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1792 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1793 &msg, "%s))", filter);
1794 TALLOC_FREE(filter);
1795 if (rc != TLDAP_SUCCESS) {
1796 DEBUG(10, ("tldap_search failed %s\n",
1797 tldap_errstr(talloc_tos(), state->ld, rc)));
1798 return NT_STATUS_LDAP(rc);
1801 count = talloc_array_length(msg);
1806 alias_rids = talloc_array(mem_ctx, uint32_t, count);
1807 if (alias_rids == NULL) {
1809 return NT_STATUS_NO_MEMORY;
1812 for (i=0; i<count; i++) {
1815 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1816 DEBUG(10, ("Could not pull SID for member %d\n", i));
1819 if (sid_peek_check_rid(domain_sid, &sid,
1820 &alias_rids[num_alias_rids])) {
1821 num_alias_rids += 1;
1826 *palias_rids = alias_rids;
1827 *pnum_alias_rids = 0;
1828 return NT_STATUS_OK;
1831 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1832 const struct dom_sid *domain_sid,
1836 enum lsa_SidType *lsa_attrs)
1838 struct pdb_ads_state *state = talloc_get_type_abort(
1839 m->private_data, struct pdb_ads_state);
1840 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1843 if (num_rids == 0) {
1844 return NT_STATUS_NONE_MAPPED;
1849 for (i=0; i<num_rids; i++) {
1851 struct tldap_message **msg;
1856 lsa_attrs[i] = SID_NAME_UNKNOWN;
1858 sid_compose(&sid, domain_sid, rids[i]);
1860 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
1861 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1863 rc = pdb_ads_search_fmt(state, state->domaindn,
1864 TLDAP_SCOPE_SUB, attrs,
1865 ARRAY_SIZE(attrs), 0, talloc_tos(),
1866 &msg, "(objectsid=%s)", sidstr);
1867 TALLOC_FREE(sidstr);
1868 if (rc != TLDAP_SUCCESS) {
1869 DEBUG(10, ("ldap_search failed %s\n",
1870 tldap_errstr(talloc_tos(), state->ld, rc)));
1874 switch talloc_array_length(msg) {
1876 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1881 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1884 names[i] = tldap_talloc_single_attribute(
1885 msg[0], "samAccountName", talloc_tos());
1886 if (names[i] == NULL) {
1887 DEBUG(10, ("no samAccountName\n"));
1890 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1891 DEBUG(10, ("no samAccountType"));
1894 lsa_attrs[i] = ds_atype_map(attr);
1898 if (num_mapped == 0) {
1899 return NT_STATUS_NONE_MAPPED;
1901 if (num_mapped < num_rids) {
1902 return STATUS_SOME_UNMAPPED;
1904 return NT_STATUS_OK;
1907 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1908 const struct dom_sid *domain_sid,
1910 const char **pp_names,
1912 enum lsa_SidType *attrs)
1914 return NT_STATUS_NOT_IMPLEMENTED;
1917 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1918 enum pdb_policy_type type,
1921 return account_policy_get(type, value)
1922 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1925 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1926 enum pdb_policy_type type,
1929 return account_policy_set(type, value)
1930 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1933 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1936 return NT_STATUS_NOT_IMPLEMENTED;
1939 struct pdb_ads_search_state {
1940 uint32_t acct_flags;
1941 struct samr_displayentry *entries;
1942 uint32_t num_entries;
1947 static bool pdb_ads_next_entry(struct pdb_search *search,
1948 struct samr_displayentry *entry)
1950 struct pdb_ads_search_state *state = talloc_get_type_abort(
1951 search->private_data, struct pdb_ads_search_state);
1953 if (state->current == state->num_entries) {
1957 entry->idx = state->entries[state->current].idx;
1958 entry->rid = state->entries[state->current].rid;
1959 entry->acct_flags = state->entries[state->current].acct_flags;
1961 entry->account_name = talloc_strdup(
1962 search, state->entries[state->current].account_name);
1963 entry->fullname = talloc_strdup(
1964 search, state->entries[state->current].fullname);
1965 entry->description = talloc_strdup(
1966 search, state->entries[state->current].description);
1968 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1969 || (entry->description == NULL)) {
1970 DEBUG(0, ("talloc_strdup failed\n"));
1974 state->current += 1;
1978 static void pdb_ads_search_end(struct pdb_search *search)
1980 struct pdb_ads_search_state *state = talloc_get_type_abort(
1981 search->private_data, struct pdb_ads_search_state);
1985 static bool pdb_ads_search_filter(struct pdb_methods *m,
1986 struct pdb_search *search,
1988 uint32_t acct_flags,
1989 struct pdb_ads_search_state **pstate)
1991 struct pdb_ads_state *state = talloc_get_type_abort(
1992 m->private_data, struct pdb_ads_state);
1993 struct pdb_ads_search_state *sstate;
1994 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1995 "userAccountControl", "description" };
1996 struct tldap_message **users;
1997 int i, rc, num_users;
1999 sstate = talloc_zero(search, struct pdb_ads_search_state);
2000 if (sstate == NULL) {
2003 sstate->acct_flags = acct_flags;
2005 rc = pdb_ads_search_fmt(
2006 state, state->domaindn, TLDAP_SCOPE_SUB,
2007 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
2009 if (rc != TLDAP_SUCCESS) {
2010 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
2011 tldap_errstr(talloc_tos(), state->ld, rc)));
2015 num_users = talloc_array_length(users);
2017 sstate->entries = talloc_array(sstate, struct samr_displayentry,
2019 if (sstate->entries == NULL) {
2020 DEBUG(10, ("talloc failed\n"));
2024 sstate->num_entries = 0;
2026 for (i=0; i<num_users; i++) {
2027 struct samr_displayentry *e;
2031 e = &sstate->entries[sstate->num_entries];
2033 e->idx = sstate->num_entries;
2034 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
2035 DEBUG(10, ("Could not pull sid\n"));
2038 sid_peek_rid(&sid, &e->rid);
2040 if (tldap_pull_uint32(users[i], "userAccountControl", &ctrl)) {
2042 e->acct_flags = ds_uf2acb(ctrl);
2044 DEBUG(10, ("pdb_ads_search_filter: Found %x, "
2045 "filter %x\n", (int)e->acct_flags,
2046 (int)sstate->acct_flags));
2049 if ((sstate->acct_flags != 0) &&
2050 ((sstate->acct_flags & e->acct_flags) == 0)) {
2054 if (e->acct_flags & (ACB_WSTRUST|ACB_SVRTRUST)) {
2055 e->acct_flags |= ACB_NORMAL;
2058 e->acct_flags = ACB_NORMAL;
2061 if (e->rid == DOMAIN_RID_GUEST) {
2063 * Guest is specially crafted in s3. Make
2064 * QueryDisplayInfo match QueryUserInfo
2066 e->account_name = lp_guestaccount();
2067 e->fullname = lp_guestaccount();
2068 e->description = "";
2069 e->acct_flags = ACB_NORMAL;
2071 e->account_name = tldap_talloc_single_attribute(
2072 users[i], "samAccountName", sstate->entries);
2073 e->fullname = tldap_talloc_single_attribute(
2074 users[i], "displayName", sstate->entries);
2075 e->description = tldap_talloc_single_attribute(
2076 users[i], "description", sstate->entries);
2078 if (e->account_name == NULL) {
2081 if (e->fullname == NULL) {
2084 if (e->description == NULL) {
2085 e->description = "";
2088 sstate->num_entries += 1;
2089 if (sstate->num_entries >= num_users) {
2094 search->private_data = sstate;
2095 search->next_entry = pdb_ads_next_entry;
2096 search->search_end = pdb_ads_search_end;
2101 static bool pdb_ads_search_users(struct pdb_methods *m,
2102 struct pdb_search *search,
2105 struct pdb_ads_search_state *sstate;
2109 DEBUG(10, ("pdb_ads_search_users got flags %x\n", acct_flags));
2111 if (acct_flags & ACB_NORMAL) {
2112 filter = talloc_asprintf(
2114 "(&(objectclass=user)(sAMAccountType=%d))",
2115 ATYPE_NORMAL_ACCOUNT);
2116 } else if (acct_flags & ACB_WSTRUST) {
2117 filter = talloc_asprintf(
2119 "(&(objectclass=user)(sAMAccountType=%d))",
2120 ATYPE_WORKSTATION_TRUST);
2122 filter = talloc_strdup(talloc_tos(), "(objectclass=user)");
2124 if (filter == NULL) {
2128 ret = pdb_ads_search_filter(m, search, filter, acct_flags, &sstate);
2129 TALLOC_FREE(filter);
2136 static bool pdb_ads_search_groups(struct pdb_methods *m,
2137 struct pdb_search *search)
2139 struct pdb_ads_search_state *sstate;
2143 filter = talloc_asprintf(talloc_tos(),
2144 "(&(grouptype=%d)(objectclass=group))",
2145 GTYPE_SECURITY_GLOBAL_GROUP);
2146 if (filter == NULL) {
2149 ret = pdb_ads_search_filter(m, search, filter, 0, &sstate);
2150 TALLOC_FREE(filter);
2157 static bool pdb_ads_search_aliases(struct pdb_methods *m,
2158 struct pdb_search *search,
2159 const struct dom_sid *sid)
2161 struct pdb_ads_search_state *sstate;
2165 filter = talloc_asprintf(
2166 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
2167 sid_check_is_builtin(sid)
2168 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2169 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
2171 if (filter == NULL) {
2174 ret = pdb_ads_search_filter(m, search, filter, 0, &sstate);
2175 TALLOC_FREE(filter);
2182 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
2183 struct dom_sid *sid)
2185 struct pdb_ads_state *state = talloc_get_type_abort(
2186 m->private_data, struct pdb_ads_state);
2187 sid_compose(sid, &state->domainsid, uid);
2191 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
2192 struct dom_sid *sid)
2194 struct pdb_ads_state *state = talloc_get_type_abort(
2195 m->private_data, struct pdb_ads_state);
2196 sid_compose(sid, &state->domainsid, gid);
2200 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2201 union unid_t *id, enum lsa_SidType *type)
2203 struct pdb_ads_state *state = talloc_get_type_abort(
2204 m->private_data, struct pdb_ads_state);
2205 const char *attrs[4] = { "objectClass", "samAccountType",
2206 "uidNumber", "gidNumber" };
2207 struct tldap_message **msg;
2208 char *sidstr, *base;
2213 sidstr = sid_binstring_hex(sid);
2214 if (sidstr == NULL) {
2217 base = talloc_asprintf(talloc_tos(), "<SID=%s>", sidstr);
2220 rc = pdb_ads_search_fmt(
2221 state, base, TLDAP_SCOPE_BASE,
2222 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
2226 if (rc != TLDAP_SUCCESS) {
2227 DEBUG(10, ("pdb_ads_search_fmt failed: %s\n",
2228 tldap_errstr(talloc_tos(), state->ld, rc)));
2231 if (talloc_array_length(msg) != 1) {
2232 DEBUG(10, ("Got %d objects, expected 1\n",
2233 (int)talloc_array_length(msg)));
2236 if (!tldap_pull_uint32(msg[0], "samAccountType", &atype)) {
2237 DEBUG(10, ("samAccountType not found\n"));
2240 if (atype == ATYPE_ACCOUNT) {
2242 *type = SID_NAME_USER;
2243 if (!tldap_pull_uint32(msg[0], "uidNumber", &uid)) {
2244 DEBUG(10, ("Did not find uidNumber\n"));
2250 *type = SID_NAME_DOM_GRP;
2251 if (!tldap_pull_uint32(msg[0], "gidNumber", &gid)) {
2252 DEBUG(10, ("Did not find gidNumber\n"));
2263 static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
2265 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2268 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
2273 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
2274 const char *domain, char** pwd,
2275 struct dom_sid *sid,
2276 time_t *pass_last_set_time)
2281 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
2282 const char* domain, const char* pwd,
2283 const struct dom_sid *sid)
2288 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
2294 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
2295 TALLOC_CTX *mem_ctx,
2296 uint32 *num_domains,
2297 struct trustdom_info ***domains)
2301 return NT_STATUS_OK;
2304 static void pdb_ads_init_methods(struct pdb_methods *m)
2307 m->get_domain_info = pdb_ads_get_domain_info;
2308 m->getsampwnam = pdb_ads_getsampwnam;
2309 m->getsampwsid = pdb_ads_getsampwsid;
2310 m->create_user = pdb_ads_create_user;
2311 m->delete_user = pdb_ads_delete_user;
2312 m->add_sam_account = pdb_ads_add_sam_account;
2313 m->update_sam_account = pdb_ads_update_sam_account;
2314 m->delete_sam_account = pdb_ads_delete_sam_account;
2315 m->rename_sam_account = pdb_ads_rename_sam_account;
2316 m->update_login_attempts = pdb_ads_update_login_attempts;
2317 m->getgrsid = pdb_ads_getgrsid;
2318 m->getgrgid = pdb_ads_getgrgid;
2319 m->getgrnam = pdb_ads_getgrnam;
2320 m->create_dom_group = pdb_ads_create_dom_group;
2321 m->delete_dom_group = pdb_ads_delete_dom_group;
2322 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
2323 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
2324 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
2325 m->enum_group_mapping = pdb_ads_enum_group_mapping;
2326 m->enum_group_members = pdb_ads_enum_group_members;
2327 m->enum_group_memberships = pdb_ads_enum_group_memberships;
2328 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
2329 m->add_groupmem = pdb_ads_add_groupmem;
2330 m->del_groupmem = pdb_ads_del_groupmem;
2331 m->create_alias = pdb_ads_create_alias;
2332 m->delete_alias = pdb_ads_delete_alias;
2333 m->get_aliasinfo = pdb_default_get_aliasinfo;
2334 m->set_aliasinfo = pdb_ads_set_aliasinfo;
2335 m->add_aliasmem = pdb_ads_add_aliasmem;
2336 m->del_aliasmem = pdb_ads_del_aliasmem;
2337 m->enum_aliasmem = pdb_ads_enum_aliasmem;
2338 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
2339 m->lookup_rids = pdb_ads_lookup_rids;
2340 m->lookup_names = pdb_ads_lookup_names;
2341 m->get_account_policy = pdb_ads_get_account_policy;
2342 m->set_account_policy = pdb_ads_set_account_policy;
2343 m->get_seq_num = pdb_ads_get_seq_num;
2344 m->search_users = pdb_ads_search_users;
2345 m->search_groups = pdb_ads_search_groups;
2346 m->search_aliases = pdb_ads_search_aliases;
2347 m->uid_to_sid = pdb_ads_uid_to_sid;
2348 m->gid_to_sid = pdb_ads_gid_to_sid;
2349 m->sid_to_id = pdb_ads_sid_to_id;
2350 m->capabilities = pdb_ads_capabilities;
2351 m->new_rid = pdb_ads_new_rid;
2352 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2353 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2354 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2355 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2358 static void free_private_data(void **vp)
2360 struct pdb_ads_state *state = talloc_get_type_abort(
2361 *vp, struct pdb_ads_state);
2363 TALLOC_FREE(state->ld);
2368 this is used to catch debug messages from events
2370 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2371 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
2373 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2374 const char *fmt, va_list ap)
2376 int samba_level = -1;
2379 case TLDAP_DEBUG_FATAL:
2382 case TLDAP_DEBUG_ERROR:
2385 case TLDAP_DEBUG_WARNING:
2388 case TLDAP_DEBUG_TRACE:
2393 if (vasprintf(&s, fmt, ap) == -1) {
2396 DEBUG(samba_level, ("tldap: %s", s));
2400 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2405 if (tldap_connection_ok(state->ld)) {
2408 TALLOC_FREE(state->ld);
2410 status = open_socket_out(
2411 (struct sockaddr_storage *)(void *)&state->socket_address,
2413 if (!NT_STATUS_IS_OK(status)) {
2414 DEBUG(10, ("Could not connect to %s: %s\n",
2415 state->socket_address.sun_path, nt_errstr(status)));
2419 set_blocking(fd, false);
2421 state->ld = tldap_context_create(state, fd);
2422 if (state->ld == NULL) {
2426 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2431 int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2432 int scope, const char *attrs[], int num_attrs,
2434 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2435 const char *fmt, ...)
2437 struct tldap_context *ld;
2441 ld = pdb_ads_ld(state);
2443 return TLDAP_SERVER_DOWN;
2447 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2448 mem_ctx, res, fmt, ap);
2451 if (ret != TLDAP_SERVER_DOWN) {
2456 ld = pdb_ads_ld(state);
2458 return TLDAP_SERVER_DOWN;
2462 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2463 mem_ctx, res, fmt, ap);
2468 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2469 const char *location)
2471 const char *domain_attrs[2] = { "objectSid", "objectGUID" };
2472 const char *ncname_attrs[1] = { "netbiosname" };
2473 struct tldap_context *ld;
2474 struct tldap_message *rootdse, **domain, **ncname;
2475 TALLOC_CTX *frame = talloc_stackframe();
2480 ZERO_STRUCT(state->socket_address);
2481 state->socket_address.sun_family = AF_UNIX;
2482 strlcpy(state->socket_address.sun_path, location,
2483 sizeof(state->socket_address.sun_path));
2485 ld = pdb_ads_ld(state);
2487 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2491 rc = tldap_fetch_rootdse(ld);
2492 if (rc != TLDAP_SUCCESS) {
2493 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2494 tldap_errstr(talloc_tos(), state->ld, rc)));
2495 status = NT_STATUS_LDAP(rc);
2498 rootdse = tldap_rootdse(state->ld);
2500 state->domaindn = tldap_talloc_single_attribute(
2501 rootdse, "defaultNamingContext", state);
2502 if (state->domaindn == NULL) {
2503 DEBUG(10, ("Could not get defaultNamingContext\n"));
2504 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2507 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2509 state->configdn = tldap_talloc_single_attribute(
2510 rootdse, "configurationNamingContext", state);
2511 if (state->configdn == NULL) {
2512 DEBUG(10, ("Could not get configurationNamingContext\n"));
2513 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2516 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2519 * Figure out our domain's SID
2521 rc = pdb_ads_search_fmt(
2522 state, state->domaindn, TLDAP_SCOPE_BASE,
2523 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2524 talloc_tos(), &domain, "(objectclass=*)");
2525 if (rc != TLDAP_SUCCESS) {
2526 DEBUG(10, ("Could not retrieve domain: %s\n",
2527 tldap_errstr(talloc_tos(), state->ld, rc)));
2528 status = NT_STATUS_LDAP(rc);
2532 num_domains = talloc_array_length(domain);
2533 if (num_domains != 1) {
2534 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2535 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2538 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2539 DEBUG(10, ("Could not retrieve domain SID\n"));
2540 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2543 if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) {
2544 DEBUG(10, ("Could not retrieve domain GUID\n"));
2545 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2548 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2551 * Figure out our domain's short name
2553 rc = pdb_ads_search_fmt(
2554 state, state->configdn, TLDAP_SCOPE_SUB,
2555 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2556 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2557 if (rc != TLDAP_SUCCESS) {
2558 DEBUG(10, ("Could not retrieve ncname: %s\n",
2559 tldap_errstr(talloc_tos(), state->ld, rc)));
2560 status = NT_STATUS_LDAP(rc);
2563 if (talloc_array_length(ncname) != 1) {
2564 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2568 state->netbiosname = tldap_talloc_single_attribute(
2569 ncname[0], "netbiosname", state);
2570 if (state->netbiosname == NULL) {
2571 DEBUG(10, ("Could not get netbiosname\n"));
2572 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2575 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2577 if (!strequal(lp_workgroup(), state->netbiosname)) {
2578 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2579 state->netbiosname, lp_workgroup()));
2580 status = NT_STATUS_NO_SUCH_DOMAIN;
2584 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2586 status = NT_STATUS_OK;
2592 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2593 const char *location)
2595 struct pdb_methods *m;
2596 struct pdb_ads_state *state;
2600 m = talloc(NULL, struct pdb_methods);
2602 return NT_STATUS_NO_MEMORY;
2604 state = talloc_zero(m, struct pdb_ads_state);
2605 if (state == NULL) {
2608 m->private_data = state;
2609 m->free_private_data = free_private_data;
2610 pdb_ads_init_methods(m);
2612 if (location == NULL) {
2613 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2617 if (location == NULL) {
2621 status = pdb_ads_connect(state, location);
2622 if (!NT_STATUS_IS_OK(status)) {
2623 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2628 return NT_STATUS_OK;
2630 status = NT_STATUS_NO_MEMORY;
2636 NTSTATUS pdb_ads_init(void);
2637 NTSTATUS pdb_ads_init(void)
2639 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",