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 struct pdb_ads_state {
23 struct sockaddr_un socket_address;
24 struct tldap_context *ld;
25 struct dom_sid domainsid;
26 struct GUID domainguid;
32 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
33 struct samu *sam_acct,
35 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
37 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
38 struct dom_sid *psid);
39 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
40 const struct dom_sid *sid,
41 TALLOC_CTX *mem_ctx, char **pdn);
42 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state);
43 static int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
44 int scope, const char *attrs[], int num_attrs,
46 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
47 const char *fmt, ...);
49 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
54 if (!tldap_pull_uint64(msg, attr, &tmp)) {
57 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
61 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
64 sid_peek_rid(sid, &rid);
68 struct pdb_ads_samu_private {
70 struct tldap_message *ldapmsg;
73 static char *pdb_ads_domaindn2dns(TALLOC_CTX *mem_ctx, char *dn)
77 result = talloc_string_sub2(mem_ctx, dn, "DC=", "", false, false,
83 while ((p = strchr_m(result, ',')) != NULL) {
90 static struct pdb_domain_info *pdb_ads_get_domain_info(
91 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
93 struct pdb_ads_state *state = talloc_get_type_abort(
94 m->private_data, struct pdb_ads_state);
95 struct pdb_domain_info *info;
96 struct tldap_message *rootdse;
99 info = talloc(mem_ctx, struct pdb_domain_info);
103 info->name = talloc_strdup(info, state->netbiosname);
104 if (info->name == NULL) {
107 info->dns_domain = pdb_ads_domaindn2dns(info, state->domaindn);
108 if (info->dns_domain == NULL) {
112 rootdse = tldap_rootdse(state->ld);
113 tmp = tldap_talloc_single_attribute(rootdse, "rootDomainNamingContext",
118 info->dns_forest = pdb_ads_domaindn2dns(info, tmp);
120 if (info->dns_forest == NULL) {
123 info->sid = state->domainsid;
124 info->guid = state->domainguid;
132 static struct samu *pdb_ads_init_guest(TALLOC_CTX *mem_ctx,
133 struct pdb_methods *m)
135 struct pdb_ads_state *state = talloc_get_type_abort(
136 m->private_data, struct pdb_ads_state);
137 struct dom_sid guest_sid;
141 sid_compose(&guest_sid, &state->domainsid, DOMAIN_USER_RID_GUEST);
143 guest = samu_new(mem_ctx);
148 status = pdb_ads_getsampwsid(m, guest, &guest_sid);
149 if (!NT_STATUS_IS_OK(status)) {
150 DEBUG(10, ("Could not init guest account: %s\n",
158 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
159 struct pdb_methods *m, struct samu *sam)
161 struct pdb_ads_samu_private *result;
164 result = (struct pdb_ads_samu_private *)
165 pdb_get_backend_private_data(sam, m);
167 if (result != NULL) {
168 return talloc_get_type_abort(
169 result, struct pdb_ads_samu_private);
173 * This is now a weirdness of the passdb API. For the guest user we
174 * are not asked first.
176 sid_peek_rid(pdb_get_user_sid(sam), &rid);
178 if (rid == DOMAIN_USER_RID_GUEST) {
179 struct samu *guest = pdb_ads_init_guest(talloc_tos(), m);
184 result = talloc_get_type_abort(
185 pdb_get_backend_private_data(guest, m),
186 struct pdb_ads_samu_private);
187 pdb_set_backend_private_data(
188 sam, talloc_move(sam, &result), NULL, m, PDB_SET);
190 return talloc_get_type_abort(
191 pdb_get_backend_private_data(sam, m),
192 struct pdb_ads_samu_private);
198 static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m,
200 struct tldap_message *entry)
202 struct pdb_ads_state *state = talloc_get_type_abort(
203 m->private_data, struct pdb_ads_state);
204 TALLOC_CTX *frame = talloc_stackframe();
205 struct pdb_ads_samu_private *priv;
206 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
213 priv = talloc(sam, struct pdb_ads_samu_private);
215 return NT_STATUS_NO_MEMORY;
217 if (!tldap_entry_dn(entry, &priv->dn)) {
219 return NT_STATUS_INTERNAL_DB_CORRUPTION;
222 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
224 DEBUG(10, ("no samAccountName\n"));
227 pdb_set_username(sam, str, PDB_SET);
229 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
230 pdb_set_logon_time(sam, tmp_time, PDB_SET);
232 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
233 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
235 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
236 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
238 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
239 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
242 str = tldap_talloc_single_attribute(entry, "displayName",
245 pdb_set_fullname(sam, str, PDB_SET);
248 str = tldap_talloc_single_attribute(entry, "homeDirectory",
251 pdb_set_homedir(sam, str, PDB_SET);
254 str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
256 pdb_set_dir_drive(sam, str, PDB_SET);
259 str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
261 pdb_set_logon_script(sam, str, PDB_SET);
264 str = tldap_talloc_single_attribute(entry, "profilePath",
267 pdb_set_profile_path(sam, str, PDB_SET);
270 str = tldap_talloc_single_attribute(entry, "profilePath",
273 pdb_set_profile_path(sam, str, PDB_SET);
276 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
277 DEBUG(10, ("Could not pull SID\n"));
280 pdb_set_user_sid(sam, &sid, PDB_SET);
282 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
283 DEBUG(10, ("Could not pull userAccountControl\n"));
286 pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET);
288 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
289 if (blob.length != NT_HASH_LEN) {
290 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
291 (int)blob.length, NT_HASH_LEN));
294 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
297 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
298 if (blob.length != LM_HASH_LEN) {
299 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
300 (int)blob.length, LM_HASH_LEN));
303 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
306 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
307 sid_compose(&sid, &state->domainsid, n);
308 pdb_set_group_sid(sam, &sid, PDB_SET);
312 priv->ldapmsg = talloc_move(priv, &entry);
313 pdb_set_backend_private_data(sam, priv, NULL, m, PDB_SET);
315 status = NT_STATUS_OK;
321 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
322 struct tldap_message *existing,
324 int *pnum_mods, struct tldap_mod **pmods,
330 /* TODO: All fields :-) */
332 ret &= tldap_make_mod_fmt(
333 existing, mem_ctx, pnum_mods, pmods, "displayName",
334 "%s", pdb_get_fullname(sam));
336 blob = data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN);
337 if (blob.data != NULL) {
338 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
339 "unicodePwd", 1, &blob);
342 blob = data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN);
343 if (blob.data != NULL) {
344 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
345 "dBCSPwd", 1, &blob);
348 ret &= tldap_make_mod_fmt(
349 existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
350 "%d", ads_acb2uf(pdb_get_acct_ctrl(sam)));
352 ret &= tldap_make_mod_fmt(
353 existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
354 "%s", pdb_get_homedir(sam));
356 ret &= tldap_make_mod_fmt(
357 existing, mem_ctx, pnum_mods, pmods, "homeDrive",
358 "%s", pdb_get_dir_drive(sam));
360 ret &= tldap_make_mod_fmt(
361 existing, mem_ctx, pnum_mods, pmods, "scriptPath",
362 "%s", pdb_get_logon_script(sam));
364 ret &= tldap_make_mod_fmt(
365 existing, mem_ctx, pnum_mods, pmods, "profilePath",
366 "%s", pdb_get_profile_path(sam));
371 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
372 struct pdb_ads_state *state,
373 struct samu *sam_acct,
376 const char * attrs[] = {
377 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
378 "sAMAccountName", "displayName", "homeDirectory",
379 "homeDrive", "scriptPath", "profilePath", "description",
380 "userWorkstations", "comment", "userParameters", "objectSid",
381 "primaryGroupID", "userAccountControl", "logonHours",
382 "badPwdCount", "logonCount", "countryCode", "codePage",
383 "unicodePwd", "dBCSPwd" };
384 struct tldap_message **users;
387 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
388 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
389 &users, "%s", filter);
390 if (rc != TLDAP_SUCCESS) {
391 DEBUG(10, ("ldap_search failed %s\n",
392 tldap_errstr(debug_ctx(), state->ld, rc)));
393 return NT_STATUS_LDAP(rc);
396 count = talloc_array_length(users);
398 DEBUG(10, ("Expected 1 user, got %d\n", count));
399 return NT_STATUS_INTERNAL_DB_CORRUPTION;
402 return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]);
405 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
406 struct samu *sam_acct,
407 const char *username)
409 struct pdb_ads_state *state = talloc_get_type_abort(
410 m->private_data, struct pdb_ads_state);
413 filter = talloc_asprintf(
414 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
416 NT_STATUS_HAVE_NO_MEMORY(filter);
418 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
421 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
422 struct samu *sam_acct,
425 struct pdb_ads_state *state = talloc_get_type_abort(
426 m->private_data, struct pdb_ads_state);
427 char *sidstr, *filter;
429 sidstr = sid_binstring(talloc_tos(), sid);
430 NT_STATUS_HAVE_NO_MEMORY(sidstr);
432 filter = talloc_asprintf(
433 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
435 NT_STATUS_HAVE_NO_MEMORY(filter);
437 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
440 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
442 const char *name, uint32 acct_flags,
445 struct pdb_ads_state *state = talloc_get_type_abort(
446 m->private_data, struct pdb_ads_state);
447 struct tldap_context *ld;
448 const char *attrs[1] = { "objectSid" };
449 struct tldap_mod *mods = NULL;
451 struct tldap_message **user;
457 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
460 return NT_STATUS_NO_MEMORY;
463 ld = pdb_ads_ld(state);
465 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
468 /* TODO: Create machines etc */
471 ok &= tldap_make_mod_fmt(
472 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
473 ok &= tldap_make_mod_fmt(
474 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
477 return NT_STATUS_NO_MEMORY;
481 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
482 if (rc != TLDAP_SUCCESS) {
483 DEBUG(10, ("ldap_add failed %s\n",
484 tldap_errstr(debug_ctx(), ld, rc)));
486 return NT_STATUS_LDAP(rc);
489 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
490 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
492 "(&(objectclass=user)(samaccountname=%s))",
494 if (rc != TLDAP_SUCCESS) {
495 DEBUG(10, ("Could not find just created user %s: %s\n",
496 name, tldap_errstr(debug_ctx(), state->ld, rc)));
498 return NT_STATUS_LDAP(rc);
501 if (talloc_array_length(user) != 1) {
502 DEBUG(10, ("Got %d users, expected one\n",
503 (int)talloc_array_length(user)));
505 return NT_STATUS_LDAP(rc);
508 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
509 DEBUG(10, ("Could not fetch objectSid from user %s\n",
512 return NT_STATUS_INTERNAL_DB_CORRUPTION;
515 sid_peek_rid(&sid, rid);
520 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
524 struct pdb_ads_state *state = talloc_get_type_abort(
525 m->private_data, struct pdb_ads_state);
527 struct tldap_context *ld;
531 ld = pdb_ads_ld(state);
533 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
536 status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
538 if (!NT_STATUS_IS_OK(status)) {
542 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
544 if (rc != TLDAP_SUCCESS) {
545 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
546 tldap_errstr(debug_ctx(), ld, rc)));
547 return NT_STATUS_LDAP(rc);
552 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
553 struct samu *sampass)
555 return NT_STATUS_NOT_IMPLEMENTED;
558 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
561 struct pdb_ads_state *state = talloc_get_type_abort(
562 m->private_data, struct pdb_ads_state);
563 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
564 struct tldap_context *ld;
565 struct tldap_mod *mods = NULL;
566 int rc, num_mods = 0;
568 ld = pdb_ads_ld(state);
570 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
573 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
574 &num_mods, &mods, sam)) {
575 return NT_STATUS_NO_MEMORY;
579 /* Nothing to do, just return success */
583 rc = tldap_modify(ld, priv->dn, num_mods, mods, NULL, 0,
586 if (rc != TLDAP_SUCCESS) {
587 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
588 tldap_errstr(debug_ctx(), ld, rc)));
589 return NT_STATUS_LDAP(rc);
595 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
596 struct samu *username)
598 return NT_STATUS_NOT_IMPLEMENTED;
601 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
602 struct samu *oldname,
605 return NT_STATUS_NOT_IMPLEMENTED;
608 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
609 struct samu *sam_acct,
612 return NT_STATUS_NOT_IMPLEMENTED;
615 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
618 struct pdb_ads_state *state = talloc_get_type_abort(
619 m->private_data, struct pdb_ads_state);
620 const char *attrs[4] = { "objectSid", "description", "samAccountName",
623 struct tldap_message **group;
627 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
628 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
629 &group, "%s", filter);
630 if (rc != TLDAP_SUCCESS) {
631 DEBUG(10, ("ldap_search failed %s\n",
632 tldap_errstr(debug_ctx(), state->ld, rc)));
633 return NT_STATUS_LDAP(rc);
635 if (talloc_array_length(group) != 1) {
636 DEBUG(10, ("Expected 1 user, got %d\n",
637 (int)talloc_array_length(group)));
638 return NT_STATUS_INTERNAL_DB_CORRUPTION;
641 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
642 return NT_STATUS_INTERNAL_DB_CORRUPTION;
644 map->gid = pdb_ads_sid2gid(&map->sid);
646 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
647 return NT_STATUS_INTERNAL_DB_CORRUPTION;
650 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
651 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
652 map->sid_name_use = SID_NAME_ALIAS;
654 case GTYPE_SECURITY_GLOBAL_GROUP:
655 map->sid_name_use = SID_NAME_DOM_GRP;
658 return NT_STATUS_INTERNAL_DB_CORRUPTION;
661 str = tldap_talloc_single_attribute(group[0], "samAccountName",
664 return NT_STATUS_INTERNAL_DB_CORRUPTION;
666 fstrcpy(map->nt_name, str);
669 str = tldap_talloc_single_attribute(group[0], "description",
672 fstrcpy(map->comment, str);
675 map->comment[0] = '\0';
682 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
688 filter = talloc_asprintf(talloc_tos(),
689 "(&(objectsid=%s)(objectclass=group))",
690 sid_string_talloc(talloc_tos(), &sid));
691 if (filter == NULL) {
692 return NT_STATUS_NO_MEMORY;
695 status = pdb_ads_getgrfilter(m, map, filter);
700 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
704 pdb_ads_gid_to_sid(m, gid, &sid);
705 return pdb_ads_getgrsid(m, map, sid);
708 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
714 filter = talloc_asprintf(talloc_tos(),
715 "(&(samaccountname=%s)(objectclass=group))",
717 if (filter == NULL) {
718 return NT_STATUS_NO_MEMORY;
721 status = pdb_ads_getgrfilter(m, map, filter);
726 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
727 TALLOC_CTX *mem_ctx, const char *name,
730 TALLOC_CTX *frame = talloc_stackframe();
731 struct pdb_ads_state *state = talloc_get_type_abort(
732 m->private_data, struct pdb_ads_state);
733 struct tldap_context *ld;
734 const char *attrs[1] = { "objectSid" };
736 struct tldap_mod *mods = NULL;
737 struct tldap_message **alias;
743 ld = pdb_ads_ld(state);
745 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
748 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
752 return NT_STATUS_NO_MEMORY;
755 ok &= tldap_make_mod_fmt(
756 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
758 ok &= tldap_make_mod_fmt(
759 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
760 ok &= tldap_make_mod_fmt(
761 NULL, talloc_tos(), &num_mods, &mods, "groupType",
762 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
766 return NT_STATUS_NO_MEMORY;
769 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
770 if (rc != TLDAP_SUCCESS) {
771 DEBUG(10, ("ldap_add failed %s\n",
772 tldap_errstr(debug_ctx(), state->ld, rc)));
774 return NT_STATUS_LDAP(rc);
777 rc = pdb_ads_search_fmt(
778 state, state->domaindn, TLDAP_SCOPE_SUB,
779 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
780 "(&(objectclass=group)(samaccountname=%s))", name);
781 if (rc != TLDAP_SUCCESS) {
782 DEBUG(10, ("Could not find just created alias %s: %s\n",
783 name, tldap_errstr(debug_ctx(), state->ld, rc)));
785 return NT_STATUS_LDAP(rc);
788 if (talloc_array_length(alias) != 1) {
789 DEBUG(10, ("Got %d alias, expected one\n",
790 (int)talloc_array_length(alias)));
792 return NT_STATUS_LDAP(rc);
795 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
796 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
799 return NT_STATUS_INTERNAL_DB_CORRUPTION;
802 sid_peek_rid(&sid, rid);
807 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
808 TALLOC_CTX *mem_ctx, uint32 rid)
810 struct pdb_ads_state *state = talloc_get_type_abort(
811 m->private_data, struct pdb_ads_state);
812 struct tldap_context *ld;
815 struct tldap_message **msg;
819 sid_compose(&sid, &state->domainsid, rid);
821 sidstr = sid_binstring(talloc_tos(), &sid);
822 NT_STATUS_HAVE_NO_MEMORY(sidstr);
824 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
825 NULL, 0, 0, talloc_tos(), &msg,
826 ("(&(objectSid=%s)(objectClass=group))"),
829 if (rc != TLDAP_SUCCESS) {
830 DEBUG(10, ("ldap_search failed %s\n",
831 tldap_errstr(debug_ctx(), state->ld, rc)));
832 return NT_STATUS_LDAP(rc);
835 switch talloc_array_length(msg) {
837 return NT_STATUS_NO_SUCH_GROUP;
841 return NT_STATUS_INTERNAL_DB_CORRUPTION;
844 if (!tldap_entry_dn(msg[0], &dn)) {
846 return NT_STATUS_INTERNAL_DB_CORRUPTION;
849 ld = pdb_ads_ld(state);
852 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
855 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
857 if (rc != TLDAP_SUCCESS) {
858 DEBUG(10, ("ldap_delete failed: %s\n",
859 tldap_errstr(debug_ctx(), state->ld, rc)));
860 return NT_STATUS_LDAP(rc);
866 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
869 return NT_STATUS_NOT_IMPLEMENTED;
872 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
875 return NT_STATUS_NOT_IMPLEMENTED;
878 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
881 return NT_STATUS_NOT_IMPLEMENTED;
884 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
886 enum lsa_SidType sid_name_use,
888 size_t *p_num_entries,
891 return NT_STATUS_NOT_IMPLEMENTED;
894 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
896 const DOM_SID *group,
898 size_t *pnum_members)
900 struct pdb_ads_state *state = talloc_get_type_abort(
901 m->private_data, struct pdb_ads_state);
902 const char *attrs[1] = { "member" };
904 struct tldap_message **msg;
905 int i, rc, num_members;
909 sidstr = sid_binstring(talloc_tos(), group);
910 NT_STATUS_HAVE_NO_MEMORY(sidstr);
912 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
913 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
914 &msg, "(objectsid=%s)", sidstr);
916 if (rc != TLDAP_SUCCESS) {
917 DEBUG(10, ("ldap_search failed %s\n",
918 tldap_errstr(debug_ctx(), state->ld, rc)));
919 return NT_STATUS_LDAP(rc);
921 switch talloc_array_length(msg) {
923 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
928 return NT_STATUS_INTERNAL_DB_CORRUPTION;
932 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
933 return NT_STATUS_INTERNAL_DB_CORRUPTION;
936 members = talloc_array(mem_ctx, uint32_t, num_members);
937 if (members == NULL) {
938 return NT_STATUS_NO_MEMORY;
941 for (i=0; i<num_members; i++) {
943 if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
944 || !sid_peek_rid(&sid, &members[i])) {
945 TALLOC_FREE(members);
946 return NT_STATUS_INTERNAL_DB_CORRUPTION;
951 *pnum_members = num_members;
955 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
960 size_t *p_num_groups)
962 struct pdb_ads_state *state = talloc_get_type_abort(
963 m->private_data, struct pdb_ads_state);
964 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
966 const char *attrs[1] = { "objectSid" };
967 struct tldap_message **groups;
970 struct dom_sid *group_sids;
973 rc = pdb_ads_search_fmt(
974 state, state->domaindn, TLDAP_SCOPE_SUB,
975 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
976 "(&(member=%s)(grouptype=%d)(objectclass=group))",
977 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
978 if (rc != TLDAP_SUCCESS) {
979 DEBUG(10, ("ldap_search failed %s\n",
980 tldap_errstr(debug_ctx(), state->ld, rc)));
981 return NT_STATUS_LDAP(rc);
984 count = talloc_array_length(groups);
986 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
987 if (group_sids == NULL) {
988 return NT_STATUS_NO_MEMORY;
990 gids = talloc_array(mem_ctx, gid_t, count);
992 TALLOC_FREE(group_sids);
993 return NT_STATUS_NO_MEMORY;
997 for (i=0; i<count; i++) {
998 if (!tldap_pull_binsid(groups[i], "objectSid",
999 &group_sids[num_groups])) {
1002 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
1005 if (num_groups == count) {
1010 *pp_sids = group_sids;
1012 *p_num_groups = num_groups;
1013 return NT_STATUS_OK;
1016 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
1017 TALLOC_CTX *mem_ctx,
1020 return NT_STATUS_NOT_IMPLEMENTED;
1023 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
1024 TALLOC_CTX *mem_ctx,
1025 uint32 grouprid, uint32 memberrid,
1028 struct pdb_ads_state *state = talloc_get_type_abort(
1029 m->private_data, struct pdb_ads_state);
1030 TALLOC_CTX *frame = talloc_stackframe();
1031 struct tldap_context *ld;
1032 struct dom_sid groupsid, membersid;
1033 char *groupdn, *memberdn;
1034 struct tldap_mod *mods;
1038 ld = pdb_ads_ld(state);
1040 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1043 sid_compose(&groupsid, &state->domainsid, grouprid);
1044 sid_compose(&membersid, &state->domainsid, memberrid);
1046 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
1047 if (!NT_STATUS_IS_OK(status)) {
1049 return NT_STATUS_NO_SUCH_GROUP;
1051 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
1052 if (!NT_STATUS_IS_OK(status)) {
1054 return NT_STATUS_NO_SUCH_USER;
1059 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1060 "member", memberdn)) {
1062 return NT_STATUS_NO_MEMORY;
1065 rc = tldap_modify(ld, groupdn, 1, mods, NULL, 0, NULL, 0);
1067 if (rc != TLDAP_SUCCESS) {
1068 DEBUG(10, ("ldap_modify failed: %s\n",
1069 tldap_errstr(debug_ctx(), state->ld, rc)));
1070 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1071 return NT_STATUS_MEMBER_IN_GROUP;
1073 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1074 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1076 return NT_STATUS_LDAP(rc);
1079 return NT_STATUS_OK;
1082 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
1083 TALLOC_CTX *mem_ctx,
1084 uint32 group_rid, uint32 member_rid)
1086 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1090 static NTSTATUS pdb_ads_del_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_create_alias(struct pdb_methods *m,
1099 const char *name, uint32 *rid)
1101 TALLOC_CTX *frame = talloc_stackframe();
1102 struct pdb_ads_state *state = talloc_get_type_abort(
1103 m->private_data, struct pdb_ads_state);
1104 struct tldap_context *ld;
1105 const char *attrs[1] = { "objectSid" };
1107 struct tldap_mod *mods = NULL;
1108 struct tldap_message **alias;
1114 ld = pdb_ads_ld(state);
1116 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1119 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1123 return NT_STATUS_NO_MEMORY;
1126 ok &= tldap_make_mod_fmt(
1127 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
1129 ok &= tldap_make_mod_fmt(
1130 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
1131 ok &= tldap_make_mod_fmt(
1132 NULL, talloc_tos(), &num_mods, &mods, "groupType",
1133 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1137 return NT_STATUS_NO_MEMORY;
1140 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1141 if (rc != TLDAP_SUCCESS) {
1142 DEBUG(10, ("ldap_add failed %s\n",
1143 tldap_errstr(debug_ctx(), state->ld, rc)));
1145 return NT_STATUS_LDAP(rc);
1148 rc = pdb_ads_search_fmt(
1149 state, state->domaindn, TLDAP_SCOPE_SUB,
1150 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1151 "(&(objectclass=group)(samaccountname=%s))", name);
1152 if (rc != TLDAP_SUCCESS) {
1153 DEBUG(10, ("Could not find just created alias %s: %s\n",
1154 name, tldap_errstr(debug_ctx(), state->ld, rc)));
1156 return NT_STATUS_LDAP(rc);
1159 if (talloc_array_length(alias) != 1) {
1160 DEBUG(10, ("Got %d alias, expected one\n",
1161 (int)talloc_array_length(alias)));
1163 return NT_STATUS_LDAP(rc);
1166 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1167 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1170 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1173 sid_peek_rid(&sid, rid);
1175 return NT_STATUS_OK;
1178 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1181 struct pdb_ads_state *state = talloc_get_type_abort(
1182 m->private_data, struct pdb_ads_state);
1183 struct tldap_context *ld;
1184 struct tldap_message **alias;
1188 ld = pdb_ads_ld(state);
1190 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1193 sidstr = sid_binstring(talloc_tos(), sid);
1194 if (sidstr == NULL) {
1195 return NT_STATUS_NO_MEMORY;
1198 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1199 NULL, 0, 0, talloc_tos(), &alias,
1200 "(&(objectSid=%s)(objectclass=group)"
1201 "(|(grouptype=%d)(grouptype=%d)))",
1202 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1203 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1204 TALLOC_FREE(sidstr);
1205 if (rc != TLDAP_SUCCESS) {
1206 DEBUG(10, ("ldap_search failed: %s\n",
1207 tldap_errstr(debug_ctx(), state->ld, rc)));
1209 return NT_STATUS_LDAP(rc);
1211 if (talloc_array_length(alias) != 1) {
1212 DEBUG(10, ("Expected 1 alias, got %d\n",
1213 (int)talloc_array_length(alias)));
1214 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1216 if (!tldap_entry_dn(alias[0], &dn)) {
1217 DEBUG(10, ("Could not get DN for alias %s\n",
1218 sid_string_dbg(sid)));
1219 return NT_STATUS_INTERNAL_ERROR;
1222 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
1223 if (rc != TLDAP_SUCCESS) {
1224 DEBUG(10, ("ldap_delete failed: %s\n",
1225 tldap_errstr(debug_ctx(), state->ld, rc)));
1227 return NT_STATUS_LDAP(rc);
1230 return NT_STATUS_OK;
1233 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1235 struct acct_info *info)
1237 struct pdb_ads_state *state = talloc_get_type_abort(
1238 m->private_data, struct pdb_ads_state);
1239 struct tldap_context *ld;
1240 const char *attrs[3] = { "objectSid", "description",
1242 struct tldap_message **msg;
1245 struct tldap_mod *mods;
1249 ld = pdb_ads_ld(state);
1251 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1254 sidstr = sid_binstring(talloc_tos(), sid);
1255 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1257 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1258 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1259 &msg, "(&(objectSid=%s)(objectclass=group)"
1260 "(|(grouptype=%d)(grouptype=%d)))",
1261 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1262 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1263 TALLOC_FREE(sidstr);
1264 if (rc != TLDAP_SUCCESS) {
1265 DEBUG(10, ("ldap_search failed %s\n",
1266 tldap_errstr(debug_ctx(), state->ld, rc)));
1267 return NT_STATUS_LDAP(rc);
1269 switch talloc_array_length(msg) {
1271 return NT_STATUS_NO_SUCH_ALIAS;
1275 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1278 if (!tldap_entry_dn(msg[0], &dn)) {
1280 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1287 ok &= tldap_make_mod_fmt(
1288 msg[0], msg, &num_mods, &mods, "description",
1289 "%s", info->acct_desc);
1290 ok &= tldap_make_mod_fmt(
1291 msg[0], msg, &num_mods, &mods, "samAccountName",
1292 "%s", info->acct_name);
1295 return NT_STATUS_NO_MEMORY;
1297 if (num_mods == 0) {
1300 return NT_STATUS_OK;
1303 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1305 if (rc != TLDAP_SUCCESS) {
1306 DEBUG(10, ("ldap_modify failed: %s\n",
1307 tldap_errstr(debug_ctx(), state->ld, rc)));
1308 return NT_STATUS_LDAP(rc);
1310 return NT_STATUS_OK;
1313 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1314 const struct dom_sid *sid,
1315 TALLOC_CTX *mem_ctx, char **pdn)
1317 struct tldap_message **msg;
1321 sidstr = sid_binstring(talloc_tos(), sid);
1322 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1324 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1325 NULL, 0, 0, talloc_tos(), &msg,
1326 "(objectsid=%s)", sidstr);
1327 TALLOC_FREE(sidstr);
1328 if (rc != TLDAP_SUCCESS) {
1329 DEBUG(10, ("ldap_search failed %s\n",
1330 tldap_errstr(debug_ctx(), state->ld, rc)));
1331 return NT_STATUS_LDAP(rc);
1334 switch talloc_array_length(msg) {
1336 return NT_STATUS_NOT_FOUND;
1340 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1343 if (!tldap_entry_dn(msg[0], &dn)) {
1344 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1347 dn = talloc_strdup(mem_ctx, dn);
1349 return NT_STATUS_NO_MEMORY;
1354 return NT_STATUS_OK;
1357 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1358 const DOM_SID *alias,
1359 const DOM_SID *member,
1362 struct pdb_ads_state *state = talloc_get_type_abort(
1363 m->private_data, struct pdb_ads_state);
1364 struct tldap_context *ld;
1365 TALLOC_CTX *frame = talloc_stackframe();
1366 struct tldap_mod *mods;
1368 char *aliasdn, *memberdn;
1371 ld = pdb_ads_ld(state);
1373 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1376 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1377 if (!NT_STATUS_IS_OK(status)) {
1378 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1379 sid_string_dbg(alias), nt_errstr(status)));
1381 return NT_STATUS_NO_SUCH_ALIAS;
1383 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1384 if (!NT_STATUS_IS_OK(status)) {
1385 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1386 sid_string_dbg(member), nt_errstr(status)));
1393 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1394 "member", memberdn)) {
1396 return NT_STATUS_NO_MEMORY;
1399 rc = tldap_modify(ld, aliasdn, 1, mods, NULL, 0, NULL, 0);
1401 if (rc != TLDAP_SUCCESS) {
1402 DEBUG(10, ("ldap_modify failed: %s\n",
1403 tldap_errstr(debug_ctx(), state->ld, rc)));
1404 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1405 return NT_STATUS_MEMBER_IN_ALIAS;
1407 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1408 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1410 return NT_STATUS_LDAP(rc);
1413 return NT_STATUS_OK;
1416 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1417 const DOM_SID *alias,
1418 const DOM_SID *member)
1420 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1423 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1424 const DOM_SID *alias,
1425 const DOM_SID *member)
1427 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1430 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
1431 struct dom_sid *psid)
1433 const char *attrs[1] = { "objectSid" };
1434 struct tldap_message **msg;
1440 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1441 dnblob->data, dnblob->length, &dn, &len,
1445 rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
1446 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1447 &msg, "(objectclass=*)");
1449 if (talloc_array_length(msg) != 1) {
1450 DEBUG(10, ("Got %d objects, expected one\n",
1451 (int)talloc_array_length(msg)));
1456 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1461 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1462 const DOM_SID *alias,
1463 TALLOC_CTX *mem_ctx,
1465 size_t *pnum_members)
1467 struct pdb_ads_state *state = talloc_get_type_abort(
1468 m->private_data, struct pdb_ads_state);
1469 const char *attrs[1] = { "member" };
1471 struct tldap_message **msg;
1472 int i, rc, num_members;
1474 struct dom_sid *members;
1476 sidstr = sid_binstring(talloc_tos(), alias);
1477 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1479 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1480 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1481 &msg, "(objectsid=%s)", sidstr);
1482 TALLOC_FREE(sidstr);
1483 if (rc != TLDAP_SUCCESS) {
1484 DEBUG(10, ("ldap_search failed %s\n",
1485 tldap_errstr(debug_ctx(), state->ld, rc)));
1486 return NT_STATUS_LDAP(rc);
1488 switch talloc_array_length(msg) {
1490 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1495 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1499 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1500 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1503 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1504 if (members == NULL) {
1505 return NT_STATUS_NO_MEMORY;
1508 for (i=0; i<num_members; i++) {
1509 if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
1510 TALLOC_FREE(members);
1511 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1515 *pmembers = members;
1516 *pnum_members = num_members;
1517 return NT_STATUS_OK;
1520 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1521 TALLOC_CTX *mem_ctx,
1522 const DOM_SID *domain_sid,
1523 const DOM_SID *members,
1525 uint32_t **palias_rids,
1526 size_t *pnum_alias_rids)
1528 struct pdb_ads_state *state = talloc_get_type_abort(
1529 m->private_data, struct pdb_ads_state);
1530 const char *attrs[1] = { "objectSid" };
1531 struct tldap_message **msg;
1532 uint32_t *alias_rids = NULL;
1533 size_t num_alias_rids = 0;
1535 bool got_members = false;
1540 * TODO: Get the filter right so that we only get the aliases from
1541 * either the SAM or BUILTIN
1544 filter = talloc_asprintf(talloc_tos(),
1545 "(&(|(grouptype=%d)(grouptype=%d))"
1546 "(objectclass=group)(|",
1547 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1548 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1549 if (filter == NULL) {
1550 return NT_STATUS_NO_MEMORY;
1553 for (i=0; i<num_members; i++) {
1556 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1557 if (!NT_STATUS_IS_OK(status)) {
1558 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1559 sid_string_dbg(&members[i]),
1560 nt_errstr(status)));
1563 filter = talloc_asprintf_append_buffer(
1564 filter, "(member=%s)", dn);
1566 if (filter == NULL) {
1567 return NT_STATUS_NO_MEMORY;
1576 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1577 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1578 &msg, "%s))", filter);
1579 TALLOC_FREE(filter);
1580 if (rc != TLDAP_SUCCESS) {
1581 DEBUG(10, ("tldap_search failed %s\n",
1582 tldap_errstr(debug_ctx(), state->ld, rc)));
1583 return NT_STATUS_LDAP(rc);
1586 count = talloc_array_length(msg);
1591 alias_rids = talloc_array(mem_ctx, uint32_t, count);
1592 if (alias_rids == NULL) {
1594 return NT_STATUS_NO_MEMORY;
1597 for (i=0; i<count; i++) {
1600 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1601 DEBUG(10, ("Could not pull SID for member %d\n", i));
1604 if (sid_peek_check_rid(domain_sid, &sid,
1605 &alias_rids[num_alias_rids])) {
1606 num_alias_rids += 1;
1611 *palias_rids = alias_rids;
1612 *pnum_alias_rids = 0;
1613 return NT_STATUS_OK;
1616 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1617 const DOM_SID *domain_sid,
1621 enum lsa_SidType *lsa_attrs)
1623 struct pdb_ads_state *state = talloc_get_type_abort(
1624 m->private_data, struct pdb_ads_state);
1625 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1628 if (num_rids == 0) {
1629 return NT_STATUS_NONE_MAPPED;
1634 for (i=0; i<num_rids; i++) {
1636 struct tldap_message **msg;
1641 lsa_attrs[i] = SID_NAME_UNKNOWN;
1643 sid_compose(&sid, domain_sid, rids[i]);
1645 sidstr = sid_binstring(talloc_tos(), &sid);
1646 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1648 rc = pdb_ads_search_fmt(state, state->domaindn,
1649 TLDAP_SCOPE_SUB, attrs,
1650 ARRAY_SIZE(attrs), 0, talloc_tos(),
1651 &msg, "(objectsid=%s)", sidstr);
1652 TALLOC_FREE(sidstr);
1653 if (rc != TLDAP_SUCCESS) {
1654 DEBUG(10, ("ldap_search failed %s\n",
1655 tldap_errstr(debug_ctx(), state->ld, rc)));
1659 switch talloc_array_length(msg) {
1661 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1666 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1669 names[i] = tldap_talloc_single_attribute(
1670 msg[0], "samAccountName", talloc_tos());
1671 if (names[i] == NULL) {
1672 DEBUG(10, ("no samAccountName\n"));
1675 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1676 DEBUG(10, ("no samAccountType"));
1679 lsa_attrs[i] = ads_atype_map(attr);
1683 if (num_mapped == 0) {
1684 return NT_STATUS_NONE_MAPPED;
1686 if (num_mapped < num_rids) {
1687 return STATUS_SOME_UNMAPPED;
1689 return NT_STATUS_OK;
1692 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1693 const DOM_SID *domain_sid,
1695 const char **pp_names,
1697 enum lsa_SidType *attrs)
1699 return NT_STATUS_NOT_IMPLEMENTED;
1702 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1703 int policy_index, uint32 *value)
1705 return account_policy_get(policy_index, value)
1706 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1709 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1710 int policy_index, uint32 value)
1712 return account_policy_set(policy_index, value)
1713 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1716 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1719 return NT_STATUS_NOT_IMPLEMENTED;
1722 struct pdb_ads_search_state {
1723 uint32_t acct_flags;
1724 struct samr_displayentry *entries;
1725 uint32_t num_entries;
1730 static bool pdb_ads_next_entry(struct pdb_search *search,
1731 struct samr_displayentry *entry)
1733 struct pdb_ads_search_state *state = talloc_get_type_abort(
1734 search->private_data, struct pdb_ads_search_state);
1736 if (state->current == state->num_entries) {
1740 entry->idx = state->entries[state->current].idx;
1741 entry->rid = state->entries[state->current].rid;
1742 entry->acct_flags = state->entries[state->current].acct_flags;
1744 entry->account_name = talloc_strdup(
1745 search, state->entries[state->current].account_name);
1746 entry->fullname = talloc_strdup(
1747 search, state->entries[state->current].fullname);
1748 entry->description = talloc_strdup(
1749 search, state->entries[state->current].description);
1751 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1752 || (entry->description == NULL)) {
1753 DEBUG(0, ("talloc_strdup failed\n"));
1757 state->current += 1;
1761 static void pdb_ads_search_end(struct pdb_search *search)
1763 struct pdb_ads_search_state *state = talloc_get_type_abort(
1764 search->private_data, struct pdb_ads_search_state);
1768 static bool pdb_ads_search_filter(struct pdb_methods *m,
1769 struct pdb_search *search,
1771 struct pdb_ads_search_state **pstate)
1773 struct pdb_ads_state *state = talloc_get_type_abort(
1774 m->private_data, struct pdb_ads_state);
1775 struct pdb_ads_search_state *sstate;
1776 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1777 "userAccountControl", "description" };
1778 struct tldap_message **users;
1779 int i, rc, num_users;
1781 sstate = talloc_zero(search, struct pdb_ads_search_state);
1782 if (sstate == NULL) {
1786 rc = pdb_ads_search_fmt(
1787 state, state->domaindn, TLDAP_SCOPE_SUB,
1788 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1790 if (rc != TLDAP_SUCCESS) {
1791 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1792 tldap_errstr(debug_ctx(), state->ld, rc)));
1796 num_users = talloc_array_length(users);
1798 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1800 if (sstate->entries == NULL) {
1801 DEBUG(10, ("talloc failed\n"));
1805 sstate->num_entries = 0;
1807 for (i=0; i<num_users; i++) {
1808 struct samr_displayentry *e;
1811 e = &sstate->entries[sstate->num_entries];
1813 e->idx = sstate->num_entries;
1814 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1815 DEBUG(10, ("Could not pull sid\n"));
1818 sid_peek_rid(&sid, &e->rid);
1819 e->acct_flags = ACB_NORMAL;
1820 e->account_name = tldap_talloc_single_attribute(
1821 users[i], "samAccountName", sstate->entries);
1822 if (e->account_name == NULL) {
1825 e->fullname = tldap_talloc_single_attribute(
1826 users[i], "displayName", sstate->entries);
1827 if (e->fullname == NULL) {
1830 e->description = tldap_talloc_single_attribute(
1831 users[i], "description", sstate->entries);
1832 if (e->description == NULL) {
1833 e->description = "";
1836 sstate->num_entries += 1;
1837 if (sstate->num_entries >= num_users) {
1842 search->private_data = sstate;
1843 search->next_entry = pdb_ads_next_entry;
1844 search->search_end = pdb_ads_search_end;
1849 static bool pdb_ads_search_users(struct pdb_methods *m,
1850 struct pdb_search *search,
1853 struct pdb_ads_search_state *sstate;
1856 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1860 sstate->acct_flags = acct_flags;
1864 static bool pdb_ads_search_groups(struct pdb_methods *m,
1865 struct pdb_search *search)
1867 struct pdb_ads_search_state *sstate;
1871 filter = talloc_asprintf(talloc_tos(),
1872 "(&(grouptype=%d)(objectclass=group))",
1873 GTYPE_SECURITY_GLOBAL_GROUP);
1874 if (filter == NULL) {
1877 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1878 TALLOC_FREE(filter);
1882 sstate->acct_flags = 0;
1886 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1887 struct pdb_search *search,
1890 struct pdb_ads_search_state *sstate;
1894 filter = talloc_asprintf(
1895 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1896 sid_check_is_builtin(sid)
1897 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1898 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1900 if (filter == NULL) {
1903 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1904 TALLOC_FREE(filter);
1908 sstate->acct_flags = 0;
1912 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1918 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1921 struct pdb_ads_state *state = talloc_get_type_abort(
1922 m->private_data, struct pdb_ads_state);
1923 sid_compose(sid, &state->domainsid, uid);
1927 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1930 struct pdb_ads_state *state = talloc_get_type_abort(
1931 m->private_data, struct pdb_ads_state);
1932 sid_compose(sid, &state->domainsid, gid);
1936 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1937 union unid_t *id, enum lsa_SidType *type)
1939 struct pdb_ads_state *state = talloc_get_type_abort(
1940 m->private_data, struct pdb_ads_state);
1941 struct tldap_message **msg;
1947 * This is a big, big hack: Just hard-code the rid as uid/gid.
1950 sid_peek_rid(sid, &rid);
1952 sidstr = sid_binstring(talloc_tos(), sid);
1953 if (sidstr == NULL) {
1957 rc = pdb_ads_search_fmt(
1958 state, state->domaindn, TLDAP_SCOPE_SUB,
1959 NULL, 0, 0, talloc_tos(), &msg,
1960 "(&(objectsid=%s)(objectclass=user))", sidstr);
1961 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1963 *type = SID_NAME_USER;
1964 TALLOC_FREE(sidstr);
1968 rc = pdb_ads_search_fmt(
1969 state, state->domaindn, TLDAP_SCOPE_SUB,
1970 NULL, 0, 0, talloc_tos(), &msg,
1971 "(&(objectsid=%s)(objectclass=group))", sidstr);
1972 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1974 *type = SID_NAME_DOM_GRP;
1975 TALLOC_FREE(sidstr);
1979 TALLOC_FREE(sidstr);
1983 static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
1985 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
1988 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1993 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1994 const char *domain, char** pwd,
1996 time_t *pass_last_set_time)
2001 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
2002 const char* domain, const char* pwd,
2008 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
2014 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
2015 TALLOC_CTX *mem_ctx,
2016 uint32 *num_domains,
2017 struct trustdom_info ***domains)
2019 return NT_STATUS_NOT_IMPLEMENTED;
2022 static void pdb_ads_init_methods(struct pdb_methods *m)
2025 m->get_domain_info = pdb_ads_get_domain_info;
2026 m->getsampwnam = pdb_ads_getsampwnam;
2027 m->getsampwsid = pdb_ads_getsampwsid;
2028 m->create_user = pdb_ads_create_user;
2029 m->delete_user = pdb_ads_delete_user;
2030 m->add_sam_account = pdb_ads_add_sam_account;
2031 m->update_sam_account = pdb_ads_update_sam_account;
2032 m->delete_sam_account = pdb_ads_delete_sam_account;
2033 m->rename_sam_account = pdb_ads_rename_sam_account;
2034 m->update_login_attempts = pdb_ads_update_login_attempts;
2035 m->getgrsid = pdb_ads_getgrsid;
2036 m->getgrgid = pdb_ads_getgrgid;
2037 m->getgrnam = pdb_ads_getgrnam;
2038 m->create_dom_group = pdb_ads_create_dom_group;
2039 m->delete_dom_group = pdb_ads_delete_dom_group;
2040 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
2041 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
2042 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
2043 m->enum_group_mapping = pdb_ads_enum_group_mapping;
2044 m->enum_group_members = pdb_ads_enum_group_members;
2045 m->enum_group_memberships = pdb_ads_enum_group_memberships;
2046 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
2047 m->add_groupmem = pdb_ads_add_groupmem;
2048 m->del_groupmem = pdb_ads_del_groupmem;
2049 m->create_alias = pdb_ads_create_alias;
2050 m->delete_alias = pdb_ads_delete_alias;
2051 m->get_aliasinfo = pdb_default_get_aliasinfo;
2052 m->set_aliasinfo = pdb_ads_set_aliasinfo;
2053 m->add_aliasmem = pdb_ads_add_aliasmem;
2054 m->del_aliasmem = pdb_ads_del_aliasmem;
2055 m->enum_aliasmem = pdb_ads_enum_aliasmem;
2056 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
2057 m->lookup_rids = pdb_ads_lookup_rids;
2058 m->lookup_names = pdb_ads_lookup_names;
2059 m->get_account_policy = pdb_ads_get_account_policy;
2060 m->set_account_policy = pdb_ads_set_account_policy;
2061 m->get_seq_num = pdb_ads_get_seq_num;
2062 m->search_users = pdb_ads_search_users;
2063 m->search_groups = pdb_ads_search_groups;
2064 m->search_aliases = pdb_ads_search_aliases;
2065 m->uid_to_rid = pdb_ads_uid_to_rid;
2066 m->uid_to_sid = pdb_ads_uid_to_sid;
2067 m->gid_to_sid = pdb_ads_gid_to_sid;
2068 m->sid_to_id = pdb_ads_sid_to_id;
2069 m->capabilities = pdb_ads_capabilities;
2070 m->new_rid = pdb_ads_new_rid;
2071 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2072 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2073 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2074 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2077 static void free_private_data(void **vp)
2079 struct pdb_ads_state *state = talloc_get_type_abort(
2080 *vp, struct pdb_ads_state);
2082 TALLOC_FREE(state->ld);
2087 this is used to catch debug messages from events
2089 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2090 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
2092 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2093 const char *fmt, va_list ap)
2095 int samba_level = -1;
2098 case TLDAP_DEBUG_FATAL:
2101 case TLDAP_DEBUG_ERROR:
2104 case TLDAP_DEBUG_WARNING:
2107 case TLDAP_DEBUG_TRACE:
2112 if (vasprintf(&s, fmt, ap) == -1) {
2115 DEBUG(samba_level, ("tldap: %s", s));
2119 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2124 if (tldap_connection_ok(state->ld)) {
2127 TALLOC_FREE(state->ld);
2129 status = open_socket_out(
2130 (struct sockaddr_storage *)(void *)&state->socket_address,
2132 if (!NT_STATUS_IS_OK(status)) {
2133 DEBUG(10, ("Could not connect to %s: %s\n",
2134 state->socket_address.sun_path, nt_errstr(status)));
2138 set_blocking(fd, false);
2140 state->ld = tldap_context_create(state, fd);
2141 if (state->ld == NULL) {
2145 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2150 int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2151 int scope, const char *attrs[], int num_attrs,
2153 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2154 const char *fmt, ...)
2156 struct tldap_context *ld;
2160 ld = pdb_ads_ld(state);
2162 return TLDAP_SERVER_DOWN;
2166 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2167 mem_ctx, res, fmt, ap);
2170 if (ret != TLDAP_SERVER_DOWN) {
2175 ld = pdb_ads_ld(state);
2177 return TLDAP_SERVER_DOWN;
2181 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2182 mem_ctx, res, fmt, ap);
2187 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2188 const char *location)
2190 const char *domain_attrs[2] = { "objectSid", "objectGUID" };
2191 const char *ncname_attrs[1] = { "netbiosname" };
2192 struct tldap_context *ld;
2193 struct tldap_message *rootdse, **domain, **ncname;
2194 TALLOC_CTX *frame = talloc_stackframe();
2199 ZERO_STRUCT(state->socket_address);
2200 state->socket_address.sun_family = AF_UNIX;
2201 strncpy(state->socket_address.sun_path, location,
2202 sizeof(state->socket_address.sun_path) - 1);
2204 ld = pdb_ads_ld(state);
2206 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2210 rc = tldap_fetch_rootdse(ld);
2211 if (rc != TLDAP_SUCCESS) {
2212 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2213 tldap_errstr(debug_ctx(), state->ld, rc)));
2214 status = NT_STATUS_LDAP(rc);
2217 rootdse = tldap_rootdse(state->ld);
2219 state->domaindn = tldap_talloc_single_attribute(
2220 rootdse, "defaultNamingContext", state);
2221 if (state->domaindn == NULL) {
2222 DEBUG(10, ("Could not get defaultNamingContext\n"));
2223 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2226 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2228 state->configdn = tldap_talloc_single_attribute(
2229 rootdse, "configurationNamingContext", state);
2230 if (state->domaindn == NULL) {
2231 DEBUG(10, ("Could not get configurationNamingContext\n"));
2232 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2235 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2238 * Figure out our domain's SID
2240 rc = pdb_ads_search_fmt(
2241 state, state->domaindn, TLDAP_SCOPE_BASE,
2242 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2243 talloc_tos(), &domain, "(objectclass=*)");
2244 if (rc != TLDAP_SUCCESS) {
2245 DEBUG(10, ("Could not retrieve domain: %s\n",
2246 tldap_errstr(debug_ctx(), state->ld, rc)));
2247 status = NT_STATUS_LDAP(rc);
2251 num_domains = talloc_array_length(domain);
2252 if (num_domains != 1) {
2253 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2254 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2257 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2258 DEBUG(10, ("Could not retrieve domain SID\n"));
2259 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2262 if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) {
2263 DEBUG(10, ("Could not retrieve domain GUID\n"));
2264 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2267 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2270 * Figure out our domain's short name
2272 rc = pdb_ads_search_fmt(
2273 state, state->configdn, TLDAP_SCOPE_SUB,
2274 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2275 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2276 if (rc != TLDAP_SUCCESS) {
2277 DEBUG(10, ("Could not retrieve ncname: %s\n",
2278 tldap_errstr(debug_ctx(), state->ld, rc)));
2279 status = NT_STATUS_LDAP(rc);
2282 if (talloc_array_length(ncname) != 1) {
2283 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2287 state->netbiosname = tldap_talloc_single_attribute(
2288 ncname[0], "netbiosname", state);
2289 if (state->netbiosname == NULL) {
2290 DEBUG(10, ("Could not get netbiosname\n"));
2291 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2294 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2296 if (!strequal(lp_workgroup(), state->netbiosname)) {
2297 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2298 state->netbiosname, lp_workgroup()));
2299 status = NT_STATUS_NO_SUCH_DOMAIN;
2303 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2305 status = NT_STATUS_OK;
2311 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2312 const char *location)
2314 struct pdb_methods *m;
2315 struct pdb_ads_state *state;
2319 m = talloc(talloc_autofree_context(), struct pdb_methods);
2321 return NT_STATUS_NO_MEMORY;
2323 state = talloc_zero(m, struct pdb_ads_state);
2324 if (state == NULL) {
2327 m->private_data = state;
2328 m->free_private_data = free_private_data;
2329 pdb_ads_init_methods(m);
2331 if (location == NULL) {
2332 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2336 if (location == NULL) {
2340 status = pdb_ads_connect(state, location);
2341 if (!NT_STATUS_IS_OK(status)) {
2342 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2347 return NT_STATUS_OK;
2349 status = NT_STATUS_NO_MEMORY;
2355 NTSTATUS pdb_ads_init(void);
2356 NTSTATUS pdb_ads_init(void)
2358 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",