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 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 struct tldap_message **msg;
2211 * This is a big, big hack: Just hard-code the rid as uid/gid.
2214 sid_peek_rid(sid, &rid);
2216 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
2217 if (sidstr == NULL) {
2221 rc = pdb_ads_search_fmt(
2222 state, state->domaindn, TLDAP_SCOPE_SUB,
2223 NULL, 0, 0, talloc_tos(), &msg,
2224 "(&(objectsid=%s)(objectclass=user))", sidstr);
2225 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
2227 *type = SID_NAME_USER;
2228 TALLOC_FREE(sidstr);
2232 rc = pdb_ads_search_fmt(
2233 state, state->domaindn, TLDAP_SCOPE_SUB,
2234 NULL, 0, 0, talloc_tos(), &msg,
2235 "(&(objectsid=%s)(objectclass=group))", sidstr);
2236 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
2238 *type = SID_NAME_DOM_GRP;
2239 TALLOC_FREE(sidstr);
2243 TALLOC_FREE(sidstr);
2247 static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
2249 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2252 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
2257 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
2258 const char *domain, char** pwd,
2259 struct dom_sid *sid,
2260 time_t *pass_last_set_time)
2265 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
2266 const char* domain, const char* pwd,
2267 const struct dom_sid *sid)
2272 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
2278 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
2279 TALLOC_CTX *mem_ctx,
2280 uint32 *num_domains,
2281 struct trustdom_info ***domains)
2285 return NT_STATUS_OK;
2288 static void pdb_ads_init_methods(struct pdb_methods *m)
2291 m->get_domain_info = pdb_ads_get_domain_info;
2292 m->getsampwnam = pdb_ads_getsampwnam;
2293 m->getsampwsid = pdb_ads_getsampwsid;
2294 m->create_user = pdb_ads_create_user;
2295 m->delete_user = pdb_ads_delete_user;
2296 m->add_sam_account = pdb_ads_add_sam_account;
2297 m->update_sam_account = pdb_ads_update_sam_account;
2298 m->delete_sam_account = pdb_ads_delete_sam_account;
2299 m->rename_sam_account = pdb_ads_rename_sam_account;
2300 m->update_login_attempts = pdb_ads_update_login_attempts;
2301 m->getgrsid = pdb_ads_getgrsid;
2302 m->getgrgid = pdb_ads_getgrgid;
2303 m->getgrnam = pdb_ads_getgrnam;
2304 m->create_dom_group = pdb_ads_create_dom_group;
2305 m->delete_dom_group = pdb_ads_delete_dom_group;
2306 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
2307 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
2308 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
2309 m->enum_group_mapping = pdb_ads_enum_group_mapping;
2310 m->enum_group_members = pdb_ads_enum_group_members;
2311 m->enum_group_memberships = pdb_ads_enum_group_memberships;
2312 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
2313 m->add_groupmem = pdb_ads_add_groupmem;
2314 m->del_groupmem = pdb_ads_del_groupmem;
2315 m->create_alias = pdb_ads_create_alias;
2316 m->delete_alias = pdb_ads_delete_alias;
2317 m->get_aliasinfo = pdb_default_get_aliasinfo;
2318 m->set_aliasinfo = pdb_ads_set_aliasinfo;
2319 m->add_aliasmem = pdb_ads_add_aliasmem;
2320 m->del_aliasmem = pdb_ads_del_aliasmem;
2321 m->enum_aliasmem = pdb_ads_enum_aliasmem;
2322 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
2323 m->lookup_rids = pdb_ads_lookup_rids;
2324 m->lookup_names = pdb_ads_lookup_names;
2325 m->get_account_policy = pdb_ads_get_account_policy;
2326 m->set_account_policy = pdb_ads_set_account_policy;
2327 m->get_seq_num = pdb_ads_get_seq_num;
2328 m->search_users = pdb_ads_search_users;
2329 m->search_groups = pdb_ads_search_groups;
2330 m->search_aliases = pdb_ads_search_aliases;
2331 m->uid_to_sid = pdb_ads_uid_to_sid;
2332 m->gid_to_sid = pdb_ads_gid_to_sid;
2333 m->sid_to_id = pdb_ads_sid_to_id;
2334 m->capabilities = pdb_ads_capabilities;
2335 m->new_rid = pdb_ads_new_rid;
2336 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2337 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2338 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2339 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2342 static void free_private_data(void **vp)
2344 struct pdb_ads_state *state = talloc_get_type_abort(
2345 *vp, struct pdb_ads_state);
2347 TALLOC_FREE(state->ld);
2352 this is used to catch debug messages from events
2354 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2355 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
2357 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2358 const char *fmt, va_list ap)
2360 int samba_level = -1;
2363 case TLDAP_DEBUG_FATAL:
2366 case TLDAP_DEBUG_ERROR:
2369 case TLDAP_DEBUG_WARNING:
2372 case TLDAP_DEBUG_TRACE:
2377 if (vasprintf(&s, fmt, ap) == -1) {
2380 DEBUG(samba_level, ("tldap: %s", s));
2384 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2389 if (tldap_connection_ok(state->ld)) {
2392 TALLOC_FREE(state->ld);
2394 status = open_socket_out(
2395 (struct sockaddr_storage *)(void *)&state->socket_address,
2397 if (!NT_STATUS_IS_OK(status)) {
2398 DEBUG(10, ("Could not connect to %s: %s\n",
2399 state->socket_address.sun_path, nt_errstr(status)));
2403 set_blocking(fd, false);
2405 state->ld = tldap_context_create(state, fd);
2406 if (state->ld == NULL) {
2410 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2415 int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2416 int scope, const char *attrs[], int num_attrs,
2418 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2419 const char *fmt, ...)
2421 struct tldap_context *ld;
2425 ld = pdb_ads_ld(state);
2427 return TLDAP_SERVER_DOWN;
2431 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2432 mem_ctx, res, fmt, ap);
2435 if (ret != TLDAP_SERVER_DOWN) {
2440 ld = pdb_ads_ld(state);
2442 return TLDAP_SERVER_DOWN;
2446 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2447 mem_ctx, res, fmt, ap);
2452 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2453 const char *location)
2455 const char *domain_attrs[2] = { "objectSid", "objectGUID" };
2456 const char *ncname_attrs[1] = { "netbiosname" };
2457 struct tldap_context *ld;
2458 struct tldap_message *rootdse, **domain, **ncname;
2459 TALLOC_CTX *frame = talloc_stackframe();
2464 ZERO_STRUCT(state->socket_address);
2465 state->socket_address.sun_family = AF_UNIX;
2466 strlcpy(state->socket_address.sun_path, location,
2467 sizeof(state->socket_address.sun_path));
2469 ld = pdb_ads_ld(state);
2471 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2475 rc = tldap_fetch_rootdse(ld);
2476 if (rc != TLDAP_SUCCESS) {
2477 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2478 tldap_errstr(talloc_tos(), state->ld, rc)));
2479 status = NT_STATUS_LDAP(rc);
2482 rootdse = tldap_rootdse(state->ld);
2484 state->domaindn = tldap_talloc_single_attribute(
2485 rootdse, "defaultNamingContext", state);
2486 if (state->domaindn == NULL) {
2487 DEBUG(10, ("Could not get defaultNamingContext\n"));
2488 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2491 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2493 state->configdn = tldap_talloc_single_attribute(
2494 rootdse, "configurationNamingContext", state);
2495 if (state->domaindn == NULL) {
2496 DEBUG(10, ("Could not get configurationNamingContext\n"));
2497 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2500 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2503 * Figure out our domain's SID
2505 rc = pdb_ads_search_fmt(
2506 state, state->domaindn, TLDAP_SCOPE_BASE,
2507 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2508 talloc_tos(), &domain, "(objectclass=*)");
2509 if (rc != TLDAP_SUCCESS) {
2510 DEBUG(10, ("Could not retrieve domain: %s\n",
2511 tldap_errstr(talloc_tos(), state->ld, rc)));
2512 status = NT_STATUS_LDAP(rc);
2516 num_domains = talloc_array_length(domain);
2517 if (num_domains != 1) {
2518 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2519 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2522 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2523 DEBUG(10, ("Could not retrieve domain SID\n"));
2524 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2527 if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) {
2528 DEBUG(10, ("Could not retrieve domain GUID\n"));
2529 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2532 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2535 * Figure out our domain's short name
2537 rc = pdb_ads_search_fmt(
2538 state, state->configdn, TLDAP_SCOPE_SUB,
2539 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2540 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2541 if (rc != TLDAP_SUCCESS) {
2542 DEBUG(10, ("Could not retrieve ncname: %s\n",
2543 tldap_errstr(talloc_tos(), state->ld, rc)));
2544 status = NT_STATUS_LDAP(rc);
2547 if (talloc_array_length(ncname) != 1) {
2548 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2552 state->netbiosname = tldap_talloc_single_attribute(
2553 ncname[0], "netbiosname", state);
2554 if (state->netbiosname == NULL) {
2555 DEBUG(10, ("Could not get netbiosname\n"));
2556 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2559 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2561 if (!strequal(lp_workgroup(), state->netbiosname)) {
2562 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2563 state->netbiosname, lp_workgroup()));
2564 status = NT_STATUS_NO_SUCH_DOMAIN;
2568 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2570 status = NT_STATUS_OK;
2576 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2577 const char *location)
2579 struct pdb_methods *m;
2580 struct pdb_ads_state *state;
2584 m = talloc(NULL, struct pdb_methods);
2586 return NT_STATUS_NO_MEMORY;
2588 state = talloc_zero(m, struct pdb_ads_state);
2589 if (state == NULL) {
2592 m->private_data = state;
2593 m->free_private_data = free_private_data;
2594 pdb_ads_init_methods(m);
2596 if (location == NULL) {
2597 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2601 if (location == NULL) {
2605 status = pdb_ads_connect(state, location);
2606 if (!NT_STATUS_IS_OK(status)) {
2607 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2612 return NT_STATUS_OK;
2614 status = NT_STATUS_NO_MEMORY;
2620 NTSTATUS pdb_ads_init(void);
2621 NTSTATUS pdb_ads_init(void)
2623 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",