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 tldap_message **pmsg)
751 struct pdb_ads_state *state = talloc_get_type_abort(
752 m->private_data, struct pdb_ads_state);
753 const char *attrs[4] = { "objectSid", "description", "samAccountName",
756 struct tldap_message **group;
760 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
761 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
762 &group, "%s", filter);
763 if (rc != TLDAP_SUCCESS) {
764 DEBUG(10, ("ldap_search failed %s\n",
765 tldap_errstr(talloc_tos(), state->ld, rc)));
766 return NT_STATUS_LDAP(rc);
768 if (talloc_array_length(group) != 1) {
769 DEBUG(10, ("Expected 1 group, got %d\n",
770 (int)talloc_array_length(group)));
771 return NT_STATUS_INTERNAL_DB_CORRUPTION;
774 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
775 return NT_STATUS_INTERNAL_DB_CORRUPTION;
777 map->gid = pdb_ads_sid2gid(&map->sid);
779 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
780 return NT_STATUS_INTERNAL_DB_CORRUPTION;
783 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
784 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
785 map->sid_name_use = SID_NAME_ALIAS;
787 case GTYPE_SECURITY_GLOBAL_GROUP:
788 map->sid_name_use = SID_NAME_DOM_GRP;
791 return NT_STATUS_INTERNAL_DB_CORRUPTION;
794 str = tldap_talloc_single_attribute(group[0], "samAccountName",
797 return NT_STATUS_INTERNAL_DB_CORRUPTION;
799 fstrcpy(map->nt_name, str);
802 str = tldap_talloc_single_attribute(group[0], "description",
805 fstrcpy(map->comment, str);
808 map->comment[0] = '\0';
812 *pmsg = talloc_move(mem_ctx, &group[0]);
818 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
824 filter = talloc_asprintf(talloc_tos(),
825 "(&(objectsid=%s)(objectclass=group))",
826 sid_string_talloc(talloc_tos(), &sid));
827 if (filter == NULL) {
828 return NT_STATUS_NO_MEMORY;
831 status = pdb_ads_getgrfilter(m, map, filter, NULL, NULL);
836 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
840 pdb_ads_gid_to_sid(m, gid, &sid);
841 return pdb_ads_getgrsid(m, map, sid);
844 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
850 filter = talloc_asprintf(talloc_tos(),
851 "(&(samaccountname=%s)(objectclass=group))",
853 if (filter == NULL) {
854 return NT_STATUS_NO_MEMORY;
857 status = pdb_ads_getgrfilter(m, map, filter, NULL, NULL);
862 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
863 TALLOC_CTX *mem_ctx, const char *name,
866 TALLOC_CTX *frame = talloc_stackframe();
867 struct pdb_ads_state *state = talloc_get_type_abort(
868 m->private_data, struct pdb_ads_state);
869 struct tldap_context *ld;
870 const char *attrs[1] = { "objectSid" };
872 struct tldap_mod *mods = NULL;
873 struct tldap_message **alias;
879 ld = pdb_ads_ld(state);
881 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
884 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
888 return NT_STATUS_NO_MEMORY;
891 ok &= tldap_make_mod_fmt(
892 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
894 ok &= tldap_make_mod_fmt(
895 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group");
896 ok &= tldap_make_mod_fmt(
897 NULL, talloc_tos(), &mods, &num_mods, "groupType",
898 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
902 return NT_STATUS_NO_MEMORY;
905 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
906 if (rc != TLDAP_SUCCESS) {
907 DEBUG(10, ("ldap_add failed %s\n",
908 tldap_errstr(talloc_tos(), state->ld, rc)));
910 return NT_STATUS_LDAP(rc);
913 rc = pdb_ads_search_fmt(
914 state, state->domaindn, TLDAP_SCOPE_SUB,
915 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
916 "(&(objectclass=group)(samaccountname=%s))", name);
917 if (rc != TLDAP_SUCCESS) {
918 DEBUG(10, ("Could not find just created alias %s: %s\n",
919 name, tldap_errstr(talloc_tos(), state->ld, rc)));
921 return NT_STATUS_LDAP(rc);
924 if (talloc_array_length(alias) != 1) {
925 DEBUG(10, ("Got %d alias, expected one\n",
926 (int)talloc_array_length(alias)));
928 return NT_STATUS_LDAP(rc);
931 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
932 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
935 return NT_STATUS_INTERNAL_DB_CORRUPTION;
938 sid_peek_rid(&sid, rid);
943 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
944 TALLOC_CTX *mem_ctx, uint32 rid)
946 struct pdb_ads_state *state = talloc_get_type_abort(
947 m->private_data, struct pdb_ads_state);
948 struct tldap_context *ld;
951 struct tldap_message **msg;
955 sid_compose(&sid, &state->domainsid, rid);
957 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
958 NT_STATUS_HAVE_NO_MEMORY(sidstr);
960 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
961 NULL, 0, 0, talloc_tos(), &msg,
962 ("(&(objectSid=%s)(objectClass=group))"),
965 if (rc != TLDAP_SUCCESS) {
966 DEBUG(10, ("ldap_search failed %s\n",
967 tldap_errstr(talloc_tos(), state->ld, rc)));
968 return NT_STATUS_LDAP(rc);
971 switch talloc_array_length(msg) {
973 return NT_STATUS_NO_SUCH_GROUP;
977 return NT_STATUS_INTERNAL_DB_CORRUPTION;
980 if (!tldap_entry_dn(msg[0], &dn)) {
982 return NT_STATUS_INTERNAL_DB_CORRUPTION;
985 ld = pdb_ads_ld(state);
988 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
991 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
993 if (rc != TLDAP_SUCCESS) {
994 DEBUG(10, ("ldap_delete failed: %s\n",
995 tldap_errstr(talloc_tos(), state->ld, rc)));
996 return NT_STATUS_LDAP(rc);
1002 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
1005 return NT_STATUS_NOT_IMPLEMENTED;
1008 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
1011 struct pdb_ads_state *state = talloc_get_type_abort(
1012 m->private_data, struct pdb_ads_state);
1013 struct tldap_context *ld;
1014 struct tldap_mod *mods = NULL;
1016 struct tldap_message *existing;
1018 GROUP_MAP existing_map;
1019 int rc, num_mods = 0;
1023 ld = pdb_ads_ld(state);
1025 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1028 filter = talloc_asprintf(talloc_tos(),
1029 "(&(objectsid=%s)(objectclass=group))",
1030 sid_string_talloc(talloc_tos(), &map->sid));
1031 if (filter == NULL) {
1032 return NT_STATUS_NO_MEMORY;
1034 status = pdb_ads_getgrfilter(m, &existing_map, filter,
1035 talloc_tos(), &existing);
1036 TALLOC_FREE(filter);
1038 if (!tldap_entry_dn(existing, &dn)) {
1039 return NT_STATUS_LDAP(TLDAP_DECODING_ERROR);
1044 ret &= tldap_make_mod_fmt(
1045 existing, talloc_tos(), &mods, &num_mods, "description",
1046 "%s", map->comment);
1047 ret &= tldap_make_mod_fmt(
1048 existing, talloc_tos(), &mods, &num_mods, "samaccountname",
1049 "%s", map->nt_name);
1052 return NT_STATUS_NO_MEMORY;
1055 if (num_mods == 0) {
1056 TALLOC_FREE(existing);
1057 return NT_STATUS_OK;
1060 rc = tldap_modify(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1061 if (rc != TLDAP_SUCCESS) {
1062 DEBUG(10, ("ldap_modify for %s failed: %s\n", dn,
1063 tldap_errstr(talloc_tos(), ld, rc)));
1064 TALLOC_FREE(existing);
1065 return NT_STATUS_LDAP(rc);
1067 TALLOC_FREE(existing);
1068 return NT_STATUS_OK;
1071 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
1074 return NT_STATUS_NOT_IMPLEMENTED;
1077 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
1078 const struct dom_sid *sid,
1079 enum lsa_SidType sid_name_use,
1080 GROUP_MAP **pp_rmap,
1081 size_t *p_num_entries,
1084 return NT_STATUS_NOT_IMPLEMENTED;
1087 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
1088 TALLOC_CTX *mem_ctx,
1089 const struct dom_sid *group,
1091 size_t *pnum_members)
1093 struct pdb_ads_state *state = talloc_get_type_abort(
1094 m->private_data, struct pdb_ads_state);
1095 const char *attrs[1] = { "member" };
1097 struct tldap_message **msg;
1098 int i, rc, num_members;
1102 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), group);
1103 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1105 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1106 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1107 &msg, "(objectsid=%s)", sidstr);
1108 TALLOC_FREE(sidstr);
1109 if (rc != TLDAP_SUCCESS) {
1110 DEBUG(10, ("ldap_search failed %s\n",
1111 tldap_errstr(talloc_tos(), state->ld, rc)));
1112 return NT_STATUS_LDAP(rc);
1114 switch talloc_array_length(msg) {
1116 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1121 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1125 if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
1128 return NT_STATUS_OK;
1131 members = talloc_array(mem_ctx, uint32_t, num_members);
1132 if (members == NULL) {
1133 return NT_STATUS_NO_MEMORY;
1136 for (i=0; i<num_members; i++) {
1138 if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
1139 || !sid_peek_rid(&sid, &members[i])) {
1140 TALLOC_FREE(members);
1141 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1145 *pmembers = members;
1146 *pnum_members = num_members;
1147 return NT_STATUS_OK;
1150 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
1151 TALLOC_CTX *mem_ctx,
1153 struct dom_sid **pp_sids,
1155 size_t *p_num_groups)
1157 struct pdb_ads_state *state = talloc_get_type_abort(
1158 m->private_data, struct pdb_ads_state);
1159 struct pdb_ads_samu_private *priv;
1160 const char *attrs[1] = { "objectSid" };
1161 struct tldap_message **groups;
1164 struct dom_sid *group_sids;
1167 priv = pdb_ads_get_samu_private(m, user);
1169 rc = pdb_ads_search_fmt(
1170 state, state->domaindn, TLDAP_SCOPE_SUB,
1171 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
1172 "(&(member=%s)(grouptype=%d)(objectclass=group))",
1173 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
1174 if (rc != TLDAP_SUCCESS) {
1175 DEBUG(10, ("ldap_search failed %s\n",
1176 tldap_errstr(talloc_tos(), state->ld, rc)));
1177 return NT_STATUS_LDAP(rc);
1179 count = talloc_array_length(groups);
1182 * This happens for artificial samu users
1184 DEBUG(10, ("Could not get pdb_ads_samu_private\n"));
1188 group_sids = talloc_array(mem_ctx, struct dom_sid, count+1);
1189 if (group_sids == NULL) {
1190 return NT_STATUS_NO_MEMORY;
1192 gids = talloc_array(mem_ctx, gid_t, count+1);
1194 TALLOC_FREE(group_sids);
1195 return NT_STATUS_NO_MEMORY;
1198 sid_copy(&group_sids[0], pdb_get_group_sid(user));
1199 if (!sid_to_gid(&group_sids[0], &gids[0])) {
1201 TALLOC_FREE(group_sids);
1202 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1206 for (i=0; i<count; i++) {
1207 if (!tldap_pull_binsid(groups[i], "objectSid",
1208 &group_sids[num_groups])) {
1211 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
1214 if (num_groups == count) {
1219 *pp_sids = group_sids;
1221 *p_num_groups = num_groups;
1222 return NT_STATUS_OK;
1225 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
1226 TALLOC_CTX *mem_ctx,
1229 return NT_STATUS_NOT_IMPLEMENTED;
1232 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
1233 TALLOC_CTX *mem_ctx,
1234 uint32 grouprid, uint32 memberrid,
1237 struct pdb_ads_state *state = talloc_get_type_abort(
1238 m->private_data, struct pdb_ads_state);
1239 TALLOC_CTX *frame = talloc_stackframe();
1240 struct tldap_context *ld;
1241 struct dom_sid groupsid, membersid;
1242 char *groupdn, *memberdn;
1243 struct tldap_mod *mods;
1248 ld = pdb_ads_ld(state);
1250 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1253 sid_compose(&groupsid, &state->domainsid, grouprid);
1254 sid_compose(&membersid, &state->domainsid, memberrid);
1256 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
1257 if (!NT_STATUS_IS_OK(status)) {
1259 return NT_STATUS_NO_SUCH_GROUP;
1261 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
1262 if (!NT_STATUS_IS_OK(status)) {
1264 return NT_STATUS_NO_SUCH_USER;
1270 if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op,
1271 "member", memberdn)) {
1273 return NT_STATUS_NO_MEMORY;
1276 rc = tldap_modify(ld, groupdn, mods, num_mods, NULL, 0, NULL, 0);
1278 if (rc != TLDAP_SUCCESS) {
1279 DEBUG(10, ("ldap_modify failed: %s\n",
1280 tldap_errstr(talloc_tos(), state->ld, rc)));
1281 if ((mod_op == TLDAP_MOD_ADD) &&
1282 (rc == TLDAP_ALREADY_EXISTS)) {
1283 return NT_STATUS_MEMBER_IN_GROUP;
1285 if ((mod_op == TLDAP_MOD_DELETE) &&
1286 (rc == TLDAP_UNWILLING_TO_PERFORM)) {
1287 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1289 return NT_STATUS_LDAP(rc);
1292 return NT_STATUS_OK;
1295 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
1296 TALLOC_CTX *mem_ctx,
1297 uint32 group_rid, uint32 member_rid)
1299 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1303 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
1304 TALLOC_CTX *mem_ctx,
1305 uint32 group_rid, uint32 member_rid)
1307 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1311 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
1312 const char *name, uint32 *rid)
1314 TALLOC_CTX *frame = talloc_stackframe();
1315 struct pdb_ads_state *state = talloc_get_type_abort(
1316 m->private_data, struct pdb_ads_state);
1317 struct tldap_context *ld;
1318 const char *attrs[1] = { "objectSid" };
1320 struct tldap_mod *mods = NULL;
1321 struct tldap_message **alias;
1327 ld = pdb_ads_ld(state);
1329 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1332 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1336 return NT_STATUS_NO_MEMORY;
1339 ok &= tldap_make_mod_fmt(
1340 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
1342 ok &= tldap_make_mod_fmt(
1343 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group");
1344 ok &= tldap_make_mod_fmt(
1345 NULL, talloc_tos(), &mods, &num_mods, "groupType",
1346 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1350 return NT_STATUS_NO_MEMORY;
1353 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1354 if (rc != TLDAP_SUCCESS) {
1355 DEBUG(10, ("ldap_add failed %s\n",
1356 tldap_errstr(talloc_tos(), state->ld, rc)));
1358 return NT_STATUS_LDAP(rc);
1361 rc = pdb_ads_search_fmt(
1362 state, state->domaindn, TLDAP_SCOPE_SUB,
1363 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1364 "(&(objectclass=group)(samaccountname=%s))", name);
1365 if (rc != TLDAP_SUCCESS) {
1366 DEBUG(10, ("Could not find just created alias %s: %s\n",
1367 name, tldap_errstr(talloc_tos(), state->ld, rc)));
1369 return NT_STATUS_LDAP(rc);
1372 if (talloc_array_length(alias) != 1) {
1373 DEBUG(10, ("Got %d alias, expected one\n",
1374 (int)talloc_array_length(alias)));
1376 return NT_STATUS_LDAP(rc);
1379 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1380 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1383 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1386 sid_peek_rid(&sid, rid);
1388 return NT_STATUS_OK;
1391 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1392 const struct dom_sid *sid)
1394 struct pdb_ads_state *state = talloc_get_type_abort(
1395 m->private_data, struct pdb_ads_state);
1396 struct tldap_context *ld;
1397 struct tldap_message **alias;
1398 char *sidstr, *dn = NULL;
1401 ld = pdb_ads_ld(state);
1403 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1406 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1407 if (sidstr == NULL) {
1408 return NT_STATUS_NO_MEMORY;
1411 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1412 NULL, 0, 0, talloc_tos(), &alias,
1413 "(&(objectSid=%s)(objectclass=group)"
1414 "(|(grouptype=%d)(grouptype=%d)))",
1415 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1416 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1417 TALLOC_FREE(sidstr);
1418 if (rc != TLDAP_SUCCESS) {
1419 DEBUG(10, ("ldap_search failed: %s\n",
1420 tldap_errstr(talloc_tos(), state->ld, rc)));
1421 return NT_STATUS_LDAP(rc);
1423 if (talloc_array_length(alias) != 1) {
1424 DEBUG(10, ("Expected 1 alias, got %d\n",
1425 (int)talloc_array_length(alias)));
1426 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1428 if (!tldap_entry_dn(alias[0], &dn)) {
1429 DEBUG(10, ("Could not get DN for alias %s\n",
1430 sid_string_dbg(sid)));
1431 return NT_STATUS_INTERNAL_ERROR;
1434 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
1435 if (rc != TLDAP_SUCCESS) {
1436 DEBUG(10, ("ldap_delete failed: %s\n",
1437 tldap_errstr(talloc_tos(), state->ld, rc)));
1438 return NT_STATUS_LDAP(rc);
1441 return NT_STATUS_OK;
1444 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1445 const struct dom_sid *sid,
1446 struct acct_info *info)
1448 struct pdb_ads_state *state = talloc_get_type_abort(
1449 m->private_data, struct pdb_ads_state);
1450 struct tldap_context *ld;
1451 const char *attrs[3] = { "objectSid", "description",
1453 struct tldap_message **msg;
1456 struct tldap_mod *mods;
1460 ld = pdb_ads_ld(state);
1462 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1465 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1466 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1468 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1469 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1470 &msg, "(&(objectSid=%s)(objectclass=group)"
1471 "(|(grouptype=%d)(grouptype=%d)))",
1472 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1473 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1474 TALLOC_FREE(sidstr);
1475 if (rc != TLDAP_SUCCESS) {
1476 DEBUG(10, ("ldap_search failed %s\n",
1477 tldap_errstr(talloc_tos(), state->ld, rc)));
1478 return NT_STATUS_LDAP(rc);
1480 switch talloc_array_length(msg) {
1482 return NT_STATUS_NO_SUCH_ALIAS;
1486 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1489 if (!tldap_entry_dn(msg[0], &dn)) {
1491 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1498 ok &= tldap_make_mod_fmt(
1499 msg[0], msg, &mods, &num_mods, "description",
1500 "%s", info->acct_desc);
1501 ok &= tldap_make_mod_fmt(
1502 msg[0], msg, &mods, &num_mods, "samAccountName",
1503 "%s", info->acct_name);
1506 return NT_STATUS_NO_MEMORY;
1508 if (num_mods == 0) {
1511 return NT_STATUS_OK;
1514 rc = tldap_modify(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1516 if (rc != TLDAP_SUCCESS) {
1517 DEBUG(10, ("ldap_modify failed: %s\n",
1518 tldap_errstr(talloc_tos(), state->ld, rc)));
1519 return NT_STATUS_LDAP(rc);
1521 return NT_STATUS_OK;
1524 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1525 const struct dom_sid *sid,
1526 TALLOC_CTX *mem_ctx, char **pdn)
1528 struct tldap_message **msg;
1532 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1533 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1535 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1536 NULL, 0, 0, talloc_tos(), &msg,
1537 "(objectsid=%s)", sidstr);
1538 TALLOC_FREE(sidstr);
1539 if (rc != TLDAP_SUCCESS) {
1540 DEBUG(10, ("ldap_search failed %s\n",
1541 tldap_errstr(talloc_tos(), state->ld, rc)));
1542 return NT_STATUS_LDAP(rc);
1545 switch talloc_array_length(msg) {
1547 return NT_STATUS_NOT_FOUND;
1551 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1554 if (!tldap_entry_dn(msg[0], &dn)) {
1555 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1558 dn = talloc_strdup(mem_ctx, dn);
1560 return NT_STATUS_NO_MEMORY;
1565 return NT_STATUS_OK;
1568 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1569 const struct dom_sid *alias,
1570 const struct dom_sid *member,
1573 struct pdb_ads_state *state = talloc_get_type_abort(
1574 m->private_data, struct pdb_ads_state);
1575 struct tldap_context *ld;
1576 TALLOC_CTX *frame = talloc_stackframe();
1577 struct tldap_mod *mods;
1580 char *aliasdn, *memberdn;
1583 ld = pdb_ads_ld(state);
1585 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1588 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1589 if (!NT_STATUS_IS_OK(status)) {
1590 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1591 sid_string_dbg(alias), nt_errstr(status)));
1593 return NT_STATUS_NO_SUCH_ALIAS;
1595 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1596 if (!NT_STATUS_IS_OK(status)) {
1597 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1598 sid_string_dbg(member), nt_errstr(status)));
1606 if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op,
1607 "member", memberdn)) {
1609 return NT_STATUS_NO_MEMORY;
1612 rc = tldap_modify(ld, aliasdn, mods, num_mods, NULL, 0, NULL, 0);
1614 if (rc != TLDAP_SUCCESS) {
1615 DEBUG(10, ("ldap_modify failed: %s\n",
1616 tldap_errstr(talloc_tos(), state->ld, rc)));
1617 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1618 return NT_STATUS_MEMBER_IN_ALIAS;
1620 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1621 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1623 return NT_STATUS_LDAP(rc);
1626 return NT_STATUS_OK;
1629 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1630 const struct dom_sid *alias,
1631 const struct dom_sid *member)
1633 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1636 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1637 const struct dom_sid *alias,
1638 const struct dom_sid *member)
1640 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1643 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
1644 struct dom_sid *psid)
1646 const char *attrs[1] = { "objectSid" };
1647 struct tldap_message **msg;
1653 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1654 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 struct pdb_ads_search_state **pstate)
1990 struct pdb_ads_state *state = talloc_get_type_abort(
1991 m->private_data, struct pdb_ads_state);
1992 struct pdb_ads_search_state *sstate;
1993 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1994 "userAccountControl", "description" };
1995 struct tldap_message **users;
1996 int i, rc, num_users;
1998 sstate = talloc_zero(search, struct pdb_ads_search_state);
1999 if (sstate == NULL) {
2003 rc = pdb_ads_search_fmt(
2004 state, state->domaindn, TLDAP_SCOPE_SUB,
2005 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
2007 if (rc != TLDAP_SUCCESS) {
2008 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
2009 tldap_errstr(talloc_tos(), state->ld, rc)));
2013 num_users = talloc_array_length(users);
2015 sstate->entries = talloc_array(sstate, struct samr_displayentry,
2017 if (sstate->entries == NULL) {
2018 DEBUG(10, ("talloc failed\n"));
2022 sstate->num_entries = 0;
2024 for (i=0; i<num_users; i++) {
2025 struct samr_displayentry *e;
2029 e = &sstate->entries[sstate->num_entries];
2031 e->idx = sstate->num_entries;
2032 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
2033 DEBUG(10, ("Could not pull sid\n"));
2036 sid_peek_rid(&sid, &e->rid);
2038 if (tldap_pull_uint32(users[i], "userAccountControl", &ctrl)) {
2039 e->acct_flags = ds_uf2acb(ctrl);
2040 if (e->acct_flags & (ACB_WSTRUST|ACB_SVRTRUST)) {
2041 e->acct_flags |= ACB_NORMAL;
2044 e->acct_flags = ACB_NORMAL;
2047 if (e->rid == DOMAIN_RID_GUEST) {
2049 * Guest is specially crafted in s3. Make
2050 * QueryDisplayInfo match QueryUserInfo
2052 e->account_name = lp_guestaccount();
2053 e->fullname = lp_guestaccount();
2054 e->description = "";
2055 e->acct_flags = ACB_NORMAL;
2057 e->account_name = tldap_talloc_single_attribute(
2058 users[i], "samAccountName", sstate->entries);
2059 e->fullname = tldap_talloc_single_attribute(
2060 users[i], "displayName", sstate->entries);
2061 e->description = tldap_talloc_single_attribute(
2062 users[i], "description", sstate->entries);
2064 if (e->account_name == NULL) {
2067 if (e->fullname == NULL) {
2070 if (e->description == NULL) {
2071 e->description = "";
2074 sstate->num_entries += 1;
2075 if (sstate->num_entries >= num_users) {
2080 search->private_data = sstate;
2081 search->next_entry = pdb_ads_next_entry;
2082 search->search_end = pdb_ads_search_end;
2087 static bool pdb_ads_search_users(struct pdb_methods *m,
2088 struct pdb_search *search,
2091 struct pdb_ads_search_state *sstate;
2095 if (acct_flags & ACB_NORMAL) {
2096 filter = talloc_asprintf(
2098 "(&(objectclass=user)(sAMAccountType=%d))",
2099 ATYPE_NORMAL_ACCOUNT);
2100 } else if (acct_flags & ACB_WSTRUST) {
2101 filter = talloc_asprintf(
2103 "(&(objectclass=user)(sAMAccountType=%d))",
2104 ATYPE_WORKSTATION_TRUST);
2106 filter = talloc_strdup(talloc_tos(), "(objectclass=user)");
2108 if (filter == NULL) {
2112 ret = pdb_ads_search_filter(m, search, filter, &sstate);
2113 TALLOC_FREE(filter);
2117 sstate->acct_flags = acct_flags;
2121 static bool pdb_ads_search_groups(struct pdb_methods *m,
2122 struct pdb_search *search)
2124 struct pdb_ads_search_state *sstate;
2128 filter = talloc_asprintf(talloc_tos(),
2129 "(&(grouptype=%d)(objectclass=group))",
2130 GTYPE_SECURITY_GLOBAL_GROUP);
2131 if (filter == NULL) {
2134 ret = pdb_ads_search_filter(m, search, filter, &sstate);
2135 TALLOC_FREE(filter);
2139 sstate->acct_flags = 0;
2143 static bool pdb_ads_search_aliases(struct pdb_methods *m,
2144 struct pdb_search *search,
2145 const struct dom_sid *sid)
2147 struct pdb_ads_search_state *sstate;
2151 filter = talloc_asprintf(
2152 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
2153 sid_check_is_builtin(sid)
2154 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2155 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
2157 if (filter == NULL) {
2160 ret = pdb_ads_search_filter(m, search, filter, &sstate);
2161 TALLOC_FREE(filter);
2165 sstate->acct_flags = 0;
2169 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
2170 struct dom_sid *sid)
2172 struct pdb_ads_state *state = talloc_get_type_abort(
2173 m->private_data, struct pdb_ads_state);
2174 sid_compose(sid, &state->domainsid, uid);
2178 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
2179 struct dom_sid *sid)
2181 struct pdb_ads_state *state = talloc_get_type_abort(
2182 m->private_data, struct pdb_ads_state);
2183 sid_compose(sid, &state->domainsid, gid);
2187 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2188 union unid_t *id, enum lsa_SidType *type)
2190 struct pdb_ads_state *state = talloc_get_type_abort(
2191 m->private_data, struct pdb_ads_state);
2192 struct tldap_message **msg;
2198 * This is a big, big hack: Just hard-code the rid as uid/gid.
2201 sid_peek_rid(sid, &rid);
2203 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
2204 if (sidstr == NULL) {
2208 rc = pdb_ads_search_fmt(
2209 state, state->domaindn, TLDAP_SCOPE_SUB,
2210 NULL, 0, 0, talloc_tos(), &msg,
2211 "(&(objectsid=%s)(objectclass=user))", sidstr);
2212 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
2214 *type = SID_NAME_USER;
2215 TALLOC_FREE(sidstr);
2219 rc = pdb_ads_search_fmt(
2220 state, state->domaindn, TLDAP_SCOPE_SUB,
2221 NULL, 0, 0, talloc_tos(), &msg,
2222 "(&(objectsid=%s)(objectclass=group))", sidstr);
2223 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
2225 *type = SID_NAME_DOM_GRP;
2226 TALLOC_FREE(sidstr);
2230 TALLOC_FREE(sidstr);
2234 static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
2236 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2239 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
2244 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
2245 const char *domain, char** pwd,
2246 struct dom_sid *sid,
2247 time_t *pass_last_set_time)
2252 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
2253 const char* domain, const char* pwd,
2254 const struct dom_sid *sid)
2259 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
2265 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
2266 TALLOC_CTX *mem_ctx,
2267 uint32 *num_domains,
2268 struct trustdom_info ***domains)
2272 return NT_STATUS_OK;
2275 static void pdb_ads_init_methods(struct pdb_methods *m)
2278 m->get_domain_info = pdb_ads_get_domain_info;
2279 m->getsampwnam = pdb_ads_getsampwnam;
2280 m->getsampwsid = pdb_ads_getsampwsid;
2281 m->create_user = pdb_ads_create_user;
2282 m->delete_user = pdb_ads_delete_user;
2283 m->add_sam_account = pdb_ads_add_sam_account;
2284 m->update_sam_account = pdb_ads_update_sam_account;
2285 m->delete_sam_account = pdb_ads_delete_sam_account;
2286 m->rename_sam_account = pdb_ads_rename_sam_account;
2287 m->update_login_attempts = pdb_ads_update_login_attempts;
2288 m->getgrsid = pdb_ads_getgrsid;
2289 m->getgrgid = pdb_ads_getgrgid;
2290 m->getgrnam = pdb_ads_getgrnam;
2291 m->create_dom_group = pdb_ads_create_dom_group;
2292 m->delete_dom_group = pdb_ads_delete_dom_group;
2293 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
2294 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
2295 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
2296 m->enum_group_mapping = pdb_ads_enum_group_mapping;
2297 m->enum_group_members = pdb_ads_enum_group_members;
2298 m->enum_group_memberships = pdb_ads_enum_group_memberships;
2299 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
2300 m->add_groupmem = pdb_ads_add_groupmem;
2301 m->del_groupmem = pdb_ads_del_groupmem;
2302 m->create_alias = pdb_ads_create_alias;
2303 m->delete_alias = pdb_ads_delete_alias;
2304 m->get_aliasinfo = pdb_default_get_aliasinfo;
2305 m->set_aliasinfo = pdb_ads_set_aliasinfo;
2306 m->add_aliasmem = pdb_ads_add_aliasmem;
2307 m->del_aliasmem = pdb_ads_del_aliasmem;
2308 m->enum_aliasmem = pdb_ads_enum_aliasmem;
2309 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
2310 m->lookup_rids = pdb_ads_lookup_rids;
2311 m->lookup_names = pdb_ads_lookup_names;
2312 m->get_account_policy = pdb_ads_get_account_policy;
2313 m->set_account_policy = pdb_ads_set_account_policy;
2314 m->get_seq_num = pdb_ads_get_seq_num;
2315 m->search_users = pdb_ads_search_users;
2316 m->search_groups = pdb_ads_search_groups;
2317 m->search_aliases = pdb_ads_search_aliases;
2318 m->uid_to_sid = pdb_ads_uid_to_sid;
2319 m->gid_to_sid = pdb_ads_gid_to_sid;
2320 m->sid_to_id = pdb_ads_sid_to_id;
2321 m->capabilities = pdb_ads_capabilities;
2322 m->new_rid = pdb_ads_new_rid;
2323 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2324 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2325 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2326 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2329 static void free_private_data(void **vp)
2331 struct pdb_ads_state *state = talloc_get_type_abort(
2332 *vp, struct pdb_ads_state);
2334 TALLOC_FREE(state->ld);
2339 this is used to catch debug messages from events
2341 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2342 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
2344 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2345 const char *fmt, va_list ap)
2347 int samba_level = -1;
2350 case TLDAP_DEBUG_FATAL:
2353 case TLDAP_DEBUG_ERROR:
2356 case TLDAP_DEBUG_WARNING:
2359 case TLDAP_DEBUG_TRACE:
2364 if (vasprintf(&s, fmt, ap) == -1) {
2367 DEBUG(samba_level, ("tldap: %s", s));
2371 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2376 if (tldap_connection_ok(state->ld)) {
2379 TALLOC_FREE(state->ld);
2381 status = open_socket_out(
2382 (struct sockaddr_storage *)(void *)&state->socket_address,
2384 if (!NT_STATUS_IS_OK(status)) {
2385 DEBUG(10, ("Could not connect to %s: %s\n",
2386 state->socket_address.sun_path, nt_errstr(status)));
2390 set_blocking(fd, false);
2392 state->ld = tldap_context_create(state, fd);
2393 if (state->ld == NULL) {
2397 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2402 int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2403 int scope, const char *attrs[], int num_attrs,
2405 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2406 const char *fmt, ...)
2408 struct tldap_context *ld;
2412 ld = pdb_ads_ld(state);
2414 return TLDAP_SERVER_DOWN;
2418 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2419 mem_ctx, res, fmt, ap);
2422 if (ret != TLDAP_SERVER_DOWN) {
2427 ld = pdb_ads_ld(state);
2429 return TLDAP_SERVER_DOWN;
2433 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2434 mem_ctx, res, fmt, ap);
2439 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2440 const char *location)
2442 const char *domain_attrs[2] = { "objectSid", "objectGUID" };
2443 const char *ncname_attrs[1] = { "netbiosname" };
2444 struct tldap_context *ld;
2445 struct tldap_message *rootdse, **domain, **ncname;
2446 TALLOC_CTX *frame = talloc_stackframe();
2451 ZERO_STRUCT(state->socket_address);
2452 state->socket_address.sun_family = AF_UNIX;
2453 strlcpy(state->socket_address.sun_path, location,
2454 sizeof(state->socket_address.sun_path));
2456 ld = pdb_ads_ld(state);
2458 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2462 rc = tldap_fetch_rootdse(ld);
2463 if (rc != TLDAP_SUCCESS) {
2464 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2465 tldap_errstr(talloc_tos(), state->ld, rc)));
2466 status = NT_STATUS_LDAP(rc);
2469 rootdse = tldap_rootdse(state->ld);
2471 state->domaindn = tldap_talloc_single_attribute(
2472 rootdse, "defaultNamingContext", state);
2473 if (state->domaindn == NULL) {
2474 DEBUG(10, ("Could not get defaultNamingContext\n"));
2475 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2478 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2480 state->configdn = tldap_talloc_single_attribute(
2481 rootdse, "configurationNamingContext", state);
2482 if (state->domaindn == NULL) {
2483 DEBUG(10, ("Could not get configurationNamingContext\n"));
2484 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2487 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2490 * Figure out our domain's SID
2492 rc = pdb_ads_search_fmt(
2493 state, state->domaindn, TLDAP_SCOPE_BASE,
2494 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2495 talloc_tos(), &domain, "(objectclass=*)");
2496 if (rc != TLDAP_SUCCESS) {
2497 DEBUG(10, ("Could not retrieve domain: %s\n",
2498 tldap_errstr(talloc_tos(), state->ld, rc)));
2499 status = NT_STATUS_LDAP(rc);
2503 num_domains = talloc_array_length(domain);
2504 if (num_domains != 1) {
2505 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2506 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2509 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2510 DEBUG(10, ("Could not retrieve domain SID\n"));
2511 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2514 if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) {
2515 DEBUG(10, ("Could not retrieve domain GUID\n"));
2516 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2519 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2522 * Figure out our domain's short name
2524 rc = pdb_ads_search_fmt(
2525 state, state->configdn, TLDAP_SCOPE_SUB,
2526 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2527 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2528 if (rc != TLDAP_SUCCESS) {
2529 DEBUG(10, ("Could not retrieve ncname: %s\n",
2530 tldap_errstr(talloc_tos(), state->ld, rc)));
2531 status = NT_STATUS_LDAP(rc);
2534 if (talloc_array_length(ncname) != 1) {
2535 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2539 state->netbiosname = tldap_talloc_single_attribute(
2540 ncname[0], "netbiosname", state);
2541 if (state->netbiosname == NULL) {
2542 DEBUG(10, ("Could not get netbiosname\n"));
2543 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2546 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2548 if (!strequal(lp_workgroup(), state->netbiosname)) {
2549 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2550 state->netbiosname, lp_workgroup()));
2551 status = NT_STATUS_NO_SUCH_DOMAIN;
2555 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2557 status = NT_STATUS_OK;
2563 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2564 const char *location)
2566 struct pdb_methods *m;
2567 struct pdb_ads_state *state;
2571 m = talloc(NULL, struct pdb_methods);
2573 return NT_STATUS_NO_MEMORY;
2575 state = talloc_zero(m, struct pdb_ads_state);
2576 if (state == NULL) {
2579 m->private_data = state;
2580 m->free_private_data = free_private_data;
2581 pdb_ads_init_methods(m);
2583 if (location == NULL) {
2584 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2588 if (location == NULL) {
2592 status = pdb_ads_connect(state, location);
2593 if (!NT_STATUS_IS_OK(status)) {
2594 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2599 return NT_STATUS_OK;
2601 status = NT_STATUS_NO_MEMORY;
2607 NTSTATUS pdb_ads_init(void);
2608 NTSTATUS pdb_ads_init(void)
2610 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",