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"
24 struct pdb_ads_state {
25 struct sockaddr_un socket_address;
26 struct tldap_context *ld;
27 struct dom_sid domainsid;
28 struct GUID domainguid;
34 struct pdb_ads_samu_private {
36 struct tldap_message *ldapmsg;
39 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
40 struct samu *sam_acct,
41 const struct dom_sid *sid);
42 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
44 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
45 struct dom_sid *psid);
46 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
47 const struct dom_sid *sid,
48 TALLOC_CTX *mem_ctx, char **pdn);
49 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state);
50 static int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
51 int scope, const char *attrs[], int num_attrs,
53 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
54 const char *fmt, ...);
55 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
58 struct pdb_ads_samu_private **presult);
60 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
65 if (!tldap_pull_uint64(msg, attr, &tmp)) {
68 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
72 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
75 sid_peek_rid(sid, &rid);
79 static char *pdb_ads_domaindn2dns(TALLOC_CTX *mem_ctx, char *dn)
83 result = talloc_string_sub2(mem_ctx, dn, "DC=", "", false, false,
89 while ((p = strchr_m(result, ',')) != NULL) {
96 static struct pdb_domain_info *pdb_ads_get_domain_info(
97 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
99 struct pdb_ads_state *state = talloc_get_type_abort(
100 m->private_data, struct pdb_ads_state);
101 struct pdb_domain_info *info;
102 struct tldap_message *rootdse;
105 info = talloc(mem_ctx, struct pdb_domain_info);
109 info->name = talloc_strdup(info, state->netbiosname);
110 if (info->name == NULL) {
113 info->dns_domain = pdb_ads_domaindn2dns(info, state->domaindn);
114 if (info->dns_domain == NULL) {
118 rootdse = tldap_rootdse(state->ld);
119 tmp = tldap_talloc_single_attribute(rootdse, "rootDomainNamingContext",
124 info->dns_forest = pdb_ads_domaindn2dns(info, tmp);
126 if (info->dns_forest == NULL) {
129 info->sid = state->domainsid;
130 info->guid = state->domainguid;
138 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
139 struct pdb_methods *m, struct samu *sam)
141 struct pdb_ads_state *state = talloc_get_type_abort(
142 m->private_data, struct pdb_ads_state);
143 struct pdb_ads_samu_private *result;
144 char *sidstr, *filter;
147 result = (struct pdb_ads_samu_private *)
148 pdb_get_backend_private_data(sam, m);
150 if (result != NULL) {
151 return talloc_get_type_abort(
152 result, struct pdb_ads_samu_private);
155 sidstr = sid_binstring(talloc_tos(), pdb_get_user_sid(sam));
156 if (sidstr == NULL) {
160 filter = talloc_asprintf(
161 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
163 if (filter == NULL) {
167 status = pdb_ads_getsamupriv(state, filter, sam, &result);
169 if (!NT_STATUS_IS_OK(status)) {
176 static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m,
178 struct pdb_ads_samu_private *priv)
180 struct pdb_ads_state *state = talloc_get_type_abort(
181 m->private_data, struct pdb_ads_state);
182 TALLOC_CTX *frame = talloc_stackframe();
183 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
184 struct tldap_message *entry = priv->ldapmsg;
191 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
193 DEBUG(10, ("no samAccountName\n"));
196 pdb_set_username(sam, str, PDB_SET);
198 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
199 pdb_set_logon_time(sam, tmp_time, PDB_SET);
201 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
202 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
204 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
205 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
207 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
208 pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
211 str = tldap_talloc_single_attribute(entry, "displayName",
214 pdb_set_fullname(sam, str, PDB_SET);
217 str = tldap_talloc_single_attribute(entry, "homeDirectory",
220 pdb_set_homedir(sam, str, PDB_SET);
223 str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
225 pdb_set_dir_drive(sam, str, PDB_SET);
228 str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
230 pdb_set_logon_script(sam, str, PDB_SET);
233 str = tldap_talloc_single_attribute(entry, "profilePath",
236 pdb_set_profile_path(sam, str, PDB_SET);
239 str = tldap_talloc_single_attribute(entry, "profilePath",
242 pdb_set_profile_path(sam, str, PDB_SET);
245 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
246 DEBUG(10, ("Could not pull SID\n"));
249 pdb_set_user_sid(sam, &sid, PDB_SET);
251 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
252 DEBUG(10, ("Could not pull userAccountControl\n"));
255 pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
257 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
258 if (blob.length != NT_HASH_LEN) {
259 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
260 (int)blob.length, NT_HASH_LEN));
263 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
266 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
267 if (blob.length != LM_HASH_LEN) {
268 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
269 (int)blob.length, LM_HASH_LEN));
272 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
275 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
276 sid_compose(&sid, &state->domainsid, n);
277 pdb_set_group_sid(sam, &sid, PDB_SET);
280 status = NT_STATUS_OK;
286 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
287 struct tldap_message *existing,
289 int *pnum_mods, struct tldap_mod **pmods,
295 /* TODO: All fields :-) */
297 ret &= tldap_make_mod_fmt(
298 existing, mem_ctx, pnum_mods, pmods, "displayName",
299 "%s", pdb_get_fullname(sam));
301 blob = data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN);
302 if (blob.data != NULL) {
303 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
304 "unicodePwd", 1, &blob);
307 blob = data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN);
308 if (blob.data != NULL) {
309 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
310 "dBCSPwd", 1, &blob);
313 ret &= tldap_make_mod_fmt(
314 existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
315 "%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
317 ret &= tldap_make_mod_fmt(
318 existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
319 "%s", pdb_get_homedir(sam));
321 ret &= tldap_make_mod_fmt(
322 existing, mem_ctx, pnum_mods, pmods, "homeDrive",
323 "%s", pdb_get_dir_drive(sam));
325 ret &= tldap_make_mod_fmt(
326 existing, mem_ctx, pnum_mods, pmods, "scriptPath",
327 "%s", pdb_get_logon_script(sam));
329 ret &= tldap_make_mod_fmt(
330 existing, mem_ctx, pnum_mods, pmods, "profilePath",
331 "%s", pdb_get_profile_path(sam));
336 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
339 struct pdb_ads_samu_private **presult)
341 const char * attrs[] = {
342 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
343 "sAMAccountName", "displayName", "homeDirectory",
344 "homeDrive", "scriptPath", "profilePath", "description",
345 "userWorkstations", "comment", "userParameters", "objectSid",
346 "primaryGroupID", "userAccountControl", "logonHours",
347 "badPwdCount", "logonCount", "countryCode", "codePage",
348 "unicodePwd", "dBCSPwd" };
349 struct tldap_message **users;
351 struct pdb_ads_samu_private *result;
353 result = talloc(mem_ctx, struct pdb_ads_samu_private);
354 if (result == NULL) {
355 return NT_STATUS_NO_MEMORY;
358 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
359 attrs, ARRAY_SIZE(attrs), 0, result,
360 &users, "%s", filter);
361 if (rc != TLDAP_SUCCESS) {
362 DEBUG(10, ("ldap_search failed %s\n",
363 tldap_errstr(talloc_tos(), state->ld, rc)));
365 return NT_STATUS_LDAP(rc);
368 count = talloc_array_length(users);
370 DEBUG(10, ("Expected 1 user, got %d\n", count));
372 return NT_STATUS_INTERNAL_DB_CORRUPTION;
375 result->ldapmsg = users[0];
376 if (!tldap_entry_dn(result->ldapmsg, &result->dn)) {
377 DEBUG(10, ("Could not extract dn\n"));
379 return NT_STATUS_INTERNAL_DB_CORRUPTION;
386 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
387 struct pdb_ads_state *state,
388 struct samu *sam_acct,
391 struct pdb_ads_samu_private *priv;
394 status = pdb_ads_getsamupriv(state, filter, sam_acct, &priv);
395 if (!NT_STATUS_IS_OK(status)) {
396 DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n",
401 status = pdb_ads_init_sam_from_priv(m, sam_acct, priv);
402 if (!NT_STATUS_IS_OK(status)) {
403 DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n",
409 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
413 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
414 struct samu *sam_acct,
415 const char *username)
417 struct pdb_ads_state *state = talloc_get_type_abort(
418 m->private_data, struct pdb_ads_state);
421 filter = talloc_asprintf(
422 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
424 NT_STATUS_HAVE_NO_MEMORY(filter);
426 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
429 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
430 struct samu *sam_acct,
431 const struct dom_sid *sid)
433 struct pdb_ads_state *state = talloc_get_type_abort(
434 m->private_data, struct pdb_ads_state);
435 char *sidstr, *filter;
437 sidstr = sid_binstring(talloc_tos(), sid);
438 NT_STATUS_HAVE_NO_MEMORY(sidstr);
440 filter = talloc_asprintf(
441 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
443 NT_STATUS_HAVE_NO_MEMORY(filter);
445 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
448 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
450 const char *name, uint32 acct_flags,
453 struct pdb_ads_state *state = talloc_get_type_abort(
454 m->private_data, struct pdb_ads_state);
455 struct tldap_context *ld;
456 const char *attrs[1] = { "objectSid" };
457 struct tldap_mod *mods = NULL;
459 struct tldap_message **user;
465 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
468 return NT_STATUS_NO_MEMORY;
471 ld = pdb_ads_ld(state);
473 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
476 /* TODO: Create machines etc */
479 ok &= tldap_make_mod_fmt(
480 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
481 ok &= tldap_make_mod_fmt(
482 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
485 return NT_STATUS_NO_MEMORY;
489 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
490 if (rc != TLDAP_SUCCESS) {
491 DEBUG(10, ("ldap_add failed %s\n",
492 tldap_errstr(talloc_tos(), ld, rc)));
494 return NT_STATUS_LDAP(rc);
497 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
498 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
500 "(&(objectclass=user)(samaccountname=%s))",
502 if (rc != TLDAP_SUCCESS) {
503 DEBUG(10, ("Could not find just created user %s: %s\n",
504 name, tldap_errstr(talloc_tos(), state->ld, rc)));
506 return NT_STATUS_LDAP(rc);
509 if (talloc_array_length(user) != 1) {
510 DEBUG(10, ("Got %d users, expected one\n",
511 (int)talloc_array_length(user)));
513 return NT_STATUS_LDAP(rc);
516 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
517 DEBUG(10, ("Could not fetch objectSid from user %s\n",
520 return NT_STATUS_INTERNAL_DB_CORRUPTION;
523 sid_peek_rid(&sid, rid);
528 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
532 struct pdb_ads_state *state = talloc_get_type_abort(
533 m->private_data, struct pdb_ads_state);
535 struct tldap_context *ld;
539 ld = pdb_ads_ld(state);
541 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
544 status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
546 if (!NT_STATUS_IS_OK(status)) {
550 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
552 if (rc != TLDAP_SUCCESS) {
553 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
554 tldap_errstr(talloc_tos(), ld, rc)));
555 return NT_STATUS_LDAP(rc);
560 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
561 struct samu *sampass)
563 return NT_STATUS_NOT_IMPLEMENTED;
566 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
569 struct pdb_ads_state *state = talloc_get_type_abort(
570 m->private_data, struct pdb_ads_state);
571 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
572 struct tldap_context *ld;
573 struct tldap_mod *mods = NULL;
574 int rc, num_mods = 0;
576 ld = pdb_ads_ld(state);
578 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
581 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
582 &num_mods, &mods, sam)) {
583 return NT_STATUS_NO_MEMORY;
587 /* Nothing to do, just return success */
591 rc = tldap_modify(ld, priv->dn, num_mods, mods, NULL, 0,
594 if (rc != TLDAP_SUCCESS) {
595 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
596 tldap_errstr(talloc_tos(), ld, rc)));
597 return NT_STATUS_LDAP(rc);
603 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
604 struct samu *username)
606 return NT_STATUS_NOT_IMPLEMENTED;
609 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
610 struct samu *oldname,
613 return NT_STATUS_NOT_IMPLEMENTED;
616 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
617 struct samu *sam_acct,
620 return NT_STATUS_NOT_IMPLEMENTED;
623 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
626 struct pdb_ads_state *state = talloc_get_type_abort(
627 m->private_data, struct pdb_ads_state);
628 const char *attrs[4] = { "objectSid", "description", "samAccountName",
631 struct tldap_message **group;
635 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
636 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
637 &group, "%s", filter);
638 if (rc != TLDAP_SUCCESS) {
639 DEBUG(10, ("ldap_search failed %s\n",
640 tldap_errstr(talloc_tos(), state->ld, rc)));
641 return NT_STATUS_LDAP(rc);
643 if (talloc_array_length(group) != 1) {
644 DEBUG(10, ("Expected 1 user, got %d\n",
645 (int)talloc_array_length(group)));
646 return NT_STATUS_INTERNAL_DB_CORRUPTION;
649 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
650 return NT_STATUS_INTERNAL_DB_CORRUPTION;
652 map->gid = pdb_ads_sid2gid(&map->sid);
654 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
655 return NT_STATUS_INTERNAL_DB_CORRUPTION;
658 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
659 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
660 map->sid_name_use = SID_NAME_ALIAS;
662 case GTYPE_SECURITY_GLOBAL_GROUP:
663 map->sid_name_use = SID_NAME_DOM_GRP;
666 return NT_STATUS_INTERNAL_DB_CORRUPTION;
669 str = tldap_talloc_single_attribute(group[0], "samAccountName",
672 return NT_STATUS_INTERNAL_DB_CORRUPTION;
674 fstrcpy(map->nt_name, str);
677 str = tldap_talloc_single_attribute(group[0], "description",
680 fstrcpy(map->comment, str);
683 map->comment[0] = '\0';
690 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
696 filter = talloc_asprintf(talloc_tos(),
697 "(&(objectsid=%s)(objectclass=group))",
698 sid_string_talloc(talloc_tos(), &sid));
699 if (filter == NULL) {
700 return NT_STATUS_NO_MEMORY;
703 status = pdb_ads_getgrfilter(m, map, filter);
708 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
712 pdb_ads_gid_to_sid(m, gid, &sid);
713 return pdb_ads_getgrsid(m, map, sid);
716 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
722 filter = talloc_asprintf(talloc_tos(),
723 "(&(samaccountname=%s)(objectclass=group))",
725 if (filter == NULL) {
726 return NT_STATUS_NO_MEMORY;
729 status = pdb_ads_getgrfilter(m, map, filter);
734 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
735 TALLOC_CTX *mem_ctx, const char *name,
738 TALLOC_CTX *frame = talloc_stackframe();
739 struct pdb_ads_state *state = talloc_get_type_abort(
740 m->private_data, struct pdb_ads_state);
741 struct tldap_context *ld;
742 const char *attrs[1] = { "objectSid" };
744 struct tldap_mod *mods = NULL;
745 struct tldap_message **alias;
751 ld = pdb_ads_ld(state);
753 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
756 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
760 return NT_STATUS_NO_MEMORY;
763 ok &= tldap_make_mod_fmt(
764 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
766 ok &= tldap_make_mod_fmt(
767 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
768 ok &= tldap_make_mod_fmt(
769 NULL, talloc_tos(), &num_mods, &mods, "groupType",
770 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
774 return NT_STATUS_NO_MEMORY;
777 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
778 if (rc != TLDAP_SUCCESS) {
779 DEBUG(10, ("ldap_add failed %s\n",
780 tldap_errstr(talloc_tos(), state->ld, rc)));
782 return NT_STATUS_LDAP(rc);
785 rc = pdb_ads_search_fmt(
786 state, state->domaindn, TLDAP_SCOPE_SUB,
787 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
788 "(&(objectclass=group)(samaccountname=%s))", name);
789 if (rc != TLDAP_SUCCESS) {
790 DEBUG(10, ("Could not find just created alias %s: %s\n",
791 name, tldap_errstr(talloc_tos(), state->ld, rc)));
793 return NT_STATUS_LDAP(rc);
796 if (talloc_array_length(alias) != 1) {
797 DEBUG(10, ("Got %d alias, expected one\n",
798 (int)talloc_array_length(alias)));
800 return NT_STATUS_LDAP(rc);
803 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
804 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
807 return NT_STATUS_INTERNAL_DB_CORRUPTION;
810 sid_peek_rid(&sid, rid);
815 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
816 TALLOC_CTX *mem_ctx, uint32 rid)
818 struct pdb_ads_state *state = talloc_get_type_abort(
819 m->private_data, struct pdb_ads_state);
820 struct tldap_context *ld;
823 struct tldap_message **msg;
827 sid_compose(&sid, &state->domainsid, rid);
829 sidstr = sid_binstring(talloc_tos(), &sid);
830 NT_STATUS_HAVE_NO_MEMORY(sidstr);
832 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
833 NULL, 0, 0, talloc_tos(), &msg,
834 ("(&(objectSid=%s)(objectClass=group))"),
837 if (rc != TLDAP_SUCCESS) {
838 DEBUG(10, ("ldap_search failed %s\n",
839 tldap_errstr(talloc_tos(), state->ld, rc)));
840 return NT_STATUS_LDAP(rc);
843 switch talloc_array_length(msg) {
845 return NT_STATUS_NO_SUCH_GROUP;
849 return NT_STATUS_INTERNAL_DB_CORRUPTION;
852 if (!tldap_entry_dn(msg[0], &dn)) {
854 return NT_STATUS_INTERNAL_DB_CORRUPTION;
857 ld = pdb_ads_ld(state);
860 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
863 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
865 if (rc != TLDAP_SUCCESS) {
866 DEBUG(10, ("ldap_delete failed: %s\n",
867 tldap_errstr(talloc_tos(), state->ld, rc)));
868 return NT_STATUS_LDAP(rc);
874 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
877 return NT_STATUS_NOT_IMPLEMENTED;
880 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
883 return NT_STATUS_NOT_IMPLEMENTED;
886 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
889 return NT_STATUS_NOT_IMPLEMENTED;
892 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
893 const struct dom_sid *sid,
894 enum lsa_SidType sid_name_use,
896 size_t *p_num_entries,
899 return NT_STATUS_NOT_IMPLEMENTED;
902 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
904 const struct dom_sid *group,
906 size_t *pnum_members)
908 struct pdb_ads_state *state = talloc_get_type_abort(
909 m->private_data, struct pdb_ads_state);
910 const char *attrs[1] = { "member" };
912 struct tldap_message **msg;
913 int i, rc, num_members;
917 sidstr = sid_binstring(talloc_tos(), group);
918 NT_STATUS_HAVE_NO_MEMORY(sidstr);
920 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
921 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
922 &msg, "(objectsid=%s)", sidstr);
924 if (rc != TLDAP_SUCCESS) {
925 DEBUG(10, ("ldap_search failed %s\n",
926 tldap_errstr(talloc_tos(), state->ld, rc)));
927 return NT_STATUS_LDAP(rc);
929 switch talloc_array_length(msg) {
931 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
936 return NT_STATUS_INTERNAL_DB_CORRUPTION;
940 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
941 return NT_STATUS_INTERNAL_DB_CORRUPTION;
944 members = talloc_array(mem_ctx, uint32_t, num_members);
945 if (members == NULL) {
946 return NT_STATUS_NO_MEMORY;
949 for (i=0; i<num_members; i++) {
951 if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
952 || !sid_peek_rid(&sid, &members[i])) {
953 TALLOC_FREE(members);
954 return NT_STATUS_INTERNAL_DB_CORRUPTION;
959 *pnum_members = num_members;
963 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
966 struct dom_sid **pp_sids,
968 size_t *p_num_groups)
970 struct pdb_ads_state *state = talloc_get_type_abort(
971 m->private_data, struct pdb_ads_state);
972 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
974 const char *attrs[1] = { "objectSid" };
975 struct tldap_message **groups;
978 struct dom_sid *group_sids;
981 rc = pdb_ads_search_fmt(
982 state, state->domaindn, TLDAP_SCOPE_SUB,
983 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
984 "(&(member=%s)(grouptype=%d)(objectclass=group))",
985 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
986 if (rc != TLDAP_SUCCESS) {
987 DEBUG(10, ("ldap_search failed %s\n",
988 tldap_errstr(talloc_tos(), state->ld, rc)));
989 return NT_STATUS_LDAP(rc);
992 count = talloc_array_length(groups);
994 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
995 if (group_sids == NULL) {
996 return NT_STATUS_NO_MEMORY;
998 gids = talloc_array(mem_ctx, gid_t, count);
1000 TALLOC_FREE(group_sids);
1001 return NT_STATUS_NO_MEMORY;
1005 for (i=0; i<count; i++) {
1006 if (!tldap_pull_binsid(groups[i], "objectSid",
1007 &group_sids[num_groups])) {
1010 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
1013 if (num_groups == count) {
1018 *pp_sids = group_sids;
1020 *p_num_groups = num_groups;
1021 return NT_STATUS_OK;
1024 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
1025 TALLOC_CTX *mem_ctx,
1028 return NT_STATUS_NOT_IMPLEMENTED;
1031 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
1032 TALLOC_CTX *mem_ctx,
1033 uint32 grouprid, uint32 memberrid,
1036 struct pdb_ads_state *state = talloc_get_type_abort(
1037 m->private_data, struct pdb_ads_state);
1038 TALLOC_CTX *frame = talloc_stackframe();
1039 struct tldap_context *ld;
1040 struct dom_sid groupsid, membersid;
1041 char *groupdn, *memberdn;
1042 struct tldap_mod *mods;
1046 ld = pdb_ads_ld(state);
1048 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1051 sid_compose(&groupsid, &state->domainsid, grouprid);
1052 sid_compose(&membersid, &state->domainsid, memberrid);
1054 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
1055 if (!NT_STATUS_IS_OK(status)) {
1057 return NT_STATUS_NO_SUCH_GROUP;
1059 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
1060 if (!NT_STATUS_IS_OK(status)) {
1062 return NT_STATUS_NO_SUCH_USER;
1067 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1068 "member", memberdn)) {
1070 return NT_STATUS_NO_MEMORY;
1073 rc = tldap_modify(ld, groupdn, 1, mods, NULL, 0, NULL, 0);
1075 if (rc != TLDAP_SUCCESS) {
1076 DEBUG(10, ("ldap_modify failed: %s\n",
1077 tldap_errstr(talloc_tos(), state->ld, rc)));
1078 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1079 return NT_STATUS_MEMBER_IN_GROUP;
1081 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1082 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1084 return NT_STATUS_LDAP(rc);
1087 return NT_STATUS_OK;
1090 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
1091 TALLOC_CTX *mem_ctx,
1092 uint32 group_rid, uint32 member_rid)
1094 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1098 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
1099 TALLOC_CTX *mem_ctx,
1100 uint32 group_rid, uint32 member_rid)
1102 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1106 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
1107 const char *name, uint32 *rid)
1109 TALLOC_CTX *frame = talloc_stackframe();
1110 struct pdb_ads_state *state = talloc_get_type_abort(
1111 m->private_data, struct pdb_ads_state);
1112 struct tldap_context *ld;
1113 const char *attrs[1] = { "objectSid" };
1115 struct tldap_mod *mods = NULL;
1116 struct tldap_message **alias;
1122 ld = pdb_ads_ld(state);
1124 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1127 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1131 return NT_STATUS_NO_MEMORY;
1134 ok &= tldap_make_mod_fmt(
1135 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
1137 ok &= tldap_make_mod_fmt(
1138 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
1139 ok &= tldap_make_mod_fmt(
1140 NULL, talloc_tos(), &num_mods, &mods, "groupType",
1141 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1145 return NT_STATUS_NO_MEMORY;
1148 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1149 if (rc != TLDAP_SUCCESS) {
1150 DEBUG(10, ("ldap_add failed %s\n",
1151 tldap_errstr(talloc_tos(), state->ld, rc)));
1153 return NT_STATUS_LDAP(rc);
1156 rc = pdb_ads_search_fmt(
1157 state, state->domaindn, TLDAP_SCOPE_SUB,
1158 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1159 "(&(objectclass=group)(samaccountname=%s))", name);
1160 if (rc != TLDAP_SUCCESS) {
1161 DEBUG(10, ("Could not find just created alias %s: %s\n",
1162 name, tldap_errstr(talloc_tos(), state->ld, rc)));
1164 return NT_STATUS_LDAP(rc);
1167 if (talloc_array_length(alias) != 1) {
1168 DEBUG(10, ("Got %d alias, expected one\n",
1169 (int)talloc_array_length(alias)));
1171 return NT_STATUS_LDAP(rc);
1174 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1175 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1178 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1181 sid_peek_rid(&sid, rid);
1183 return NT_STATUS_OK;
1186 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1187 const struct dom_sid *sid)
1189 struct pdb_ads_state *state = talloc_get_type_abort(
1190 m->private_data, struct pdb_ads_state);
1191 struct tldap_context *ld;
1192 struct tldap_message **alias;
1193 char *sidstr, *dn = NULL;
1196 ld = pdb_ads_ld(state);
1198 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1201 sidstr = sid_binstring(talloc_tos(), sid);
1202 if (sidstr == NULL) {
1203 return NT_STATUS_NO_MEMORY;
1206 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1207 NULL, 0, 0, talloc_tos(), &alias,
1208 "(&(objectSid=%s)(objectclass=group)"
1209 "(|(grouptype=%d)(grouptype=%d)))",
1210 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1211 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1212 TALLOC_FREE(sidstr);
1213 if (rc != TLDAP_SUCCESS) {
1214 DEBUG(10, ("ldap_search failed: %s\n",
1215 tldap_errstr(talloc_tos(), state->ld, rc)));
1216 return NT_STATUS_LDAP(rc);
1218 if (talloc_array_length(alias) != 1) {
1219 DEBUG(10, ("Expected 1 alias, got %d\n",
1220 (int)talloc_array_length(alias)));
1221 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1223 if (!tldap_entry_dn(alias[0], &dn)) {
1224 DEBUG(10, ("Could not get DN for alias %s\n",
1225 sid_string_dbg(sid)));
1226 return NT_STATUS_INTERNAL_ERROR;
1229 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
1230 if (rc != TLDAP_SUCCESS) {
1231 DEBUG(10, ("ldap_delete failed: %s\n",
1232 tldap_errstr(talloc_tos(), state->ld, rc)));
1233 return NT_STATUS_LDAP(rc);
1236 return NT_STATUS_OK;
1239 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1240 const struct dom_sid *sid,
1241 struct acct_info *info)
1243 struct pdb_ads_state *state = talloc_get_type_abort(
1244 m->private_data, struct pdb_ads_state);
1245 struct tldap_context *ld;
1246 const char *attrs[3] = { "objectSid", "description",
1248 struct tldap_message **msg;
1251 struct tldap_mod *mods;
1255 ld = pdb_ads_ld(state);
1257 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1260 sidstr = sid_binstring(talloc_tos(), sid);
1261 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1263 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1264 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1265 &msg, "(&(objectSid=%s)(objectclass=group)"
1266 "(|(grouptype=%d)(grouptype=%d)))",
1267 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1268 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1269 TALLOC_FREE(sidstr);
1270 if (rc != TLDAP_SUCCESS) {
1271 DEBUG(10, ("ldap_search failed %s\n",
1272 tldap_errstr(talloc_tos(), state->ld, rc)));
1273 return NT_STATUS_LDAP(rc);
1275 switch talloc_array_length(msg) {
1277 return NT_STATUS_NO_SUCH_ALIAS;
1281 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1284 if (!tldap_entry_dn(msg[0], &dn)) {
1286 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1293 ok &= tldap_make_mod_fmt(
1294 msg[0], msg, &num_mods, &mods, "description",
1295 "%s", info->acct_desc);
1296 ok &= tldap_make_mod_fmt(
1297 msg[0], msg, &num_mods, &mods, "samAccountName",
1298 "%s", info->acct_name);
1301 return NT_STATUS_NO_MEMORY;
1303 if (num_mods == 0) {
1306 return NT_STATUS_OK;
1309 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1311 if (rc != TLDAP_SUCCESS) {
1312 DEBUG(10, ("ldap_modify failed: %s\n",
1313 tldap_errstr(talloc_tos(), state->ld, rc)));
1314 return NT_STATUS_LDAP(rc);
1316 return NT_STATUS_OK;
1319 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1320 const struct dom_sid *sid,
1321 TALLOC_CTX *mem_ctx, char **pdn)
1323 struct tldap_message **msg;
1327 sidstr = sid_binstring(talloc_tos(), sid);
1328 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1330 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1331 NULL, 0, 0, talloc_tos(), &msg,
1332 "(objectsid=%s)", sidstr);
1333 TALLOC_FREE(sidstr);
1334 if (rc != TLDAP_SUCCESS) {
1335 DEBUG(10, ("ldap_search failed %s\n",
1336 tldap_errstr(talloc_tos(), state->ld, rc)));
1337 return NT_STATUS_LDAP(rc);
1340 switch talloc_array_length(msg) {
1342 return NT_STATUS_NOT_FOUND;
1346 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1349 if (!tldap_entry_dn(msg[0], &dn)) {
1350 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1353 dn = talloc_strdup(mem_ctx, dn);
1355 return NT_STATUS_NO_MEMORY;
1360 return NT_STATUS_OK;
1363 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1364 const struct dom_sid *alias,
1365 const struct dom_sid *member,
1368 struct pdb_ads_state *state = talloc_get_type_abort(
1369 m->private_data, struct pdb_ads_state);
1370 struct tldap_context *ld;
1371 TALLOC_CTX *frame = talloc_stackframe();
1372 struct tldap_mod *mods;
1374 char *aliasdn, *memberdn;
1377 ld = pdb_ads_ld(state);
1379 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1382 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1383 if (!NT_STATUS_IS_OK(status)) {
1384 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1385 sid_string_dbg(alias), nt_errstr(status)));
1387 return NT_STATUS_NO_SUCH_ALIAS;
1389 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1390 if (!NT_STATUS_IS_OK(status)) {
1391 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1392 sid_string_dbg(member), nt_errstr(status)));
1399 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1400 "member", memberdn)) {
1402 return NT_STATUS_NO_MEMORY;
1405 rc = tldap_modify(ld, aliasdn, 1, mods, NULL, 0, NULL, 0);
1407 if (rc != TLDAP_SUCCESS) {
1408 DEBUG(10, ("ldap_modify failed: %s\n",
1409 tldap_errstr(talloc_tos(), state->ld, rc)));
1410 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1411 return NT_STATUS_MEMBER_IN_ALIAS;
1413 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1414 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1416 return NT_STATUS_LDAP(rc);
1419 return NT_STATUS_OK;
1422 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1423 const struct dom_sid *alias,
1424 const struct dom_sid *member)
1426 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1429 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1430 const struct dom_sid *alias,
1431 const struct dom_sid *member)
1433 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1436 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
1437 struct dom_sid *psid)
1439 const char *attrs[1] = { "objectSid" };
1440 struct tldap_message **msg;
1446 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1447 dnblob->data, dnblob->length, &dn, &len,
1451 rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
1452 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1453 &msg, "(objectclass=*)");
1455 if (talloc_array_length(msg) != 1) {
1456 DEBUG(10, ("Got %d objects, expected one\n",
1457 (int)talloc_array_length(msg)));
1462 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1467 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1468 const struct dom_sid *alias,
1469 TALLOC_CTX *mem_ctx,
1470 struct dom_sid **pmembers,
1471 size_t *pnum_members)
1473 struct pdb_ads_state *state = talloc_get_type_abort(
1474 m->private_data, struct pdb_ads_state);
1475 const char *attrs[1] = { "member" };
1477 struct tldap_message **msg;
1478 int i, rc, num_members;
1480 struct dom_sid *members;
1482 sidstr = sid_binstring(talloc_tos(), alias);
1483 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1485 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1486 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1487 &msg, "(objectsid=%s)", sidstr);
1488 TALLOC_FREE(sidstr);
1489 if (rc != TLDAP_SUCCESS) {
1490 DEBUG(10, ("ldap_search failed %s\n",
1491 tldap_errstr(talloc_tos(), state->ld, rc)));
1492 return NT_STATUS_LDAP(rc);
1494 switch talloc_array_length(msg) {
1496 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1501 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1505 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1506 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1509 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1510 if (members == NULL) {
1511 return NT_STATUS_NO_MEMORY;
1514 for (i=0; i<num_members; i++) {
1515 if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
1516 TALLOC_FREE(members);
1517 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1521 *pmembers = members;
1522 *pnum_members = num_members;
1523 return NT_STATUS_OK;
1526 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1527 TALLOC_CTX *mem_ctx,
1528 const struct dom_sid *domain_sid,
1529 const struct dom_sid *members,
1531 uint32_t **palias_rids,
1532 size_t *pnum_alias_rids)
1534 struct pdb_ads_state *state = talloc_get_type_abort(
1535 m->private_data, struct pdb_ads_state);
1536 const char *attrs[1] = { "objectSid" };
1537 struct tldap_message **msg = NULL;
1538 uint32_t *alias_rids = NULL;
1539 size_t num_alias_rids = 0;
1541 bool got_members = false;
1546 * TODO: Get the filter right so that we only get the aliases from
1547 * either the SAM or BUILTIN
1550 filter = talloc_asprintf(talloc_tos(),
1551 "(&(|(grouptype=%d)(grouptype=%d))"
1552 "(objectclass=group)(|",
1553 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1554 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1555 if (filter == NULL) {
1556 return NT_STATUS_NO_MEMORY;
1559 for (i=0; i<num_members; i++) {
1562 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1563 if (!NT_STATUS_IS_OK(status)) {
1564 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1565 sid_string_dbg(&members[i]),
1566 nt_errstr(status)));
1569 filter = talloc_asprintf_append_buffer(
1570 filter, "(member=%s)", dn);
1572 if (filter == NULL) {
1573 return NT_STATUS_NO_MEMORY;
1582 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1583 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1584 &msg, "%s))", filter);
1585 TALLOC_FREE(filter);
1586 if (rc != TLDAP_SUCCESS) {
1587 DEBUG(10, ("tldap_search failed %s\n",
1588 tldap_errstr(talloc_tos(), state->ld, rc)));
1589 return NT_STATUS_LDAP(rc);
1592 count = talloc_array_length(msg);
1597 alias_rids = talloc_array(mem_ctx, uint32_t, count);
1598 if (alias_rids == NULL) {
1600 return NT_STATUS_NO_MEMORY;
1603 for (i=0; i<count; i++) {
1606 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1607 DEBUG(10, ("Could not pull SID for member %d\n", i));
1610 if (sid_peek_check_rid(domain_sid, &sid,
1611 &alias_rids[num_alias_rids])) {
1612 num_alias_rids += 1;
1617 *palias_rids = alias_rids;
1618 *pnum_alias_rids = 0;
1619 return NT_STATUS_OK;
1622 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1623 const struct dom_sid *domain_sid,
1627 enum lsa_SidType *lsa_attrs)
1629 struct pdb_ads_state *state = talloc_get_type_abort(
1630 m->private_data, struct pdb_ads_state);
1631 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1634 if (num_rids == 0) {
1635 return NT_STATUS_NONE_MAPPED;
1640 for (i=0; i<num_rids; i++) {
1642 struct tldap_message **msg;
1647 lsa_attrs[i] = SID_NAME_UNKNOWN;
1649 sid_compose(&sid, domain_sid, rids[i]);
1651 sidstr = sid_binstring(talloc_tos(), &sid);
1652 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1654 rc = pdb_ads_search_fmt(state, state->domaindn,
1655 TLDAP_SCOPE_SUB, attrs,
1656 ARRAY_SIZE(attrs), 0, talloc_tos(),
1657 &msg, "(objectsid=%s)", sidstr);
1658 TALLOC_FREE(sidstr);
1659 if (rc != TLDAP_SUCCESS) {
1660 DEBUG(10, ("ldap_search failed %s\n",
1661 tldap_errstr(talloc_tos(), state->ld, rc)));
1665 switch talloc_array_length(msg) {
1667 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1672 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1675 names[i] = tldap_talloc_single_attribute(
1676 msg[0], "samAccountName", talloc_tos());
1677 if (names[i] == NULL) {
1678 DEBUG(10, ("no samAccountName\n"));
1681 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1682 DEBUG(10, ("no samAccountType"));
1685 lsa_attrs[i] = ds_atype_map(attr);
1689 if (num_mapped == 0) {
1690 return NT_STATUS_NONE_MAPPED;
1692 if (num_mapped < num_rids) {
1693 return STATUS_SOME_UNMAPPED;
1695 return NT_STATUS_OK;
1698 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1699 const struct dom_sid *domain_sid,
1701 const char **pp_names,
1703 enum lsa_SidType *attrs)
1705 return NT_STATUS_NOT_IMPLEMENTED;
1708 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1709 enum pdb_policy_type type,
1712 return account_policy_get(type, value)
1713 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1716 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1717 enum pdb_policy_type type,
1720 return account_policy_set(type, value)
1721 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1724 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1727 return NT_STATUS_NOT_IMPLEMENTED;
1730 struct pdb_ads_search_state {
1731 uint32_t acct_flags;
1732 struct samr_displayentry *entries;
1733 uint32_t num_entries;
1738 static bool pdb_ads_next_entry(struct pdb_search *search,
1739 struct samr_displayentry *entry)
1741 struct pdb_ads_search_state *state = talloc_get_type_abort(
1742 search->private_data, struct pdb_ads_search_state);
1744 if (state->current == state->num_entries) {
1748 entry->idx = state->entries[state->current].idx;
1749 entry->rid = state->entries[state->current].rid;
1750 entry->acct_flags = state->entries[state->current].acct_flags;
1752 entry->account_name = talloc_strdup(
1753 search, state->entries[state->current].account_name);
1754 entry->fullname = talloc_strdup(
1755 search, state->entries[state->current].fullname);
1756 entry->description = talloc_strdup(
1757 search, state->entries[state->current].description);
1759 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1760 || (entry->description == NULL)) {
1761 DEBUG(0, ("talloc_strdup failed\n"));
1765 state->current += 1;
1769 static void pdb_ads_search_end(struct pdb_search *search)
1771 struct pdb_ads_search_state *state = talloc_get_type_abort(
1772 search->private_data, struct pdb_ads_search_state);
1776 static bool pdb_ads_search_filter(struct pdb_methods *m,
1777 struct pdb_search *search,
1779 struct pdb_ads_search_state **pstate)
1781 struct pdb_ads_state *state = talloc_get_type_abort(
1782 m->private_data, struct pdb_ads_state);
1783 struct pdb_ads_search_state *sstate;
1784 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1785 "userAccountControl", "description" };
1786 struct tldap_message **users;
1787 int i, rc, num_users;
1789 sstate = talloc_zero(search, struct pdb_ads_search_state);
1790 if (sstate == NULL) {
1794 rc = pdb_ads_search_fmt(
1795 state, state->domaindn, TLDAP_SCOPE_SUB,
1796 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1798 if (rc != TLDAP_SUCCESS) {
1799 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1800 tldap_errstr(talloc_tos(), state->ld, rc)));
1804 num_users = talloc_array_length(users);
1806 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1808 if (sstate->entries == NULL) {
1809 DEBUG(10, ("talloc failed\n"));
1813 sstate->num_entries = 0;
1815 for (i=0; i<num_users; i++) {
1816 struct samr_displayentry *e;
1819 e = &sstate->entries[sstate->num_entries];
1821 e->idx = sstate->num_entries;
1822 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1823 DEBUG(10, ("Could not pull sid\n"));
1826 sid_peek_rid(&sid, &e->rid);
1827 e->acct_flags = ACB_NORMAL;
1828 e->account_name = tldap_talloc_single_attribute(
1829 users[i], "samAccountName", sstate->entries);
1830 if (e->account_name == NULL) {
1833 e->fullname = tldap_talloc_single_attribute(
1834 users[i], "displayName", sstate->entries);
1835 if (e->fullname == NULL) {
1838 e->description = tldap_talloc_single_attribute(
1839 users[i], "description", sstate->entries);
1840 if (e->description == NULL) {
1841 e->description = "";
1844 sstate->num_entries += 1;
1845 if (sstate->num_entries >= num_users) {
1850 search->private_data = sstate;
1851 search->next_entry = pdb_ads_next_entry;
1852 search->search_end = pdb_ads_search_end;
1857 static bool pdb_ads_search_users(struct pdb_methods *m,
1858 struct pdb_search *search,
1861 struct pdb_ads_search_state *sstate;
1864 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1868 sstate->acct_flags = acct_flags;
1872 static bool pdb_ads_search_groups(struct pdb_methods *m,
1873 struct pdb_search *search)
1875 struct pdb_ads_search_state *sstate;
1879 filter = talloc_asprintf(talloc_tos(),
1880 "(&(grouptype=%d)(objectclass=group))",
1881 GTYPE_SECURITY_GLOBAL_GROUP);
1882 if (filter == NULL) {
1885 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1886 TALLOC_FREE(filter);
1890 sstate->acct_flags = 0;
1894 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1895 struct pdb_search *search,
1896 const struct dom_sid *sid)
1898 struct pdb_ads_search_state *sstate;
1902 filter = talloc_asprintf(
1903 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1904 sid_check_is_builtin(sid)
1905 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1906 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1908 if (filter == NULL) {
1911 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1912 TALLOC_FREE(filter);
1916 sstate->acct_flags = 0;
1920 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1921 struct dom_sid *sid)
1923 struct pdb_ads_state *state = talloc_get_type_abort(
1924 m->private_data, struct pdb_ads_state);
1925 sid_compose(sid, &state->domainsid, uid);
1929 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1930 struct dom_sid *sid)
1932 struct pdb_ads_state *state = talloc_get_type_abort(
1933 m->private_data, struct pdb_ads_state);
1934 sid_compose(sid, &state->domainsid, gid);
1938 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
1939 union unid_t *id, enum lsa_SidType *type)
1941 struct pdb_ads_state *state = talloc_get_type_abort(
1942 m->private_data, struct pdb_ads_state);
1943 struct tldap_message **msg;
1949 * This is a big, big hack: Just hard-code the rid as uid/gid.
1952 sid_peek_rid(sid, &rid);
1954 sidstr = sid_binstring(talloc_tos(), sid);
1955 if (sidstr == NULL) {
1959 rc = pdb_ads_search_fmt(
1960 state, state->domaindn, TLDAP_SCOPE_SUB,
1961 NULL, 0, 0, talloc_tos(), &msg,
1962 "(&(objectsid=%s)(objectclass=user))", sidstr);
1963 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1965 *type = SID_NAME_USER;
1966 TALLOC_FREE(sidstr);
1970 rc = pdb_ads_search_fmt(
1971 state, state->domaindn, TLDAP_SCOPE_SUB,
1972 NULL, 0, 0, talloc_tos(), &msg,
1973 "(&(objectsid=%s)(objectclass=group))", sidstr);
1974 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1976 *type = SID_NAME_DOM_GRP;
1977 TALLOC_FREE(sidstr);
1981 TALLOC_FREE(sidstr);
1985 static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
1987 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
1990 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1995 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1996 const char *domain, char** pwd,
1997 struct dom_sid *sid,
1998 time_t *pass_last_set_time)
2003 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
2004 const char* domain, const char* pwd,
2005 const struct dom_sid *sid)
2010 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
2016 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
2017 TALLOC_CTX *mem_ctx,
2018 uint32 *num_domains,
2019 struct trustdom_info ***domains)
2023 return NT_STATUS_OK;
2026 static void pdb_ads_init_methods(struct pdb_methods *m)
2029 m->get_domain_info = pdb_ads_get_domain_info;
2030 m->getsampwnam = pdb_ads_getsampwnam;
2031 m->getsampwsid = pdb_ads_getsampwsid;
2032 m->create_user = pdb_ads_create_user;
2033 m->delete_user = pdb_ads_delete_user;
2034 m->add_sam_account = pdb_ads_add_sam_account;
2035 m->update_sam_account = pdb_ads_update_sam_account;
2036 m->delete_sam_account = pdb_ads_delete_sam_account;
2037 m->rename_sam_account = pdb_ads_rename_sam_account;
2038 m->update_login_attempts = pdb_ads_update_login_attempts;
2039 m->getgrsid = pdb_ads_getgrsid;
2040 m->getgrgid = pdb_ads_getgrgid;
2041 m->getgrnam = pdb_ads_getgrnam;
2042 m->create_dom_group = pdb_ads_create_dom_group;
2043 m->delete_dom_group = pdb_ads_delete_dom_group;
2044 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
2045 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
2046 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
2047 m->enum_group_mapping = pdb_ads_enum_group_mapping;
2048 m->enum_group_members = pdb_ads_enum_group_members;
2049 m->enum_group_memberships = pdb_ads_enum_group_memberships;
2050 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
2051 m->add_groupmem = pdb_ads_add_groupmem;
2052 m->del_groupmem = pdb_ads_del_groupmem;
2053 m->create_alias = pdb_ads_create_alias;
2054 m->delete_alias = pdb_ads_delete_alias;
2055 m->get_aliasinfo = pdb_default_get_aliasinfo;
2056 m->set_aliasinfo = pdb_ads_set_aliasinfo;
2057 m->add_aliasmem = pdb_ads_add_aliasmem;
2058 m->del_aliasmem = pdb_ads_del_aliasmem;
2059 m->enum_aliasmem = pdb_ads_enum_aliasmem;
2060 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
2061 m->lookup_rids = pdb_ads_lookup_rids;
2062 m->lookup_names = pdb_ads_lookup_names;
2063 m->get_account_policy = pdb_ads_get_account_policy;
2064 m->set_account_policy = pdb_ads_set_account_policy;
2065 m->get_seq_num = pdb_ads_get_seq_num;
2066 m->search_users = pdb_ads_search_users;
2067 m->search_groups = pdb_ads_search_groups;
2068 m->search_aliases = pdb_ads_search_aliases;
2069 m->uid_to_sid = pdb_ads_uid_to_sid;
2070 m->gid_to_sid = pdb_ads_gid_to_sid;
2071 m->sid_to_id = pdb_ads_sid_to_id;
2072 m->capabilities = pdb_ads_capabilities;
2073 m->new_rid = pdb_ads_new_rid;
2074 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2075 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2076 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2077 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2080 static void free_private_data(void **vp)
2082 struct pdb_ads_state *state = talloc_get_type_abort(
2083 *vp, struct pdb_ads_state);
2085 TALLOC_FREE(state->ld);
2090 this is used to catch debug messages from events
2092 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2093 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
2095 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2096 const char *fmt, va_list ap)
2098 int samba_level = -1;
2101 case TLDAP_DEBUG_FATAL:
2104 case TLDAP_DEBUG_ERROR:
2107 case TLDAP_DEBUG_WARNING:
2110 case TLDAP_DEBUG_TRACE:
2115 if (vasprintf(&s, fmt, ap) == -1) {
2118 DEBUG(samba_level, ("tldap: %s", s));
2122 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2127 if (tldap_connection_ok(state->ld)) {
2130 TALLOC_FREE(state->ld);
2132 status = open_socket_out(
2133 (struct sockaddr_storage *)(void *)&state->socket_address,
2135 if (!NT_STATUS_IS_OK(status)) {
2136 DEBUG(10, ("Could not connect to %s: %s\n",
2137 state->socket_address.sun_path, nt_errstr(status)));
2141 set_blocking(fd, false);
2143 state->ld = tldap_context_create(state, fd);
2144 if (state->ld == NULL) {
2148 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2153 int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2154 int scope, const char *attrs[], int num_attrs,
2156 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2157 const char *fmt, ...)
2159 struct tldap_context *ld;
2163 ld = pdb_ads_ld(state);
2165 return TLDAP_SERVER_DOWN;
2169 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2170 mem_ctx, res, fmt, ap);
2173 if (ret != TLDAP_SERVER_DOWN) {
2178 ld = pdb_ads_ld(state);
2180 return TLDAP_SERVER_DOWN;
2184 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2185 mem_ctx, res, fmt, ap);
2190 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2191 const char *location)
2193 const char *domain_attrs[2] = { "objectSid", "objectGUID" };
2194 const char *ncname_attrs[1] = { "netbiosname" };
2195 struct tldap_context *ld;
2196 struct tldap_message *rootdse, **domain, **ncname;
2197 TALLOC_CTX *frame = talloc_stackframe();
2202 ZERO_STRUCT(state->socket_address);
2203 state->socket_address.sun_family = AF_UNIX;
2204 strncpy(state->socket_address.sun_path, location,
2205 sizeof(state->socket_address.sun_path) - 1);
2207 ld = pdb_ads_ld(state);
2209 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2213 rc = tldap_fetch_rootdse(ld);
2214 if (rc != TLDAP_SUCCESS) {
2215 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2216 tldap_errstr(talloc_tos(), state->ld, rc)));
2217 status = NT_STATUS_LDAP(rc);
2220 rootdse = tldap_rootdse(state->ld);
2222 state->domaindn = tldap_talloc_single_attribute(
2223 rootdse, "defaultNamingContext", state);
2224 if (state->domaindn == NULL) {
2225 DEBUG(10, ("Could not get defaultNamingContext\n"));
2226 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2229 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2231 state->configdn = tldap_talloc_single_attribute(
2232 rootdse, "configurationNamingContext", state);
2233 if (state->domaindn == NULL) {
2234 DEBUG(10, ("Could not get configurationNamingContext\n"));
2235 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2238 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2241 * Figure out our domain's SID
2243 rc = pdb_ads_search_fmt(
2244 state, state->domaindn, TLDAP_SCOPE_BASE,
2245 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2246 talloc_tos(), &domain, "(objectclass=*)");
2247 if (rc != TLDAP_SUCCESS) {
2248 DEBUG(10, ("Could not retrieve domain: %s\n",
2249 tldap_errstr(talloc_tos(), state->ld, rc)));
2250 status = NT_STATUS_LDAP(rc);
2254 num_domains = talloc_array_length(domain);
2255 if (num_domains != 1) {
2256 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2257 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2260 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2261 DEBUG(10, ("Could not retrieve domain SID\n"));
2262 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2265 if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) {
2266 DEBUG(10, ("Could not retrieve domain GUID\n"));
2267 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2270 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2273 * Figure out our domain's short name
2275 rc = pdb_ads_search_fmt(
2276 state, state->configdn, TLDAP_SCOPE_SUB,
2277 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2278 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2279 if (rc != TLDAP_SUCCESS) {
2280 DEBUG(10, ("Could not retrieve ncname: %s\n",
2281 tldap_errstr(talloc_tos(), state->ld, rc)));
2282 status = NT_STATUS_LDAP(rc);
2285 if (talloc_array_length(ncname) != 1) {
2286 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2290 state->netbiosname = tldap_talloc_single_attribute(
2291 ncname[0], "netbiosname", state);
2292 if (state->netbiosname == NULL) {
2293 DEBUG(10, ("Could not get netbiosname\n"));
2294 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2297 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2299 if (!strequal(lp_workgroup(), state->netbiosname)) {
2300 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2301 state->netbiosname, lp_workgroup()));
2302 status = NT_STATUS_NO_SUCH_DOMAIN;
2306 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2308 status = NT_STATUS_OK;
2314 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2315 const char *location)
2317 struct pdb_methods *m;
2318 struct pdb_ads_state *state;
2322 m = talloc(talloc_autofree_context(), struct pdb_methods);
2324 return NT_STATUS_NO_MEMORY;
2326 state = talloc_zero(m, struct pdb_ads_state);
2327 if (state == NULL) {
2330 m->private_data = state;
2331 m->free_private_data = free_private_data;
2332 pdb_ads_init_methods(m);
2334 if (location == NULL) {
2335 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2339 if (location == NULL) {
2343 status = pdb_ads_connect(state, location);
2344 if (!NT_STATUS_IS_OK(status)) {
2345 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2350 return NT_STATUS_OK;
2352 status = NT_STATUS_NO_MEMORY;
2358 NTSTATUS pdb_ads_init(void);
2359 NTSTATUS pdb_ads_init(void)
2361 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",