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;
31 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
32 struct samu *sam_acct,
34 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
36 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
37 struct dom_sid *psid);
38 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
39 const struct dom_sid *sid,
40 TALLOC_CTX *mem_ctx, char **pdn);
41 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state);
42 static int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
43 int scope, const char *attrs[], int num_attrs,
45 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
46 const char *fmt, ...);
48 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
53 if (!tldap_pull_uint64(msg, attr, &tmp)) {
56 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
60 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
63 sid_peek_rid(sid, &rid);
67 struct pdb_ads_samu_private {
69 struct tldap_message *ldapmsg;
72 static struct pdb_domain_info *pdb_ads_get_domain_info(
73 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
78 static struct samu *pdb_ads_init_guest(TALLOC_CTX *mem_ctx,
79 struct pdb_methods *m)
81 struct pdb_ads_state *state = talloc_get_type_abort(
82 m->private_data, struct pdb_ads_state);
83 struct dom_sid guest_sid;
87 sid_compose(&guest_sid, &state->domainsid, DOMAIN_USER_RID_GUEST);
89 guest = samu_new(mem_ctx);
94 status = pdb_ads_getsampwsid(m, guest, &guest_sid);
95 if (!NT_STATUS_IS_OK(status)) {
96 DEBUG(10, ("Could not init guest account: %s\n",
104 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
105 struct pdb_methods *m, struct samu *sam)
107 struct pdb_ads_samu_private *result;
110 result = (struct pdb_ads_samu_private *)
111 pdb_get_backend_private_data(sam, m);
113 if (result != NULL) {
114 return talloc_get_type_abort(
115 result, struct pdb_ads_samu_private);
119 * This is now a weirdness of the passdb API. For the guest user we
120 * are not asked first.
122 sid_peek_rid(pdb_get_user_sid(sam), &rid);
124 if (rid == DOMAIN_USER_RID_GUEST) {
125 struct samu *guest = pdb_ads_init_guest(talloc_tos(), m);
130 result = talloc_get_type_abort(
131 pdb_get_backend_private_data(guest, m),
132 struct pdb_ads_samu_private);
133 pdb_set_backend_private_data(
134 sam, talloc_move(sam, &result), NULL, m, PDB_SET);
136 return talloc_get_type_abort(
137 pdb_get_backend_private_data(sam, m),
138 struct pdb_ads_samu_private);
144 static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m,
146 struct tldap_message *entry)
148 struct pdb_ads_state *state = talloc_get_type_abort(
149 m->private_data, struct pdb_ads_state);
150 TALLOC_CTX *frame = talloc_stackframe();
151 struct pdb_ads_samu_private *priv;
152 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
159 priv = talloc(sam, struct pdb_ads_samu_private);
161 return NT_STATUS_NO_MEMORY;
163 if (!tldap_entry_dn(entry, &priv->dn)) {
165 return NT_STATUS_INTERNAL_DB_CORRUPTION;
168 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
170 DEBUG(10, ("no samAccountName\n"));
173 pdb_set_username(sam, str, PDB_SET);
175 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
176 pdb_set_logon_time(sam, tmp_time, PDB_SET);
178 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
179 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
181 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
182 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
184 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
185 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
188 str = tldap_talloc_single_attribute(entry, "displayName",
191 pdb_set_fullname(sam, str, PDB_SET);
194 str = tldap_talloc_single_attribute(entry, "homeDirectory",
197 pdb_set_homedir(sam, str, PDB_SET);
200 str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
202 pdb_set_dir_drive(sam, str, PDB_SET);
205 str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
207 pdb_set_logon_script(sam, str, PDB_SET);
210 str = tldap_talloc_single_attribute(entry, "profilePath",
213 pdb_set_profile_path(sam, str, PDB_SET);
216 str = tldap_talloc_single_attribute(entry, "profilePath",
219 pdb_set_profile_path(sam, str, PDB_SET);
222 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
223 DEBUG(10, ("Could not pull SID\n"));
226 pdb_set_user_sid(sam, &sid, PDB_SET);
228 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
229 DEBUG(10, ("Could not pull userAccountControl\n"));
232 pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET);
234 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
235 if (blob.length != NT_HASH_LEN) {
236 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
237 (int)blob.length, NT_HASH_LEN));
240 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
243 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
244 if (blob.length != LM_HASH_LEN) {
245 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
246 (int)blob.length, LM_HASH_LEN));
249 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
252 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
253 sid_compose(&sid, &state->domainsid, n);
254 pdb_set_group_sid(sam, &sid, PDB_SET);
258 priv->ldapmsg = talloc_move(priv, &entry);
259 pdb_set_backend_private_data(sam, priv, NULL, m, PDB_SET);
261 status = NT_STATUS_OK;
267 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
268 struct tldap_message *existing,
270 int *pnum_mods, struct tldap_mod **pmods,
276 /* TODO: All fields :-) */
278 ret &= tldap_make_mod_fmt(
279 existing, mem_ctx, pnum_mods, pmods, "displayName",
280 "%s", pdb_get_fullname(sam));
282 blob = data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN);
283 if (blob.data != NULL) {
284 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
285 "unicodePwd", 1, &blob);
288 blob = data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN);
289 if (blob.data != NULL) {
290 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
291 "dBCSPwd", 1, &blob);
294 ret &= tldap_make_mod_fmt(
295 existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
296 "%d", ads_acb2uf(pdb_get_acct_ctrl(sam)));
298 ret &= tldap_make_mod_fmt(
299 existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
300 "%s", pdb_get_homedir(sam));
302 ret &= tldap_make_mod_fmt(
303 existing, mem_ctx, pnum_mods, pmods, "homeDrive",
304 "%s", pdb_get_dir_drive(sam));
306 ret &= tldap_make_mod_fmt(
307 existing, mem_ctx, pnum_mods, pmods, "scriptPath",
308 "%s", pdb_get_logon_script(sam));
310 ret &= tldap_make_mod_fmt(
311 existing, mem_ctx, pnum_mods, pmods, "profilePath",
312 "%s", pdb_get_profile_path(sam));
317 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
318 struct pdb_ads_state *state,
319 struct samu *sam_acct,
322 const char * attrs[] = {
323 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
324 "sAMAccountName", "displayName", "homeDirectory",
325 "homeDrive", "scriptPath", "profilePath", "description",
326 "userWorkstations", "comment", "userParameters", "objectSid",
327 "primaryGroupID", "userAccountControl", "logonHours",
328 "badPwdCount", "logonCount", "countryCode", "codePage",
329 "unicodePwd", "dBCSPwd" };
330 struct tldap_message **users;
333 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
334 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
335 &users, "%s", filter);
336 if (rc != TLDAP_SUCCESS) {
337 DEBUG(10, ("ldap_search failed %s\n",
338 tldap_errstr(debug_ctx(), state->ld, rc)));
339 return NT_STATUS_LDAP(rc);
342 count = talloc_array_length(users);
344 DEBUG(10, ("Expected 1 user, got %d\n", count));
345 return NT_STATUS_INTERNAL_DB_CORRUPTION;
348 return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]);
351 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
352 struct samu *sam_acct,
353 const char *username)
355 struct pdb_ads_state *state = talloc_get_type_abort(
356 m->private_data, struct pdb_ads_state);
359 filter = talloc_asprintf(
360 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
362 NT_STATUS_HAVE_NO_MEMORY(filter);
364 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
367 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
368 struct samu *sam_acct,
371 struct pdb_ads_state *state = talloc_get_type_abort(
372 m->private_data, struct pdb_ads_state);
373 char *sidstr, *filter;
375 sidstr = sid_binstring(talloc_tos(), sid);
376 NT_STATUS_HAVE_NO_MEMORY(sidstr);
378 filter = talloc_asprintf(
379 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
381 NT_STATUS_HAVE_NO_MEMORY(filter);
383 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
386 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
388 const char *name, uint32 acct_flags,
391 struct pdb_ads_state *state = talloc_get_type_abort(
392 m->private_data, struct pdb_ads_state);
393 struct tldap_context *ld;
394 const char *attrs[1] = { "objectSid" };
395 struct tldap_mod *mods = NULL;
397 struct tldap_message **user;
403 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
406 return NT_STATUS_NO_MEMORY;
409 ld = pdb_ads_ld(state);
411 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
414 /* TODO: Create machines etc */
417 ok &= tldap_make_mod_fmt(
418 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
419 ok &= tldap_make_mod_fmt(
420 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
423 return NT_STATUS_NO_MEMORY;
427 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
428 if (rc != TLDAP_SUCCESS) {
429 DEBUG(10, ("ldap_add failed %s\n",
430 tldap_errstr(debug_ctx(), ld, rc)));
432 return NT_STATUS_LDAP(rc);
435 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
436 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
438 "(&(objectclass=user)(samaccountname=%s))",
440 if (rc != TLDAP_SUCCESS) {
441 DEBUG(10, ("Could not find just created user %s: %s\n",
442 name, tldap_errstr(debug_ctx(), state->ld, rc)));
444 return NT_STATUS_LDAP(rc);
447 if (talloc_array_length(user) != 1) {
448 DEBUG(10, ("Got %d users, expected one\n",
449 (int)talloc_array_length(user)));
451 return NT_STATUS_LDAP(rc);
454 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
455 DEBUG(10, ("Could not fetch objectSid from user %s\n",
458 return NT_STATUS_INTERNAL_DB_CORRUPTION;
461 sid_peek_rid(&sid, rid);
466 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
470 struct pdb_ads_state *state = talloc_get_type_abort(
471 m->private_data, struct pdb_ads_state);
473 struct tldap_context *ld;
477 ld = pdb_ads_ld(state);
479 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
482 status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
484 if (!NT_STATUS_IS_OK(status)) {
488 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
490 if (rc != TLDAP_SUCCESS) {
491 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
492 tldap_errstr(debug_ctx(), ld, rc)));
493 return NT_STATUS_LDAP(rc);
498 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
499 struct samu *sampass)
501 return NT_STATUS_NOT_IMPLEMENTED;
504 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
507 struct pdb_ads_state *state = talloc_get_type_abort(
508 m->private_data, struct pdb_ads_state);
509 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
510 struct tldap_context *ld;
511 struct tldap_mod *mods = NULL;
512 int rc, num_mods = 0;
514 ld = pdb_ads_ld(state);
516 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
519 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
520 &num_mods, &mods, sam)) {
521 return NT_STATUS_NO_MEMORY;
525 /* Nothing to do, just return success */
529 rc = tldap_modify(ld, priv->dn, num_mods, mods, NULL, 0,
532 if (rc != TLDAP_SUCCESS) {
533 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
534 tldap_errstr(debug_ctx(), ld, rc)));
535 return NT_STATUS_LDAP(rc);
541 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
542 struct samu *username)
544 return NT_STATUS_NOT_IMPLEMENTED;
547 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
548 struct samu *oldname,
551 return NT_STATUS_NOT_IMPLEMENTED;
554 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
555 struct samu *sam_acct,
558 return NT_STATUS_NOT_IMPLEMENTED;
561 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
564 struct pdb_ads_state *state = talloc_get_type_abort(
565 m->private_data, struct pdb_ads_state);
566 const char *attrs[4] = { "objectSid", "description", "samAccountName",
569 struct tldap_message **group;
573 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
574 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
575 &group, "%s", filter);
576 if (rc != TLDAP_SUCCESS) {
577 DEBUG(10, ("ldap_search failed %s\n",
578 tldap_errstr(debug_ctx(), state->ld, rc)));
579 return NT_STATUS_LDAP(rc);
581 if (talloc_array_length(group) != 1) {
582 DEBUG(10, ("Expected 1 user, got %d\n",
583 (int)talloc_array_length(group)));
584 return NT_STATUS_INTERNAL_DB_CORRUPTION;
587 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
588 return NT_STATUS_INTERNAL_DB_CORRUPTION;
590 map->gid = pdb_ads_sid2gid(&map->sid);
592 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
593 return NT_STATUS_INTERNAL_DB_CORRUPTION;
596 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
597 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
598 map->sid_name_use = SID_NAME_ALIAS;
600 case GTYPE_SECURITY_GLOBAL_GROUP:
601 map->sid_name_use = SID_NAME_DOM_GRP;
604 return NT_STATUS_INTERNAL_DB_CORRUPTION;
607 str = tldap_talloc_single_attribute(group[0], "samAccountName",
610 return NT_STATUS_INTERNAL_DB_CORRUPTION;
612 fstrcpy(map->nt_name, str);
615 str = tldap_talloc_single_attribute(group[0], "description",
618 fstrcpy(map->comment, str);
621 map->comment[0] = '\0';
628 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
634 filter = talloc_asprintf(talloc_tos(),
635 "(&(objectsid=%s)(objectclass=group))",
636 sid_string_talloc(talloc_tos(), &sid));
637 if (filter == NULL) {
638 return NT_STATUS_NO_MEMORY;
641 status = pdb_ads_getgrfilter(m, map, filter);
646 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
650 pdb_ads_gid_to_sid(m, gid, &sid);
651 return pdb_ads_getgrsid(m, map, sid);
654 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
660 filter = talloc_asprintf(talloc_tos(),
661 "(&(samaccountname=%s)(objectclass=group))",
663 if (filter == NULL) {
664 return NT_STATUS_NO_MEMORY;
667 status = pdb_ads_getgrfilter(m, map, filter);
672 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
673 TALLOC_CTX *mem_ctx, const char *name,
676 TALLOC_CTX *frame = talloc_stackframe();
677 struct pdb_ads_state *state = talloc_get_type_abort(
678 m->private_data, struct pdb_ads_state);
679 struct tldap_context *ld;
680 const char *attrs[1] = { "objectSid" };
682 struct tldap_mod *mods = NULL;
683 struct tldap_message **alias;
689 ld = pdb_ads_ld(state);
691 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
694 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
698 return NT_STATUS_NO_MEMORY;
701 ok &= tldap_make_mod_fmt(
702 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
704 ok &= tldap_make_mod_fmt(
705 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
706 ok &= tldap_make_mod_fmt(
707 NULL, talloc_tos(), &num_mods, &mods, "groupType",
708 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
712 return NT_STATUS_NO_MEMORY;
715 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
716 if (rc != TLDAP_SUCCESS) {
717 DEBUG(10, ("ldap_add failed %s\n",
718 tldap_errstr(debug_ctx(), state->ld, rc)));
720 return NT_STATUS_LDAP(rc);
723 rc = pdb_ads_search_fmt(
724 state, state->domaindn, TLDAP_SCOPE_SUB,
725 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
726 "(&(objectclass=group)(samaccountname=%s))", name);
727 if (rc != TLDAP_SUCCESS) {
728 DEBUG(10, ("Could not find just created alias %s: %s\n",
729 name, tldap_errstr(debug_ctx(), state->ld, rc)));
731 return NT_STATUS_LDAP(rc);
734 if (talloc_array_length(alias) != 1) {
735 DEBUG(10, ("Got %d alias, expected one\n",
736 (int)talloc_array_length(alias)));
738 return NT_STATUS_LDAP(rc);
741 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
742 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
745 return NT_STATUS_INTERNAL_DB_CORRUPTION;
748 sid_peek_rid(&sid, rid);
753 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
754 TALLOC_CTX *mem_ctx, uint32 rid)
756 struct pdb_ads_state *state = talloc_get_type_abort(
757 m->private_data, struct pdb_ads_state);
758 struct tldap_context *ld;
761 struct tldap_message **msg;
765 sid_compose(&sid, &state->domainsid, rid);
767 sidstr = sid_binstring(talloc_tos(), &sid);
768 NT_STATUS_HAVE_NO_MEMORY(sidstr);
770 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
771 NULL, 0, 0, talloc_tos(), &msg,
772 ("(&(objectSid=%s)(objectClass=group))"),
775 if (rc != TLDAP_SUCCESS) {
776 DEBUG(10, ("ldap_search failed %s\n",
777 tldap_errstr(debug_ctx(), state->ld, rc)));
778 return NT_STATUS_LDAP(rc);
781 switch talloc_array_length(msg) {
783 return NT_STATUS_NO_SUCH_GROUP;
787 return NT_STATUS_INTERNAL_DB_CORRUPTION;
790 if (!tldap_entry_dn(msg[0], &dn)) {
792 return NT_STATUS_INTERNAL_DB_CORRUPTION;
795 ld = pdb_ads_ld(state);
798 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
801 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
803 if (rc != TLDAP_SUCCESS) {
804 DEBUG(10, ("ldap_delete failed: %s\n",
805 tldap_errstr(debug_ctx(), state->ld, rc)));
806 return NT_STATUS_LDAP(rc);
812 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
815 return NT_STATUS_NOT_IMPLEMENTED;
818 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
821 return NT_STATUS_NOT_IMPLEMENTED;
824 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
827 return NT_STATUS_NOT_IMPLEMENTED;
830 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
832 enum lsa_SidType sid_name_use,
834 size_t *p_num_entries,
837 return NT_STATUS_NOT_IMPLEMENTED;
840 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
842 const DOM_SID *group,
844 size_t *pnum_members)
846 struct pdb_ads_state *state = talloc_get_type_abort(
847 m->private_data, struct pdb_ads_state);
848 const char *attrs[1] = { "member" };
850 struct tldap_message **msg;
851 int i, rc, num_members;
855 sidstr = sid_binstring(talloc_tos(), group);
856 NT_STATUS_HAVE_NO_MEMORY(sidstr);
858 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
859 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
860 &msg, "(objectsid=%s)", sidstr);
862 if (rc != TLDAP_SUCCESS) {
863 DEBUG(10, ("ldap_search failed %s\n",
864 tldap_errstr(debug_ctx(), state->ld, rc)));
865 return NT_STATUS_LDAP(rc);
867 switch talloc_array_length(msg) {
869 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
874 return NT_STATUS_INTERNAL_DB_CORRUPTION;
878 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
879 return NT_STATUS_INTERNAL_DB_CORRUPTION;
882 members = talloc_array(mem_ctx, uint32_t, num_members);
883 if (members == NULL) {
884 return NT_STATUS_NO_MEMORY;
887 for (i=0; i<num_members; i++) {
889 if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
890 || !sid_peek_rid(&sid, &members[i])) {
891 TALLOC_FREE(members);
892 return NT_STATUS_INTERNAL_DB_CORRUPTION;
897 *pnum_members = num_members;
901 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
906 size_t *p_num_groups)
908 struct pdb_ads_state *state = talloc_get_type_abort(
909 m->private_data, struct pdb_ads_state);
910 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
912 const char *attrs[1] = { "objectSid" };
913 struct tldap_message **groups;
916 struct dom_sid *group_sids;
919 rc = pdb_ads_search_fmt(
920 state, state->domaindn, TLDAP_SCOPE_SUB,
921 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
922 "(&(member=%s)(grouptype=%d)(objectclass=group))",
923 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
924 if (rc != TLDAP_SUCCESS) {
925 DEBUG(10, ("ldap_search failed %s\n",
926 tldap_errstr(debug_ctx(), state->ld, rc)));
927 return NT_STATUS_LDAP(rc);
930 count = talloc_array_length(groups);
932 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
933 if (group_sids == NULL) {
934 return NT_STATUS_NO_MEMORY;
936 gids = talloc_array(mem_ctx, gid_t, count);
938 TALLOC_FREE(group_sids);
939 return NT_STATUS_NO_MEMORY;
943 for (i=0; i<count; i++) {
944 if (!tldap_pull_binsid(groups[i], "objectSid",
945 &group_sids[num_groups])) {
948 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
951 if (num_groups == count) {
956 *pp_sids = group_sids;
958 *p_num_groups = num_groups;
962 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
966 return NT_STATUS_NOT_IMPLEMENTED;
969 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
971 uint32 grouprid, uint32 memberrid,
974 struct pdb_ads_state *state = talloc_get_type_abort(
975 m->private_data, struct pdb_ads_state);
976 TALLOC_CTX *frame = talloc_stackframe();
977 struct tldap_context *ld;
978 struct dom_sid groupsid, membersid;
979 char *groupdn, *memberdn;
980 struct tldap_mod *mods;
984 ld = pdb_ads_ld(state);
986 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
989 sid_compose(&groupsid, &state->domainsid, grouprid);
990 sid_compose(&membersid, &state->domainsid, memberrid);
992 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
993 if (!NT_STATUS_IS_OK(status)) {
995 return NT_STATUS_NO_SUCH_GROUP;
997 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
998 if (!NT_STATUS_IS_OK(status)) {
1000 return NT_STATUS_NO_SUCH_USER;
1005 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1006 "member", memberdn)) {
1008 return NT_STATUS_NO_MEMORY;
1011 rc = tldap_modify(ld, groupdn, 1, mods, NULL, 0, NULL, 0);
1013 if (rc != TLDAP_SUCCESS) {
1014 DEBUG(10, ("ldap_modify failed: %s\n",
1015 tldap_errstr(debug_ctx(), state->ld, rc)));
1016 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1017 return NT_STATUS_MEMBER_IN_GROUP;
1019 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1020 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1022 return NT_STATUS_LDAP(rc);
1025 return NT_STATUS_OK;
1028 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
1029 TALLOC_CTX *mem_ctx,
1030 uint32 group_rid, uint32 member_rid)
1032 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1036 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
1037 TALLOC_CTX *mem_ctx,
1038 uint32 group_rid, uint32 member_rid)
1040 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1044 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
1045 const char *name, uint32 *rid)
1047 TALLOC_CTX *frame = talloc_stackframe();
1048 struct pdb_ads_state *state = talloc_get_type_abort(
1049 m->private_data, struct pdb_ads_state);
1050 struct tldap_context *ld;
1051 const char *attrs[1] = { "objectSid" };
1053 struct tldap_mod *mods = NULL;
1054 struct tldap_message **alias;
1060 ld = pdb_ads_ld(state);
1062 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1065 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1069 return NT_STATUS_NO_MEMORY;
1072 ok &= tldap_make_mod_fmt(
1073 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
1075 ok &= tldap_make_mod_fmt(
1076 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
1077 ok &= tldap_make_mod_fmt(
1078 NULL, talloc_tos(), &num_mods, &mods, "groupType",
1079 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1083 return NT_STATUS_NO_MEMORY;
1086 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1087 if (rc != TLDAP_SUCCESS) {
1088 DEBUG(10, ("ldap_add failed %s\n",
1089 tldap_errstr(debug_ctx(), state->ld, rc)));
1091 return NT_STATUS_LDAP(rc);
1094 rc = pdb_ads_search_fmt(
1095 state, state->domaindn, TLDAP_SCOPE_SUB,
1096 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1097 "(&(objectclass=group)(samaccountname=%s))", name);
1098 if (rc != TLDAP_SUCCESS) {
1099 DEBUG(10, ("Could not find just created alias %s: %s\n",
1100 name, tldap_errstr(debug_ctx(), state->ld, rc)));
1102 return NT_STATUS_LDAP(rc);
1105 if (talloc_array_length(alias) != 1) {
1106 DEBUG(10, ("Got %d alias, expected one\n",
1107 (int)talloc_array_length(alias)));
1109 return NT_STATUS_LDAP(rc);
1112 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1113 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1116 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1119 sid_peek_rid(&sid, rid);
1121 return NT_STATUS_OK;
1124 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1127 struct pdb_ads_state *state = talloc_get_type_abort(
1128 m->private_data, struct pdb_ads_state);
1129 struct tldap_context *ld;
1130 struct tldap_message **alias;
1134 ld = pdb_ads_ld(state);
1136 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1139 sidstr = sid_binstring(talloc_tos(), sid);
1140 if (sidstr == NULL) {
1141 return NT_STATUS_NO_MEMORY;
1144 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1145 NULL, 0, 0, talloc_tos(), &alias,
1146 "(&(objectSid=%s)(objectclass=group)"
1147 "(|(grouptype=%d)(grouptype=%d)))",
1148 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1149 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1150 TALLOC_FREE(sidstr);
1151 if (rc != TLDAP_SUCCESS) {
1152 DEBUG(10, ("ldap_search failed: %s\n",
1153 tldap_errstr(debug_ctx(), state->ld, rc)));
1155 return NT_STATUS_LDAP(rc);
1157 if (talloc_array_length(alias) != 1) {
1158 DEBUG(10, ("Expected 1 alias, got %d\n",
1159 (int)talloc_array_length(alias)));
1160 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1162 if (!tldap_entry_dn(alias[0], &dn)) {
1163 DEBUG(10, ("Could not get DN for alias %s\n",
1164 sid_string_dbg(sid)));
1165 return NT_STATUS_INTERNAL_ERROR;
1168 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
1169 if (rc != TLDAP_SUCCESS) {
1170 DEBUG(10, ("ldap_delete failed: %s\n",
1171 tldap_errstr(debug_ctx(), state->ld, rc)));
1173 return NT_STATUS_LDAP(rc);
1176 return NT_STATUS_OK;
1179 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1181 struct acct_info *info)
1183 struct pdb_ads_state *state = talloc_get_type_abort(
1184 m->private_data, struct pdb_ads_state);
1185 struct tldap_context *ld;
1186 const char *attrs[3] = { "objectSid", "description",
1188 struct tldap_message **msg;
1191 struct tldap_mod *mods;
1195 ld = pdb_ads_ld(state);
1197 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1200 sidstr = sid_binstring(talloc_tos(), sid);
1201 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1203 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1204 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1205 &msg, "(&(objectSid=%s)(objectclass=group)"
1206 "(|(grouptype=%d)(grouptype=%d)))",
1207 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1208 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1209 TALLOC_FREE(sidstr);
1210 if (rc != TLDAP_SUCCESS) {
1211 DEBUG(10, ("ldap_search failed %s\n",
1212 tldap_errstr(debug_ctx(), state->ld, rc)));
1213 return NT_STATUS_LDAP(rc);
1215 switch talloc_array_length(msg) {
1217 return NT_STATUS_NO_SUCH_ALIAS;
1221 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1224 if (!tldap_entry_dn(msg[0], &dn)) {
1226 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1233 ok &= tldap_make_mod_fmt(
1234 msg[0], msg, &num_mods, &mods, "description",
1235 "%s", info->acct_desc);
1236 ok &= tldap_make_mod_fmt(
1237 msg[0], msg, &num_mods, &mods, "samAccountName",
1238 "%s", info->acct_name);
1241 return NT_STATUS_NO_MEMORY;
1243 if (num_mods == 0) {
1246 return NT_STATUS_OK;
1249 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1251 if (rc != TLDAP_SUCCESS) {
1252 DEBUG(10, ("ldap_modify failed: %s\n",
1253 tldap_errstr(debug_ctx(), state->ld, rc)));
1254 return NT_STATUS_LDAP(rc);
1256 return NT_STATUS_OK;
1259 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1260 const struct dom_sid *sid,
1261 TALLOC_CTX *mem_ctx, char **pdn)
1263 struct tldap_message **msg;
1267 sidstr = sid_binstring(talloc_tos(), sid);
1268 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1270 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1271 NULL, 0, 0, talloc_tos(), &msg,
1272 "(objectsid=%s)", sidstr);
1273 TALLOC_FREE(sidstr);
1274 if (rc != TLDAP_SUCCESS) {
1275 DEBUG(10, ("ldap_search failed %s\n",
1276 tldap_errstr(debug_ctx(), state->ld, rc)));
1277 return NT_STATUS_LDAP(rc);
1280 switch talloc_array_length(msg) {
1282 return NT_STATUS_NOT_FOUND;
1286 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1289 if (!tldap_entry_dn(msg[0], &dn)) {
1290 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1293 dn = talloc_strdup(mem_ctx, dn);
1295 return NT_STATUS_NO_MEMORY;
1300 return NT_STATUS_OK;
1303 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1304 const DOM_SID *alias,
1305 const DOM_SID *member,
1308 struct pdb_ads_state *state = talloc_get_type_abort(
1309 m->private_data, struct pdb_ads_state);
1310 struct tldap_context *ld;
1311 TALLOC_CTX *frame = talloc_stackframe();
1312 struct tldap_mod *mods;
1314 char *aliasdn, *memberdn;
1317 ld = pdb_ads_ld(state);
1319 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1322 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1323 if (!NT_STATUS_IS_OK(status)) {
1324 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1325 sid_string_dbg(alias), nt_errstr(status)));
1327 return NT_STATUS_NO_SUCH_ALIAS;
1329 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1330 if (!NT_STATUS_IS_OK(status)) {
1331 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1332 sid_string_dbg(member), nt_errstr(status)));
1339 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1340 "member", memberdn)) {
1342 return NT_STATUS_NO_MEMORY;
1345 rc = tldap_modify(ld, aliasdn, 1, mods, NULL, 0, NULL, 0);
1347 if (rc != TLDAP_SUCCESS) {
1348 DEBUG(10, ("ldap_modify failed: %s\n",
1349 tldap_errstr(debug_ctx(), state->ld, rc)));
1350 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1351 return NT_STATUS_MEMBER_IN_ALIAS;
1353 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1354 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1356 return NT_STATUS_LDAP(rc);
1359 return NT_STATUS_OK;
1362 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1363 const DOM_SID *alias,
1364 const DOM_SID *member)
1366 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1369 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1370 const DOM_SID *alias,
1371 const DOM_SID *member)
1373 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1376 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
1377 struct dom_sid *psid)
1379 const char *attrs[1] = { "objectSid" };
1380 struct tldap_message **msg;
1386 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1387 dnblob->data, dnblob->length, &dn, &len,
1391 rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
1392 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1393 &msg, "(objectclass=*)");
1395 if (talloc_array_length(msg) != 1) {
1396 DEBUG(10, ("Got %d objects, expected one\n",
1397 (int)talloc_array_length(msg)));
1402 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1407 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1408 const DOM_SID *alias,
1409 TALLOC_CTX *mem_ctx,
1411 size_t *pnum_members)
1413 struct pdb_ads_state *state = talloc_get_type_abort(
1414 m->private_data, struct pdb_ads_state);
1415 const char *attrs[1] = { "member" };
1417 struct tldap_message **msg;
1418 int i, rc, num_members;
1420 struct dom_sid *members;
1422 sidstr = sid_binstring(talloc_tos(), alias);
1423 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1425 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1426 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1427 &msg, "(objectsid=%s)", sidstr);
1428 TALLOC_FREE(sidstr);
1429 if (rc != TLDAP_SUCCESS) {
1430 DEBUG(10, ("ldap_search failed %s\n",
1431 tldap_errstr(debug_ctx(), state->ld, rc)));
1432 return NT_STATUS_LDAP(rc);
1434 switch talloc_array_length(msg) {
1436 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1441 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1445 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1446 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1449 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1450 if (members == NULL) {
1451 return NT_STATUS_NO_MEMORY;
1454 for (i=0; i<num_members; i++) {
1455 if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
1456 TALLOC_FREE(members);
1457 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1461 *pmembers = members;
1462 *pnum_members = num_members;
1463 return NT_STATUS_OK;
1466 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1467 TALLOC_CTX *mem_ctx,
1468 const DOM_SID *domain_sid,
1469 const DOM_SID *members,
1471 uint32_t **palias_rids,
1472 size_t *pnum_alias_rids)
1474 struct pdb_ads_state *state = talloc_get_type_abort(
1475 m->private_data, struct pdb_ads_state);
1476 const char *attrs[1] = { "objectSid" };
1477 struct tldap_message **msg;
1478 uint32_t *alias_rids = NULL;
1479 size_t num_alias_rids = 0;
1481 bool got_members = false;
1486 * TODO: Get the filter right so that we only get the aliases from
1487 * either the SAM or BUILTIN
1490 filter = talloc_asprintf(talloc_tos(),
1491 "(&(|(grouptype=%d)(grouptype=%d))"
1492 "(objectclass=group)(|",
1493 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1494 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1495 if (filter == NULL) {
1496 return NT_STATUS_NO_MEMORY;
1499 for (i=0; i<num_members; i++) {
1502 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1503 if (!NT_STATUS_IS_OK(status)) {
1504 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1505 sid_string_dbg(&members[i]),
1506 nt_errstr(status)));
1509 filter = talloc_asprintf_append_buffer(
1510 filter, "(member=%s)", dn);
1512 if (filter == NULL) {
1513 return NT_STATUS_NO_MEMORY;
1522 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1523 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1524 &msg, "%s))", filter);
1525 TALLOC_FREE(filter);
1526 if (rc != TLDAP_SUCCESS) {
1527 DEBUG(10, ("tldap_search failed %s\n",
1528 tldap_errstr(debug_ctx(), state->ld, rc)));
1529 return NT_STATUS_LDAP(rc);
1532 count = talloc_array_length(msg);
1537 alias_rids = talloc_array(mem_ctx, uint32_t, count);
1538 if (alias_rids == NULL) {
1540 return NT_STATUS_NO_MEMORY;
1543 for (i=0; i<count; i++) {
1546 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1547 DEBUG(10, ("Could not pull SID for member %d\n", i));
1550 if (sid_peek_check_rid(domain_sid, &sid,
1551 &alias_rids[num_alias_rids])) {
1552 num_alias_rids += 1;
1557 *palias_rids = alias_rids;
1558 *pnum_alias_rids = 0;
1559 return NT_STATUS_OK;
1562 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1563 const DOM_SID *domain_sid,
1567 enum lsa_SidType *lsa_attrs)
1569 struct pdb_ads_state *state = talloc_get_type_abort(
1570 m->private_data, struct pdb_ads_state);
1571 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1574 if (num_rids == 0) {
1575 return NT_STATUS_NONE_MAPPED;
1580 for (i=0; i<num_rids; i++) {
1582 struct tldap_message **msg;
1587 lsa_attrs[i] = SID_NAME_UNKNOWN;
1589 sid_compose(&sid, domain_sid, rids[i]);
1591 sidstr = sid_binstring(talloc_tos(), &sid);
1592 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1594 rc = pdb_ads_search_fmt(state, state->domaindn,
1595 TLDAP_SCOPE_SUB, attrs,
1596 ARRAY_SIZE(attrs), 0, talloc_tos(),
1597 &msg, "(objectsid=%s)", sidstr);
1598 TALLOC_FREE(sidstr);
1599 if (rc != TLDAP_SUCCESS) {
1600 DEBUG(10, ("ldap_search failed %s\n",
1601 tldap_errstr(debug_ctx(), state->ld, rc)));
1605 switch talloc_array_length(msg) {
1607 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1612 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1615 names[i] = tldap_talloc_single_attribute(
1616 msg[0], "samAccountName", talloc_tos());
1617 if (names[i] == NULL) {
1618 DEBUG(10, ("no samAccountName\n"));
1621 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1622 DEBUG(10, ("no samAccountType"));
1625 lsa_attrs[i] = ads_atype_map(attr);
1629 if (num_mapped == 0) {
1630 return NT_STATUS_NONE_MAPPED;
1632 if (num_mapped < num_rids) {
1633 return STATUS_SOME_UNMAPPED;
1635 return NT_STATUS_OK;
1638 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1639 const DOM_SID *domain_sid,
1641 const char **pp_names,
1643 enum lsa_SidType *attrs)
1645 return NT_STATUS_NOT_IMPLEMENTED;
1648 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1649 int policy_index, uint32 *value)
1651 return account_policy_get(policy_index, value)
1652 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1655 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1656 int policy_index, uint32 value)
1658 return account_policy_set(policy_index, value)
1659 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1662 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1665 return NT_STATUS_NOT_IMPLEMENTED;
1668 struct pdb_ads_search_state {
1669 uint32_t acct_flags;
1670 struct samr_displayentry *entries;
1671 uint32_t num_entries;
1676 static bool pdb_ads_next_entry(struct pdb_search *search,
1677 struct samr_displayentry *entry)
1679 struct pdb_ads_search_state *state = talloc_get_type_abort(
1680 search->private_data, struct pdb_ads_search_state);
1682 if (state->current == state->num_entries) {
1686 entry->idx = state->entries[state->current].idx;
1687 entry->rid = state->entries[state->current].rid;
1688 entry->acct_flags = state->entries[state->current].acct_flags;
1690 entry->account_name = talloc_strdup(
1691 search, state->entries[state->current].account_name);
1692 entry->fullname = talloc_strdup(
1693 search, state->entries[state->current].fullname);
1694 entry->description = talloc_strdup(
1695 search, state->entries[state->current].description);
1697 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1698 || (entry->description == NULL)) {
1699 DEBUG(0, ("talloc_strdup failed\n"));
1703 state->current += 1;
1707 static void pdb_ads_search_end(struct pdb_search *search)
1709 struct pdb_ads_search_state *state = talloc_get_type_abort(
1710 search->private_data, struct pdb_ads_search_state);
1714 static bool pdb_ads_search_filter(struct pdb_methods *m,
1715 struct pdb_search *search,
1717 struct pdb_ads_search_state **pstate)
1719 struct pdb_ads_state *state = talloc_get_type_abort(
1720 m->private_data, struct pdb_ads_state);
1721 struct pdb_ads_search_state *sstate;
1722 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1723 "userAccountControl", "description" };
1724 struct tldap_message **users;
1725 int i, rc, num_users;
1727 sstate = talloc_zero(search, struct pdb_ads_search_state);
1728 if (sstate == NULL) {
1732 rc = pdb_ads_search_fmt(
1733 state, state->domaindn, TLDAP_SCOPE_SUB,
1734 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1736 if (rc != TLDAP_SUCCESS) {
1737 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1738 tldap_errstr(debug_ctx(), state->ld, rc)));
1742 num_users = talloc_array_length(users);
1744 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1746 if (sstate->entries == NULL) {
1747 DEBUG(10, ("talloc failed\n"));
1751 sstate->num_entries = 0;
1753 for (i=0; i<num_users; i++) {
1754 struct samr_displayentry *e;
1757 e = &sstate->entries[sstate->num_entries];
1759 e->idx = sstate->num_entries;
1760 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1761 DEBUG(10, ("Could not pull sid\n"));
1764 sid_peek_rid(&sid, &e->rid);
1765 e->acct_flags = ACB_NORMAL;
1766 e->account_name = tldap_talloc_single_attribute(
1767 users[i], "samAccountName", sstate->entries);
1768 if (e->account_name == NULL) {
1771 e->fullname = tldap_talloc_single_attribute(
1772 users[i], "displayName", sstate->entries);
1773 if (e->fullname == NULL) {
1776 e->description = tldap_talloc_single_attribute(
1777 users[i], "description", sstate->entries);
1778 if (e->description == NULL) {
1779 e->description = "";
1782 sstate->num_entries += 1;
1783 if (sstate->num_entries >= num_users) {
1788 search->private_data = sstate;
1789 search->next_entry = pdb_ads_next_entry;
1790 search->search_end = pdb_ads_search_end;
1795 static bool pdb_ads_search_users(struct pdb_methods *m,
1796 struct pdb_search *search,
1799 struct pdb_ads_search_state *sstate;
1802 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1806 sstate->acct_flags = acct_flags;
1810 static bool pdb_ads_search_groups(struct pdb_methods *m,
1811 struct pdb_search *search)
1813 struct pdb_ads_search_state *sstate;
1817 filter = talloc_asprintf(talloc_tos(),
1818 "(&(grouptype=%d)(objectclass=group))",
1819 GTYPE_SECURITY_GLOBAL_GROUP);
1820 if (filter == NULL) {
1823 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1824 TALLOC_FREE(filter);
1828 sstate->acct_flags = 0;
1832 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1833 struct pdb_search *search,
1836 struct pdb_ads_search_state *sstate;
1840 filter = talloc_asprintf(
1841 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1842 sid_check_is_builtin(sid)
1843 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1844 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1846 if (filter == NULL) {
1849 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1850 TALLOC_FREE(filter);
1854 sstate->acct_flags = 0;
1858 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1864 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1867 struct pdb_ads_state *state = talloc_get_type_abort(
1868 m->private_data, struct pdb_ads_state);
1869 sid_compose(sid, &state->domainsid, uid);
1873 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1876 struct pdb_ads_state *state = talloc_get_type_abort(
1877 m->private_data, struct pdb_ads_state);
1878 sid_compose(sid, &state->domainsid, gid);
1882 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1883 union unid_t *id, enum lsa_SidType *type)
1885 struct pdb_ads_state *state = talloc_get_type_abort(
1886 m->private_data, struct pdb_ads_state);
1887 struct tldap_message **msg;
1893 * This is a big, big hack: Just hard-code the rid as uid/gid.
1896 sid_peek_rid(sid, &rid);
1898 sidstr = sid_binstring(talloc_tos(), sid);
1899 if (sidstr == NULL) {
1903 rc = pdb_ads_search_fmt(
1904 state, state->domaindn, TLDAP_SCOPE_SUB,
1905 NULL, 0, 0, talloc_tos(), &msg,
1906 "(&(objectsid=%s)(objectclass=user))", sidstr);
1907 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1909 *type = SID_NAME_USER;
1910 TALLOC_FREE(sidstr);
1914 rc = pdb_ads_search_fmt(
1915 state, state->domaindn, TLDAP_SCOPE_SUB,
1916 NULL, 0, 0, talloc_tos(), &msg,
1917 "(&(objectsid=%s)(objectclass=group))", sidstr);
1918 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1920 *type = SID_NAME_DOM_GRP;
1921 TALLOC_FREE(sidstr);
1925 TALLOC_FREE(sidstr);
1929 static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
1931 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
1934 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1939 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1940 const char *domain, char** pwd,
1942 time_t *pass_last_set_time)
1947 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1948 const char* domain, const char* pwd,
1954 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1960 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1961 TALLOC_CTX *mem_ctx,
1962 uint32 *num_domains,
1963 struct trustdom_info ***domains)
1965 return NT_STATUS_NOT_IMPLEMENTED;
1968 static void pdb_ads_init_methods(struct pdb_methods *m)
1971 m->get_domain_info = pdb_ads_get_domain_info;
1972 m->getsampwnam = pdb_ads_getsampwnam;
1973 m->getsampwsid = pdb_ads_getsampwsid;
1974 m->create_user = pdb_ads_create_user;
1975 m->delete_user = pdb_ads_delete_user;
1976 m->add_sam_account = pdb_ads_add_sam_account;
1977 m->update_sam_account = pdb_ads_update_sam_account;
1978 m->delete_sam_account = pdb_ads_delete_sam_account;
1979 m->rename_sam_account = pdb_ads_rename_sam_account;
1980 m->update_login_attempts = pdb_ads_update_login_attempts;
1981 m->getgrsid = pdb_ads_getgrsid;
1982 m->getgrgid = pdb_ads_getgrgid;
1983 m->getgrnam = pdb_ads_getgrnam;
1984 m->create_dom_group = pdb_ads_create_dom_group;
1985 m->delete_dom_group = pdb_ads_delete_dom_group;
1986 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1987 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1988 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1989 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1990 m->enum_group_members = pdb_ads_enum_group_members;
1991 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1992 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1993 m->add_groupmem = pdb_ads_add_groupmem;
1994 m->del_groupmem = pdb_ads_del_groupmem;
1995 m->create_alias = pdb_ads_create_alias;
1996 m->delete_alias = pdb_ads_delete_alias;
1997 m->get_aliasinfo = pdb_default_get_aliasinfo;
1998 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1999 m->add_aliasmem = pdb_ads_add_aliasmem;
2000 m->del_aliasmem = pdb_ads_del_aliasmem;
2001 m->enum_aliasmem = pdb_ads_enum_aliasmem;
2002 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
2003 m->lookup_rids = pdb_ads_lookup_rids;
2004 m->lookup_names = pdb_ads_lookup_names;
2005 m->get_account_policy = pdb_ads_get_account_policy;
2006 m->set_account_policy = pdb_ads_set_account_policy;
2007 m->get_seq_num = pdb_ads_get_seq_num;
2008 m->search_users = pdb_ads_search_users;
2009 m->search_groups = pdb_ads_search_groups;
2010 m->search_aliases = pdb_ads_search_aliases;
2011 m->uid_to_rid = pdb_ads_uid_to_rid;
2012 m->uid_to_sid = pdb_ads_uid_to_sid;
2013 m->gid_to_sid = pdb_ads_gid_to_sid;
2014 m->sid_to_id = pdb_ads_sid_to_id;
2015 m->capabilities = pdb_ads_capabilities;
2016 m->new_rid = pdb_ads_new_rid;
2017 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2018 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2019 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2020 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2023 static void free_private_data(void **vp)
2025 struct pdb_ads_state *state = talloc_get_type_abort(
2026 *vp, struct pdb_ads_state);
2028 TALLOC_FREE(state->ld);
2033 this is used to catch debug messages from events
2035 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2036 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
2038 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2039 const char *fmt, va_list ap)
2041 int samba_level = -1;
2044 case TLDAP_DEBUG_FATAL:
2047 case TLDAP_DEBUG_ERROR:
2050 case TLDAP_DEBUG_WARNING:
2053 case TLDAP_DEBUG_TRACE:
2058 if (vasprintf(&s, fmt, ap) == -1) {
2061 DEBUG(samba_level, ("tldap: %s", s));
2065 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2070 if (tldap_connection_ok(state->ld)) {
2073 TALLOC_FREE(state->ld);
2075 status = open_socket_out(
2076 (struct sockaddr_storage *)(void *)&state->socket_address,
2078 if (!NT_STATUS_IS_OK(status)) {
2079 DEBUG(10, ("Could not connect to %s: %s\n",
2080 state->socket_address.sun_path, nt_errstr(status)));
2084 set_blocking(fd, false);
2086 state->ld = tldap_context_create(state, fd);
2087 if (state->ld == NULL) {
2091 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2096 int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2097 int scope, const char *attrs[], int num_attrs,
2099 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2100 const char *fmt, ...)
2102 struct tldap_context *ld;
2106 ld = pdb_ads_ld(state);
2108 return TLDAP_SERVER_DOWN;
2112 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2113 mem_ctx, res, fmt, ap);
2116 if (ret != TLDAP_SERVER_DOWN) {
2121 ld = pdb_ads_ld(state);
2123 return TLDAP_SERVER_DOWN;
2127 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2128 mem_ctx, res, fmt, ap);
2133 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2134 const char *location)
2136 const char *rootdse_attrs[2] = {
2137 "defaultNamingContext", "configurationNamingContext" };
2138 const char *domain_attrs[1] = { "objectSid" };
2139 const char *ncname_attrs[1] = { "netbiosname" };
2140 struct tldap_message **rootdse, **domain, **ncname;
2141 TALLOC_CTX *frame = talloc_stackframe();
2146 ZERO_STRUCT(state->socket_address);
2147 state->socket_address.sun_family = AF_UNIX;
2148 strncpy(state->socket_address.sun_path, location,
2149 sizeof(state->socket_address.sun_path) - 1);
2151 rc = pdb_ads_search_fmt(
2152 state, "", TLDAP_SCOPE_BASE,
2153 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
2154 talloc_tos(), &rootdse, "(objectclass=*)");
2155 if (rc != TLDAP_SUCCESS) {
2156 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2157 tldap_errstr(debug_ctx(), state->ld, rc)));
2158 status = NT_STATUS_LDAP(rc);
2161 if (talloc_array_length(rootdse) != 1) {
2162 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2166 state->domaindn = tldap_talloc_single_attribute(
2167 rootdse[0], "defaultNamingContext", state);
2168 if (state->domaindn == NULL) {
2169 DEBUG(10, ("Could not get defaultNamingContext\n"));
2170 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2173 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2175 state->configdn = tldap_talloc_single_attribute(
2176 rootdse[0], "configurationNamingContext", state);
2177 if (state->domaindn == NULL) {
2178 DEBUG(10, ("Could not get configurationNamingContext\n"));
2179 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2182 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2185 * Figure out our domain's SID
2187 rc = pdb_ads_search_fmt(
2188 state, state->domaindn, TLDAP_SCOPE_BASE,
2189 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2190 talloc_tos(), &domain, "(objectclass=*)");
2191 if (rc != TLDAP_SUCCESS) {
2192 DEBUG(10, ("Could not retrieve domain: %s\n",
2193 tldap_errstr(debug_ctx(), state->ld, rc)));
2194 status = NT_STATUS_LDAP(rc);
2198 num_domains = talloc_array_length(domain);
2199 if (num_domains != 1) {
2200 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2201 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2204 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2205 DEBUG(10, ("Could not retrieve domain SID\n"));
2206 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2209 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2212 * Figure out our domain's short name
2214 rc = pdb_ads_search_fmt(
2215 state, state->configdn, TLDAP_SCOPE_SUB,
2216 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2217 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2218 if (rc != TLDAP_SUCCESS) {
2219 DEBUG(10, ("Could not retrieve ncname: %s\n",
2220 tldap_errstr(debug_ctx(), state->ld, rc)));
2221 status = NT_STATUS_LDAP(rc);
2224 if (talloc_array_length(ncname) != 1) {
2225 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2229 state->netbiosname = tldap_talloc_single_attribute(
2230 ncname[0], "netbiosname", state);
2231 if (state->netbiosname == NULL) {
2232 DEBUG(10, ("Could not get netbiosname\n"));
2233 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2236 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2238 if (!strequal(lp_workgroup(), state->netbiosname)) {
2239 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2240 state->netbiosname, lp_workgroup()));
2241 status = NT_STATUS_NO_SUCH_DOMAIN;
2245 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2247 status = NT_STATUS_OK;
2253 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2254 const char *location)
2256 struct pdb_methods *m;
2257 struct pdb_ads_state *state;
2261 m = talloc(talloc_autofree_context(), struct pdb_methods);
2263 return NT_STATUS_NO_MEMORY;
2265 state = talloc_zero(m, struct pdb_ads_state);
2266 if (state == NULL) {
2269 m->private_data = state;
2270 m->free_private_data = free_private_data;
2271 pdb_ads_init_methods(m);
2273 if (location == NULL) {
2274 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2278 if (location == NULL) {
2282 status = pdb_ads_connect(state, location);
2283 if (!NT_STATUS_IS_OK(status)) {
2284 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2289 return NT_STATUS_OK;
2291 status = NT_STATUS_NO_MEMORY;
2297 NTSTATUS pdb_ads_init(void);
2298 NTSTATUS pdb_ads_init(void)
2300 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",