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 samu *pdb_ads_init_guest(TALLOC_CTX *mem_ctx,
73 struct pdb_methods *m)
75 struct pdb_ads_state *state = talloc_get_type_abort(
76 m->private_data, struct pdb_ads_state);
77 struct dom_sid guest_sid;
81 sid_compose(&guest_sid, &state->domainsid, DOMAIN_USER_RID_GUEST);
83 guest = samu_new(mem_ctx);
88 status = pdb_ads_getsampwsid(m, guest, &guest_sid);
89 if (!NT_STATUS_IS_OK(status)) {
90 DEBUG(10, ("Could not init guest account: %s\n",
98 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
99 struct pdb_methods *m, struct samu *sam)
101 struct pdb_ads_samu_private *result;
104 result = (struct pdb_ads_samu_private *)
105 pdb_get_backend_private_data(sam, m);
107 if (result != NULL) {
108 return talloc_get_type_abort(
109 result, struct pdb_ads_samu_private);
113 * This is now a weirdness of the passdb API. For the guest user we
114 * are not asked first.
116 sid_peek_rid(pdb_get_user_sid(sam), &rid);
118 if (rid == DOMAIN_USER_RID_GUEST) {
119 struct samu *guest = pdb_ads_init_guest(talloc_tos(), m);
124 result = talloc_get_type_abort(
125 pdb_get_backend_private_data(guest, m),
126 struct pdb_ads_samu_private);
127 pdb_set_backend_private_data(
128 sam, talloc_move(sam, &result), NULL, m, PDB_SET);
130 return talloc_get_type_abort(
131 pdb_get_backend_private_data(sam, m),
132 struct pdb_ads_samu_private);
138 static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m,
140 struct tldap_message *entry)
142 struct pdb_ads_state *state = talloc_get_type_abort(
143 m->private_data, struct pdb_ads_state);
144 TALLOC_CTX *frame = talloc_stackframe();
145 struct pdb_ads_samu_private *priv;
146 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
153 priv = talloc(sam, struct pdb_ads_samu_private);
155 return NT_STATUS_NO_MEMORY;
157 if (!tldap_entry_dn(entry, &priv->dn)) {
159 return NT_STATUS_INTERNAL_DB_CORRUPTION;
162 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
164 DEBUG(10, ("no samAccountName\n"));
167 pdb_set_username(sam, str, PDB_SET);
169 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
170 pdb_set_logon_time(sam, tmp_time, PDB_SET);
172 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
173 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
175 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
176 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
178 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
179 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
182 str = tldap_talloc_single_attribute(entry, "displayName",
185 pdb_set_fullname(sam, str, PDB_SET);
188 str = tldap_talloc_single_attribute(entry, "homeDirectory",
191 pdb_set_homedir(sam, str, PDB_SET);
194 str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
196 pdb_set_dir_drive(sam, str, PDB_SET);
199 str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
201 pdb_set_logon_script(sam, str, PDB_SET);
204 str = tldap_talloc_single_attribute(entry, "profilePath",
207 pdb_set_profile_path(sam, str, PDB_SET);
210 str = tldap_talloc_single_attribute(entry, "profilePath",
213 pdb_set_profile_path(sam, str, PDB_SET);
216 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
217 DEBUG(10, ("Could not pull SID\n"));
220 pdb_set_user_sid(sam, &sid, PDB_SET);
222 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
223 DEBUG(10, ("Could not pull userAccountControl\n"));
226 pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET);
228 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
229 if (blob.length != NT_HASH_LEN) {
230 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
231 (int)blob.length, NT_HASH_LEN));
234 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
237 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
238 if (blob.length != LM_HASH_LEN) {
239 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
240 (int)blob.length, LM_HASH_LEN));
243 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
246 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
247 sid_compose(&sid, &state->domainsid, n);
248 pdb_set_group_sid(sam, &sid, PDB_SET);
252 priv->ldapmsg = talloc_move(priv, &entry);
253 pdb_set_backend_private_data(sam, priv, NULL, m, PDB_SET);
255 status = NT_STATUS_OK;
261 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
262 struct tldap_message *existing,
264 int *pnum_mods, struct tldap_mod **pmods,
270 /* TODO: All fields :-) */
272 ret &= tldap_make_mod_fmt(
273 existing, mem_ctx, pnum_mods, pmods, "displayName",
274 "%s", pdb_get_fullname(sam));
276 blob = data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN);
277 if (blob.data != NULL) {
278 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
279 "unicodePwd", 1, &blob);
282 blob = data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN);
283 if (blob.data != NULL) {
284 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
285 "dBCSPwd", 1, &blob);
288 ret &= tldap_make_mod_fmt(
289 existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
290 "%d", ads_acb2uf(pdb_get_acct_ctrl(sam)));
292 ret &= tldap_make_mod_fmt(
293 existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
294 "%s", pdb_get_homedir(sam));
296 ret &= tldap_make_mod_fmt(
297 existing, mem_ctx, pnum_mods, pmods, "homeDrive",
298 "%s", pdb_get_dir_drive(sam));
300 ret &= tldap_make_mod_fmt(
301 existing, mem_ctx, pnum_mods, pmods, "scriptPath",
302 "%s", pdb_get_logon_script(sam));
304 ret &= tldap_make_mod_fmt(
305 existing, mem_ctx, pnum_mods, pmods, "profilePath",
306 "%s", pdb_get_profile_path(sam));
311 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
312 struct pdb_ads_state *state,
313 struct samu *sam_acct,
316 const char * attrs[] = {
317 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
318 "sAMAccountName", "displayName", "homeDirectory",
319 "homeDrive", "scriptPath", "profilePath", "description",
320 "userWorkstations", "comment", "userParameters", "objectSid",
321 "primaryGroupID", "userAccountControl", "logonHours",
322 "badPwdCount", "logonCount", "countryCode", "codePage",
323 "unicodePwd", "dBCSPwd" };
324 struct tldap_message **users;
327 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
328 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
329 &users, "%s", filter);
330 if (rc != TLDAP_SUCCESS) {
331 DEBUG(10, ("ldap_search failed %s\n",
332 tldap_errstr(debug_ctx(), state->ld, rc)));
333 return NT_STATUS_LDAP(rc);
336 count = talloc_array_length(users);
338 DEBUG(10, ("Expected 1 user, got %d\n", count));
339 return NT_STATUS_INTERNAL_DB_CORRUPTION;
342 return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]);
345 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
346 struct samu *sam_acct,
347 const char *username)
349 struct pdb_ads_state *state = talloc_get_type_abort(
350 m->private_data, struct pdb_ads_state);
353 filter = talloc_asprintf(
354 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
356 NT_STATUS_HAVE_NO_MEMORY(filter);
358 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
361 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
362 struct samu *sam_acct,
365 struct pdb_ads_state *state = talloc_get_type_abort(
366 m->private_data, struct pdb_ads_state);
367 char *sidstr, *filter;
369 sidstr = sid_binstring(talloc_tos(), sid);
370 NT_STATUS_HAVE_NO_MEMORY(sidstr);
372 filter = talloc_asprintf(
373 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
375 NT_STATUS_HAVE_NO_MEMORY(filter);
377 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
380 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
382 const char *name, uint32 acct_flags,
385 struct pdb_ads_state *state = talloc_get_type_abort(
386 m->private_data, struct pdb_ads_state);
387 struct tldap_context *ld;
388 const char *attrs[1] = { "objectSid" };
389 struct tldap_mod *mods = NULL;
391 struct tldap_message **user;
397 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
400 return NT_STATUS_NO_MEMORY;
403 ld = pdb_ads_ld(state);
405 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
408 /* TODO: Create machines etc */
411 ok &= tldap_make_mod_fmt(
412 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
413 ok &= tldap_make_mod_fmt(
414 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
417 return NT_STATUS_NO_MEMORY;
421 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
422 if (rc != TLDAP_SUCCESS) {
423 DEBUG(10, ("ldap_add failed %s\n",
424 tldap_errstr(debug_ctx(), ld, rc)));
426 return NT_STATUS_LDAP(rc);
429 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
430 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
432 "(&(objectclass=user)(samaccountname=%s))",
434 if (rc != TLDAP_SUCCESS) {
435 DEBUG(10, ("Could not find just created user %s: %s\n",
436 name, tldap_errstr(debug_ctx(), state->ld, rc)));
438 return NT_STATUS_LDAP(rc);
441 if (talloc_array_length(user) != 1) {
442 DEBUG(10, ("Got %d users, expected one\n",
443 (int)talloc_array_length(user)));
445 return NT_STATUS_LDAP(rc);
448 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
449 DEBUG(10, ("Could not fetch objectSid from user %s\n",
452 return NT_STATUS_INTERNAL_DB_CORRUPTION;
455 sid_peek_rid(&sid, rid);
460 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
464 struct pdb_ads_state *state = talloc_get_type_abort(
465 m->private_data, struct pdb_ads_state);
467 struct tldap_context *ld;
471 ld = pdb_ads_ld(state);
473 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
476 status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
478 if (!NT_STATUS_IS_OK(status)) {
482 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
484 if (rc != TLDAP_SUCCESS) {
485 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
486 tldap_errstr(debug_ctx(), ld, rc)));
487 return NT_STATUS_LDAP(rc);
492 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
493 struct samu *sampass)
495 return NT_STATUS_NOT_IMPLEMENTED;
498 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
501 struct pdb_ads_state *state = talloc_get_type_abort(
502 m->private_data, struct pdb_ads_state);
503 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
504 struct tldap_context *ld;
505 struct tldap_mod *mods = NULL;
506 int rc, num_mods = 0;
508 ld = pdb_ads_ld(state);
510 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
513 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
514 &num_mods, &mods, sam)) {
515 return NT_STATUS_NO_MEMORY;
519 /* Nothing to do, just return success */
523 rc = tldap_modify(ld, priv->dn, num_mods, mods, NULL, 0,
526 if (rc != TLDAP_SUCCESS) {
527 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
528 tldap_errstr(debug_ctx(), ld, rc)));
529 return NT_STATUS_LDAP(rc);
535 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
536 struct samu *username)
538 return NT_STATUS_NOT_IMPLEMENTED;
541 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
542 struct samu *oldname,
545 return NT_STATUS_NOT_IMPLEMENTED;
548 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
549 struct samu *sam_acct,
552 return NT_STATUS_NOT_IMPLEMENTED;
555 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
558 struct pdb_ads_state *state = talloc_get_type_abort(
559 m->private_data, struct pdb_ads_state);
560 const char *attrs[4] = { "objectSid", "description", "samAccountName",
563 struct tldap_message **group;
567 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
568 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
569 &group, "%s", filter);
570 if (rc != TLDAP_SUCCESS) {
571 DEBUG(10, ("ldap_search failed %s\n",
572 tldap_errstr(debug_ctx(), state->ld, rc)));
573 return NT_STATUS_LDAP(rc);
575 if (talloc_array_length(group) != 1) {
576 DEBUG(10, ("Expected 1 user, got %d\n",
577 (int)talloc_array_length(group)));
578 return NT_STATUS_INTERNAL_DB_CORRUPTION;
581 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
582 return NT_STATUS_INTERNAL_DB_CORRUPTION;
584 map->gid = pdb_ads_sid2gid(&map->sid);
586 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
587 return NT_STATUS_INTERNAL_DB_CORRUPTION;
590 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
591 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
592 map->sid_name_use = SID_NAME_ALIAS;
594 case GTYPE_SECURITY_GLOBAL_GROUP:
595 map->sid_name_use = SID_NAME_DOM_GRP;
598 return NT_STATUS_INTERNAL_DB_CORRUPTION;
601 str = tldap_talloc_single_attribute(group[0], "samAccountName",
604 return NT_STATUS_INTERNAL_DB_CORRUPTION;
606 fstrcpy(map->nt_name, str);
609 str = tldap_talloc_single_attribute(group[0], "description",
612 fstrcpy(map->comment, str);
615 map->comment[0] = '\0';
622 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
628 filter = talloc_asprintf(talloc_tos(),
629 "(&(objectsid=%s)(objectclass=group))",
630 sid_string_talloc(talloc_tos(), &sid));
631 if (filter == NULL) {
632 return NT_STATUS_NO_MEMORY;
635 status = pdb_ads_getgrfilter(m, map, filter);
640 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
644 pdb_ads_gid_to_sid(m, gid, &sid);
645 return pdb_ads_getgrsid(m, map, sid);
648 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
654 filter = talloc_asprintf(talloc_tos(),
655 "(&(samaccountname=%s)(objectclass=group))",
657 if (filter == NULL) {
658 return NT_STATUS_NO_MEMORY;
661 status = pdb_ads_getgrfilter(m, map, filter);
666 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
667 TALLOC_CTX *mem_ctx, const char *name,
670 TALLOC_CTX *frame = talloc_stackframe();
671 struct pdb_ads_state *state = talloc_get_type_abort(
672 m->private_data, struct pdb_ads_state);
673 struct tldap_context *ld;
674 const char *attrs[1] = { "objectSid" };
676 struct tldap_mod *mods = NULL;
677 struct tldap_message **alias;
683 ld = pdb_ads_ld(state);
685 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
688 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
692 return NT_STATUS_NO_MEMORY;
695 ok &= tldap_make_mod_fmt(
696 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
698 ok &= tldap_make_mod_fmt(
699 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
700 ok &= tldap_make_mod_fmt(
701 NULL, talloc_tos(), &num_mods, &mods, "groupType",
702 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
706 return NT_STATUS_NO_MEMORY;
709 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
710 if (rc != TLDAP_SUCCESS) {
711 DEBUG(10, ("ldap_add failed %s\n",
712 tldap_errstr(debug_ctx(), state->ld, rc)));
714 return NT_STATUS_LDAP(rc);
717 rc = pdb_ads_search_fmt(
718 state, state->domaindn, TLDAP_SCOPE_SUB,
719 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
720 "(&(objectclass=group)(samaccountname=%s))", name);
721 if (rc != TLDAP_SUCCESS) {
722 DEBUG(10, ("Could not find just created alias %s: %s\n",
723 name, tldap_errstr(debug_ctx(), state->ld, rc)));
725 return NT_STATUS_LDAP(rc);
728 if (talloc_array_length(alias) != 1) {
729 DEBUG(10, ("Got %d alias, expected one\n",
730 (int)talloc_array_length(alias)));
732 return NT_STATUS_LDAP(rc);
735 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
736 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
739 return NT_STATUS_INTERNAL_DB_CORRUPTION;
742 sid_peek_rid(&sid, rid);
747 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
748 TALLOC_CTX *mem_ctx, uint32 rid)
750 struct pdb_ads_state *state = talloc_get_type_abort(
751 m->private_data, struct pdb_ads_state);
752 struct tldap_context *ld;
755 struct tldap_message **msg;
759 sid_compose(&sid, &state->domainsid, rid);
761 sidstr = sid_binstring(talloc_tos(), &sid);
762 NT_STATUS_HAVE_NO_MEMORY(sidstr);
764 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
765 NULL, 0, 0, talloc_tos(), &msg,
766 ("(&(objectSid=%s)(objectClass=group))"),
769 if (rc != TLDAP_SUCCESS) {
770 DEBUG(10, ("ldap_search failed %s\n",
771 tldap_errstr(debug_ctx(), state->ld, rc)));
772 return NT_STATUS_LDAP(rc);
775 switch talloc_array_length(msg) {
777 return NT_STATUS_NO_SUCH_GROUP;
781 return NT_STATUS_INTERNAL_DB_CORRUPTION;
784 if (!tldap_entry_dn(msg[0], &dn)) {
786 return NT_STATUS_INTERNAL_DB_CORRUPTION;
789 ld = pdb_ads_ld(state);
792 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
795 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
797 if (rc != TLDAP_SUCCESS) {
798 DEBUG(10, ("ldap_delete failed: %s\n",
799 tldap_errstr(debug_ctx(), state->ld, rc)));
800 return NT_STATUS_LDAP(rc);
806 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
809 return NT_STATUS_NOT_IMPLEMENTED;
812 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
815 return NT_STATUS_NOT_IMPLEMENTED;
818 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
821 return NT_STATUS_NOT_IMPLEMENTED;
824 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
826 enum lsa_SidType sid_name_use,
828 size_t *p_num_entries,
831 return NT_STATUS_NOT_IMPLEMENTED;
834 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
836 const DOM_SID *group,
838 size_t *pnum_members)
840 struct pdb_ads_state *state = talloc_get_type_abort(
841 m->private_data, struct pdb_ads_state);
842 const char *attrs[1] = { "member" };
844 struct tldap_message **msg;
845 int i, rc, num_members;
849 sidstr = sid_binstring(talloc_tos(), group);
850 NT_STATUS_HAVE_NO_MEMORY(sidstr);
852 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
853 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
854 &msg, "(objectsid=%s)", sidstr);
856 if (rc != TLDAP_SUCCESS) {
857 DEBUG(10, ("ldap_search failed %s\n",
858 tldap_errstr(debug_ctx(), state->ld, rc)));
859 return NT_STATUS_LDAP(rc);
861 switch talloc_array_length(msg) {
863 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
868 return NT_STATUS_INTERNAL_DB_CORRUPTION;
872 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
873 return NT_STATUS_INTERNAL_DB_CORRUPTION;
876 members = talloc_array(mem_ctx, uint32_t, num_members);
877 if (members == NULL) {
878 return NT_STATUS_NO_MEMORY;
881 for (i=0; i<num_members; i++) {
883 if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
884 || !sid_peek_rid(&sid, &members[i])) {
885 TALLOC_FREE(members);
886 return NT_STATUS_INTERNAL_DB_CORRUPTION;
891 *pnum_members = num_members;
895 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
900 size_t *p_num_groups)
902 struct pdb_ads_state *state = talloc_get_type_abort(
903 m->private_data, struct pdb_ads_state);
904 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
906 const char *attrs[1] = { "objectSid" };
907 struct tldap_message **groups;
910 struct dom_sid *group_sids;
913 rc = pdb_ads_search_fmt(
914 state, state->domaindn, TLDAP_SCOPE_SUB,
915 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
916 "(&(member=%s)(grouptype=%d)(objectclass=group))",
917 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
918 if (rc != TLDAP_SUCCESS) {
919 DEBUG(10, ("ldap_search failed %s\n",
920 tldap_errstr(debug_ctx(), state->ld, rc)));
921 return NT_STATUS_LDAP(rc);
924 count = talloc_array_length(groups);
926 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
927 if (group_sids == NULL) {
928 return NT_STATUS_NO_MEMORY;
930 gids = talloc_array(mem_ctx, gid_t, count);
932 TALLOC_FREE(group_sids);
933 return NT_STATUS_NO_MEMORY;
937 for (i=0; i<count; i++) {
938 if (!tldap_pull_binsid(groups[i], "objectSid",
939 &group_sids[num_groups])) {
942 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
945 if (num_groups == count) {
950 *pp_sids = group_sids;
952 *p_num_groups = num_groups;
956 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
960 return NT_STATUS_NOT_IMPLEMENTED;
963 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
965 uint32 grouprid, uint32 memberrid,
968 struct pdb_ads_state *state = talloc_get_type_abort(
969 m->private_data, struct pdb_ads_state);
970 TALLOC_CTX *frame = talloc_stackframe();
971 struct tldap_context *ld;
972 struct dom_sid groupsid, membersid;
973 char *groupdn, *memberdn;
974 struct tldap_mod *mods;
978 ld = pdb_ads_ld(state);
980 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
983 sid_compose(&groupsid, &state->domainsid, grouprid);
984 sid_compose(&membersid, &state->domainsid, memberrid);
986 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
987 if (!NT_STATUS_IS_OK(status)) {
989 return NT_STATUS_NO_SUCH_GROUP;
991 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
992 if (!NT_STATUS_IS_OK(status)) {
994 return NT_STATUS_NO_SUCH_USER;
999 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1000 "member", memberdn)) {
1002 return NT_STATUS_NO_MEMORY;
1005 rc = tldap_modify(ld, groupdn, 1, mods, NULL, 0, NULL, 0);
1007 if (rc != TLDAP_SUCCESS) {
1008 DEBUG(10, ("ldap_modify failed: %s\n",
1009 tldap_errstr(debug_ctx(), state->ld, rc)));
1010 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1011 return NT_STATUS_MEMBER_IN_GROUP;
1013 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1014 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1016 return NT_STATUS_LDAP(rc);
1019 return NT_STATUS_OK;
1022 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
1023 TALLOC_CTX *mem_ctx,
1024 uint32 group_rid, uint32 member_rid)
1026 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1030 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
1031 TALLOC_CTX *mem_ctx,
1032 uint32 group_rid, uint32 member_rid)
1034 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1038 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
1039 const char *name, uint32 *rid)
1041 TALLOC_CTX *frame = talloc_stackframe();
1042 struct pdb_ads_state *state = talloc_get_type_abort(
1043 m->private_data, struct pdb_ads_state);
1044 struct tldap_context *ld;
1045 const char *attrs[1] = { "objectSid" };
1047 struct tldap_mod *mods = NULL;
1048 struct tldap_message **alias;
1054 ld = pdb_ads_ld(state);
1056 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1059 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1063 return NT_STATUS_NO_MEMORY;
1066 ok &= tldap_make_mod_fmt(
1067 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
1069 ok &= tldap_make_mod_fmt(
1070 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
1071 ok &= tldap_make_mod_fmt(
1072 NULL, talloc_tos(), &num_mods, &mods, "groupType",
1073 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1077 return NT_STATUS_NO_MEMORY;
1080 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1081 if (rc != TLDAP_SUCCESS) {
1082 DEBUG(10, ("ldap_add failed %s\n",
1083 tldap_errstr(debug_ctx(), state->ld, rc)));
1085 return NT_STATUS_LDAP(rc);
1088 rc = pdb_ads_search_fmt(
1089 state, state->domaindn, TLDAP_SCOPE_SUB,
1090 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1091 "(&(objectclass=group)(samaccountname=%s))", name);
1092 if (rc != TLDAP_SUCCESS) {
1093 DEBUG(10, ("Could not find just created alias %s: %s\n",
1094 name, tldap_errstr(debug_ctx(), state->ld, rc)));
1096 return NT_STATUS_LDAP(rc);
1099 if (talloc_array_length(alias) != 1) {
1100 DEBUG(10, ("Got %d alias, expected one\n",
1101 (int)talloc_array_length(alias)));
1103 return NT_STATUS_LDAP(rc);
1106 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1107 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1110 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1113 sid_peek_rid(&sid, rid);
1115 return NT_STATUS_OK;
1118 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1121 struct pdb_ads_state *state = talloc_get_type_abort(
1122 m->private_data, struct pdb_ads_state);
1123 struct tldap_context *ld;
1124 struct tldap_message **alias;
1128 ld = pdb_ads_ld(state);
1130 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1133 sidstr = sid_binstring(talloc_tos(), sid);
1134 if (sidstr == NULL) {
1135 return NT_STATUS_NO_MEMORY;
1138 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1139 NULL, 0, 0, talloc_tos(), &alias,
1140 "(&(objectSid=%s)(objectclass=group)"
1141 "(|(grouptype=%d)(grouptype=%d)))",
1142 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1143 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1144 TALLOC_FREE(sidstr);
1145 if (rc != TLDAP_SUCCESS) {
1146 DEBUG(10, ("ldap_search failed: %s\n",
1147 tldap_errstr(debug_ctx(), state->ld, rc)));
1149 return NT_STATUS_LDAP(rc);
1151 if (talloc_array_length(alias) != 1) {
1152 DEBUG(10, ("Expected 1 alias, got %d\n",
1153 (int)talloc_array_length(alias)));
1154 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1156 if (!tldap_entry_dn(alias[0], &dn)) {
1157 DEBUG(10, ("Could not get DN for alias %s\n",
1158 sid_string_dbg(sid)));
1159 return NT_STATUS_INTERNAL_ERROR;
1162 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
1163 if (rc != TLDAP_SUCCESS) {
1164 DEBUG(10, ("ldap_delete failed: %s\n",
1165 tldap_errstr(debug_ctx(), state->ld, rc)));
1167 return NT_STATUS_LDAP(rc);
1170 return NT_STATUS_OK;
1173 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1175 struct acct_info *info)
1177 struct pdb_ads_state *state = talloc_get_type_abort(
1178 m->private_data, struct pdb_ads_state);
1179 struct tldap_context *ld;
1180 const char *attrs[3] = { "objectSid", "description",
1182 struct tldap_message **msg;
1185 struct tldap_mod *mods;
1189 ld = pdb_ads_ld(state);
1191 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1194 sidstr = sid_binstring(talloc_tos(), sid);
1195 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1197 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1198 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1199 &msg, "(&(objectSid=%s)(objectclass=group)"
1200 "(|(grouptype=%d)(grouptype=%d)))",
1201 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1202 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1203 TALLOC_FREE(sidstr);
1204 if (rc != TLDAP_SUCCESS) {
1205 DEBUG(10, ("ldap_search failed %s\n",
1206 tldap_errstr(debug_ctx(), state->ld, rc)));
1207 return NT_STATUS_LDAP(rc);
1209 switch talloc_array_length(msg) {
1211 return NT_STATUS_NO_SUCH_ALIAS;
1215 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1218 if (!tldap_entry_dn(msg[0], &dn)) {
1220 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1227 ok &= tldap_make_mod_fmt(
1228 msg[0], msg, &num_mods, &mods, "description",
1229 "%s", info->acct_desc);
1230 ok &= tldap_make_mod_fmt(
1231 msg[0], msg, &num_mods, &mods, "samAccountName",
1232 "%s", info->acct_name);
1235 return NT_STATUS_NO_MEMORY;
1237 if (num_mods == 0) {
1240 return NT_STATUS_OK;
1243 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1245 if (rc != TLDAP_SUCCESS) {
1246 DEBUG(10, ("ldap_modify failed: %s\n",
1247 tldap_errstr(debug_ctx(), state->ld, rc)));
1248 return NT_STATUS_LDAP(rc);
1250 return NT_STATUS_OK;
1253 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1254 const struct dom_sid *sid,
1255 TALLOC_CTX *mem_ctx, char **pdn)
1257 struct tldap_message **msg;
1261 sidstr = sid_binstring(talloc_tos(), sid);
1262 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1264 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1265 NULL, 0, 0, talloc_tos(), &msg,
1266 "(objectsid=%s)", sidstr);
1267 TALLOC_FREE(sidstr);
1268 if (rc != TLDAP_SUCCESS) {
1269 DEBUG(10, ("ldap_search failed %s\n",
1270 tldap_errstr(debug_ctx(), state->ld, rc)));
1271 return NT_STATUS_LDAP(rc);
1274 switch talloc_array_length(msg) {
1276 return NT_STATUS_NOT_FOUND;
1280 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1283 if (!tldap_entry_dn(msg[0], &dn)) {
1284 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1287 dn = talloc_strdup(mem_ctx, dn);
1289 return NT_STATUS_NO_MEMORY;
1294 return NT_STATUS_OK;
1297 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1298 const DOM_SID *alias,
1299 const DOM_SID *member,
1302 struct pdb_ads_state *state = talloc_get_type_abort(
1303 m->private_data, struct pdb_ads_state);
1304 struct tldap_context *ld;
1305 TALLOC_CTX *frame = talloc_stackframe();
1306 struct tldap_mod *mods;
1308 char *aliasdn, *memberdn;
1311 ld = pdb_ads_ld(state);
1313 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1316 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1317 if (!NT_STATUS_IS_OK(status)) {
1318 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1319 sid_string_dbg(alias), nt_errstr(status)));
1321 return NT_STATUS_NO_SUCH_ALIAS;
1323 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1324 if (!NT_STATUS_IS_OK(status)) {
1325 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1326 sid_string_dbg(member), nt_errstr(status)));
1333 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1334 "member", memberdn)) {
1336 return NT_STATUS_NO_MEMORY;
1339 rc = tldap_modify(ld, aliasdn, 1, mods, NULL, 0, NULL, 0);
1341 if (rc != TLDAP_SUCCESS) {
1342 DEBUG(10, ("ldap_modify failed: %s\n",
1343 tldap_errstr(debug_ctx(), state->ld, rc)));
1344 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1345 return NT_STATUS_MEMBER_IN_ALIAS;
1347 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1348 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1350 return NT_STATUS_LDAP(rc);
1353 return NT_STATUS_OK;
1356 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1357 const DOM_SID *alias,
1358 const DOM_SID *member)
1360 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1363 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1364 const DOM_SID *alias,
1365 const DOM_SID *member)
1367 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1370 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
1371 struct dom_sid *psid)
1373 const char *attrs[1] = { "objectSid" };
1374 struct tldap_message **msg;
1380 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1381 dnblob->data, dnblob->length, &dn, &len,
1385 rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
1386 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1387 &msg, "(objectclass=*)");
1389 if (talloc_array_length(msg) != 1) {
1390 DEBUG(10, ("Got %d objects, expected one\n",
1391 (int)talloc_array_length(msg)));
1396 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1401 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1402 const DOM_SID *alias,
1403 TALLOC_CTX *mem_ctx,
1405 size_t *pnum_members)
1407 struct pdb_ads_state *state = talloc_get_type_abort(
1408 m->private_data, struct pdb_ads_state);
1409 const char *attrs[1] = { "member" };
1411 struct tldap_message **msg;
1412 int i, rc, num_members;
1414 struct dom_sid *members;
1416 sidstr = sid_binstring(talloc_tos(), alias);
1417 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1419 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1420 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1421 &msg, "(objectsid=%s)", sidstr);
1422 TALLOC_FREE(sidstr);
1423 if (rc != TLDAP_SUCCESS) {
1424 DEBUG(10, ("ldap_search failed %s\n",
1425 tldap_errstr(debug_ctx(), state->ld, rc)));
1426 return NT_STATUS_LDAP(rc);
1428 switch talloc_array_length(msg) {
1430 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1435 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1439 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1440 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1443 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1444 if (members == NULL) {
1445 return NT_STATUS_NO_MEMORY;
1448 for (i=0; i<num_members; i++) {
1449 if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
1450 TALLOC_FREE(members);
1451 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1455 *pmembers = members;
1456 *pnum_members = num_members;
1457 return NT_STATUS_OK;
1460 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1461 TALLOC_CTX *mem_ctx,
1462 const DOM_SID *domain_sid,
1463 const DOM_SID *members,
1465 uint32_t **palias_rids,
1466 size_t *pnum_alias_rids)
1468 struct pdb_ads_state *state = talloc_get_type_abort(
1469 m->private_data, struct pdb_ads_state);
1470 const char *attrs[1] = { "objectSid" };
1471 struct tldap_message **msg;
1472 uint32_t *alias_rids = NULL;
1473 size_t num_alias_rids = 0;
1475 bool got_members = false;
1480 * TODO: Get the filter right so that we only get the aliases from
1481 * either the SAM or BUILTIN
1484 filter = talloc_asprintf(talloc_tos(),
1485 "(&(|(grouptype=%d)(grouptype=%d))"
1486 "(objectclass=group)(|",
1487 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1488 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1489 if (filter == NULL) {
1490 return NT_STATUS_NO_MEMORY;
1493 for (i=0; i<num_members; i++) {
1496 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1497 if (!NT_STATUS_IS_OK(status)) {
1498 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1499 sid_string_dbg(&members[i]),
1500 nt_errstr(status)));
1503 filter = talloc_asprintf_append_buffer(
1504 filter, "(member=%s)", dn);
1506 if (filter == NULL) {
1507 return NT_STATUS_NO_MEMORY;
1516 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1517 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1518 &msg, "%s))", filter);
1519 TALLOC_FREE(filter);
1520 if (rc != TLDAP_SUCCESS) {
1521 DEBUG(10, ("tldap_search failed %s\n",
1522 tldap_errstr(debug_ctx(), state->ld, rc)));
1523 return NT_STATUS_LDAP(rc);
1526 count = talloc_array_length(msg);
1531 alias_rids = talloc_array(mem_ctx, uint32_t, count);
1532 if (alias_rids == NULL) {
1534 return NT_STATUS_NO_MEMORY;
1537 for (i=0; i<count; i++) {
1540 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1541 DEBUG(10, ("Could not pull SID for member %d\n", i));
1544 if (sid_peek_check_rid(domain_sid, &sid,
1545 &alias_rids[num_alias_rids])) {
1546 num_alias_rids += 1;
1551 *palias_rids = alias_rids;
1552 *pnum_alias_rids = 0;
1553 return NT_STATUS_OK;
1556 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1557 const DOM_SID *domain_sid,
1561 enum lsa_SidType *lsa_attrs)
1563 struct pdb_ads_state *state = talloc_get_type_abort(
1564 m->private_data, struct pdb_ads_state);
1565 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1568 if (num_rids == 0) {
1569 return NT_STATUS_NONE_MAPPED;
1574 for (i=0; i<num_rids; i++) {
1576 struct tldap_message **msg;
1581 lsa_attrs[i] = SID_NAME_UNKNOWN;
1583 sid_compose(&sid, domain_sid, rids[i]);
1585 sidstr = sid_binstring(talloc_tos(), &sid);
1586 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1588 rc = pdb_ads_search_fmt(state, state->domaindn,
1589 TLDAP_SCOPE_SUB, attrs,
1590 ARRAY_SIZE(attrs), 0, talloc_tos(),
1591 &msg, "(objectsid=%s)", sidstr);
1592 TALLOC_FREE(sidstr);
1593 if (rc != TLDAP_SUCCESS) {
1594 DEBUG(10, ("ldap_search failed %s\n",
1595 tldap_errstr(debug_ctx(), state->ld, rc)));
1599 switch talloc_array_length(msg) {
1601 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1606 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1609 names[i] = tldap_talloc_single_attribute(
1610 msg[0], "samAccountName", talloc_tos());
1611 if (names[i] == NULL) {
1612 DEBUG(10, ("no samAccountName\n"));
1615 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1616 DEBUG(10, ("no samAccountType"));
1619 lsa_attrs[i] = ads_atype_map(attr);
1623 if (num_mapped == 0) {
1624 return NT_STATUS_NONE_MAPPED;
1626 if (num_mapped < num_rids) {
1627 return STATUS_SOME_UNMAPPED;
1629 return NT_STATUS_OK;
1632 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1633 const DOM_SID *domain_sid,
1635 const char **pp_names,
1637 enum lsa_SidType *attrs)
1639 return NT_STATUS_NOT_IMPLEMENTED;
1642 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1643 int policy_index, uint32 *value)
1645 return account_policy_get(policy_index, value)
1646 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1649 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1650 int policy_index, uint32 value)
1652 return account_policy_set(policy_index, value)
1653 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1656 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1659 return NT_STATUS_NOT_IMPLEMENTED;
1662 struct pdb_ads_search_state {
1663 uint32_t acct_flags;
1664 struct samr_displayentry *entries;
1665 uint32_t num_entries;
1670 static bool pdb_ads_next_entry(struct pdb_search *search,
1671 struct samr_displayentry *entry)
1673 struct pdb_ads_search_state *state = talloc_get_type_abort(
1674 search->private_data, struct pdb_ads_search_state);
1676 if (state->current == state->num_entries) {
1680 entry->idx = state->entries[state->current].idx;
1681 entry->rid = state->entries[state->current].rid;
1682 entry->acct_flags = state->entries[state->current].acct_flags;
1684 entry->account_name = talloc_strdup(
1685 search, state->entries[state->current].account_name);
1686 entry->fullname = talloc_strdup(
1687 search, state->entries[state->current].fullname);
1688 entry->description = talloc_strdup(
1689 search, state->entries[state->current].description);
1691 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1692 || (entry->description == NULL)) {
1693 DEBUG(0, ("talloc_strdup failed\n"));
1697 state->current += 1;
1701 static void pdb_ads_search_end(struct pdb_search *search)
1703 struct pdb_ads_search_state *state = talloc_get_type_abort(
1704 search->private_data, struct pdb_ads_search_state);
1708 static bool pdb_ads_search_filter(struct pdb_methods *m,
1709 struct pdb_search *search,
1711 struct pdb_ads_search_state **pstate)
1713 struct pdb_ads_state *state = talloc_get_type_abort(
1714 m->private_data, struct pdb_ads_state);
1715 struct pdb_ads_search_state *sstate;
1716 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1717 "userAccountControl", "description" };
1718 struct tldap_message **users;
1719 int i, rc, num_users;
1721 sstate = talloc_zero(search, struct pdb_ads_search_state);
1722 if (sstate == NULL) {
1726 rc = pdb_ads_search_fmt(
1727 state, state->domaindn, TLDAP_SCOPE_SUB,
1728 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1730 if (rc != TLDAP_SUCCESS) {
1731 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1732 tldap_errstr(debug_ctx(), state->ld, rc)));
1736 num_users = talloc_array_length(users);
1738 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1740 if (sstate->entries == NULL) {
1741 DEBUG(10, ("talloc failed\n"));
1745 sstate->num_entries = 0;
1747 for (i=0; i<num_users; i++) {
1748 struct samr_displayentry *e;
1751 e = &sstate->entries[sstate->num_entries];
1753 e->idx = sstate->num_entries;
1754 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1755 DEBUG(10, ("Could not pull sid\n"));
1758 sid_peek_rid(&sid, &e->rid);
1759 e->acct_flags = ACB_NORMAL;
1760 e->account_name = tldap_talloc_single_attribute(
1761 users[i], "samAccountName", sstate->entries);
1762 if (e->account_name == NULL) {
1765 e->fullname = tldap_talloc_single_attribute(
1766 users[i], "displayName", sstate->entries);
1767 if (e->fullname == NULL) {
1770 e->description = tldap_talloc_single_attribute(
1771 users[i], "description", sstate->entries);
1772 if (e->description == NULL) {
1773 e->description = "";
1776 sstate->num_entries += 1;
1777 if (sstate->num_entries >= num_users) {
1782 search->private_data = sstate;
1783 search->next_entry = pdb_ads_next_entry;
1784 search->search_end = pdb_ads_search_end;
1789 static bool pdb_ads_search_users(struct pdb_methods *m,
1790 struct pdb_search *search,
1793 struct pdb_ads_search_state *sstate;
1796 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1800 sstate->acct_flags = acct_flags;
1804 static bool pdb_ads_search_groups(struct pdb_methods *m,
1805 struct pdb_search *search)
1807 struct pdb_ads_search_state *sstate;
1811 filter = talloc_asprintf(talloc_tos(),
1812 "(&(grouptype=%d)(objectclass=group))",
1813 GTYPE_SECURITY_GLOBAL_GROUP);
1814 if (filter == NULL) {
1817 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1818 TALLOC_FREE(filter);
1822 sstate->acct_flags = 0;
1826 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1827 struct pdb_search *search,
1830 struct pdb_ads_search_state *sstate;
1834 filter = talloc_asprintf(
1835 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1836 sid_check_is_builtin(sid)
1837 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1838 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1840 if (filter == NULL) {
1843 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1844 TALLOC_FREE(filter);
1848 sstate->acct_flags = 0;
1852 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1858 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1861 struct pdb_ads_state *state = talloc_get_type_abort(
1862 m->private_data, struct pdb_ads_state);
1863 sid_compose(sid, &state->domainsid, uid);
1867 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1870 struct pdb_ads_state *state = talloc_get_type_abort(
1871 m->private_data, struct pdb_ads_state);
1872 sid_compose(sid, &state->domainsid, gid);
1876 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1877 union unid_t *id, enum lsa_SidType *type)
1879 struct pdb_ads_state *state = talloc_get_type_abort(
1880 m->private_data, struct pdb_ads_state);
1881 struct tldap_message **msg;
1887 * This is a big, big hack: Just hard-code the rid as uid/gid.
1890 sid_peek_rid(sid, &rid);
1892 sidstr = sid_binstring(talloc_tos(), sid);
1893 if (sidstr == NULL) {
1897 rc = pdb_ads_search_fmt(
1898 state, state->domaindn, TLDAP_SCOPE_SUB,
1899 NULL, 0, 0, talloc_tos(), &msg,
1900 "(&(objectsid=%s)(objectclass=user))", sidstr);
1901 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1903 *type = SID_NAME_USER;
1904 TALLOC_FREE(sidstr);
1908 rc = pdb_ads_search_fmt(
1909 state, state->domaindn, TLDAP_SCOPE_SUB,
1910 NULL, 0, 0, talloc_tos(), &msg,
1911 "(&(objectsid=%s)(objectclass=group))", sidstr);
1912 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1914 *type = SID_NAME_DOM_GRP;
1915 TALLOC_FREE(sidstr);
1919 TALLOC_FREE(sidstr);
1923 static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
1925 return PDB_CAP_STORE_RIDS;
1928 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1933 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1934 const char *domain, char** pwd,
1936 time_t *pass_last_set_time)
1941 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1942 const char* domain, const char* pwd,
1948 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1954 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1955 TALLOC_CTX *mem_ctx,
1956 uint32 *num_domains,
1957 struct trustdom_info ***domains)
1959 return NT_STATUS_NOT_IMPLEMENTED;
1962 static void pdb_ads_init_methods(struct pdb_methods *m)
1965 m->getsampwnam = pdb_ads_getsampwnam;
1966 m->getsampwsid = pdb_ads_getsampwsid;
1967 m->create_user = pdb_ads_create_user;
1968 m->delete_user = pdb_ads_delete_user;
1969 m->add_sam_account = pdb_ads_add_sam_account;
1970 m->update_sam_account = pdb_ads_update_sam_account;
1971 m->delete_sam_account = pdb_ads_delete_sam_account;
1972 m->rename_sam_account = pdb_ads_rename_sam_account;
1973 m->update_login_attempts = pdb_ads_update_login_attempts;
1974 m->getgrsid = pdb_ads_getgrsid;
1975 m->getgrgid = pdb_ads_getgrgid;
1976 m->getgrnam = pdb_ads_getgrnam;
1977 m->create_dom_group = pdb_ads_create_dom_group;
1978 m->delete_dom_group = pdb_ads_delete_dom_group;
1979 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1980 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1981 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1982 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1983 m->enum_group_members = pdb_ads_enum_group_members;
1984 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1985 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1986 m->add_groupmem = pdb_ads_add_groupmem;
1987 m->del_groupmem = pdb_ads_del_groupmem;
1988 m->create_alias = pdb_ads_create_alias;
1989 m->delete_alias = pdb_ads_delete_alias;
1990 m->get_aliasinfo = pdb_default_get_aliasinfo;
1991 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1992 m->add_aliasmem = pdb_ads_add_aliasmem;
1993 m->del_aliasmem = pdb_ads_del_aliasmem;
1994 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1995 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1996 m->lookup_rids = pdb_ads_lookup_rids;
1997 m->lookup_names = pdb_ads_lookup_names;
1998 m->get_account_policy = pdb_ads_get_account_policy;
1999 m->set_account_policy = pdb_ads_set_account_policy;
2000 m->get_seq_num = pdb_ads_get_seq_num;
2001 m->search_users = pdb_ads_search_users;
2002 m->search_groups = pdb_ads_search_groups;
2003 m->search_aliases = pdb_ads_search_aliases;
2004 m->uid_to_rid = pdb_ads_uid_to_rid;
2005 m->uid_to_sid = pdb_ads_uid_to_sid;
2006 m->gid_to_sid = pdb_ads_gid_to_sid;
2007 m->sid_to_id = pdb_ads_sid_to_id;
2008 m->capabilities = pdb_ads_capabilities;
2009 m->new_rid = pdb_ads_new_rid;
2010 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2011 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2012 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2013 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2016 static void free_private_data(void **vp)
2018 struct pdb_ads_state *state = talloc_get_type_abort(
2019 *vp, struct pdb_ads_state);
2021 TALLOC_FREE(state->ld);
2026 this is used to catch debug messages from events
2028 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2029 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
2031 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2032 const char *fmt, va_list ap)
2034 int samba_level = -1;
2037 case TLDAP_DEBUG_FATAL:
2040 case TLDAP_DEBUG_ERROR:
2043 case TLDAP_DEBUG_WARNING:
2046 case TLDAP_DEBUG_TRACE:
2051 if (vasprintf(&s, fmt, ap) == -1) {
2054 DEBUG(samba_level, ("tldap: %s", s));
2058 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2063 if (tldap_connection_ok(state->ld)) {
2066 TALLOC_FREE(state->ld);
2068 status = open_socket_out(
2069 (struct sockaddr_storage *)(void *)&state->socket_address,
2071 if (!NT_STATUS_IS_OK(status)) {
2072 DEBUG(10, ("Could not connect to %s: %s\n",
2073 state->socket_address.sun_path, nt_errstr(status)));
2077 state->ld = tldap_context_create(state, fd);
2078 if (state->ld == NULL) {
2082 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2087 int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2088 int scope, const char *attrs[], int num_attrs,
2090 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2091 const char *fmt, ...)
2093 struct tldap_context *ld;
2097 ld = pdb_ads_ld(state);
2099 return TLDAP_SERVER_DOWN;
2103 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2104 mem_ctx, res, fmt, ap);
2107 if (ret != TLDAP_SERVER_DOWN) {
2112 ld = pdb_ads_ld(state);
2114 return TLDAP_SERVER_DOWN;
2118 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2119 mem_ctx, res, fmt, ap);
2124 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2125 const char *location)
2127 const char *rootdse_attrs[2] = {
2128 "defaultNamingContext", "configurationNamingContext" };
2129 const char *domain_attrs[1] = { "objectSid" };
2130 const char *ncname_attrs[1] = { "netbiosname" };
2131 struct tldap_message **rootdse, **domain, **ncname;
2132 TALLOC_CTX *frame = talloc_stackframe();
2137 ZERO_STRUCT(state->socket_address);
2138 state->socket_address.sun_family = AF_UNIX;
2139 strncpy(state->socket_address.sun_path, location,
2140 sizeof(state->socket_address.sun_path) - 1);
2142 rc = pdb_ads_search_fmt(
2143 state, "", TLDAP_SCOPE_BASE,
2144 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
2145 talloc_tos(), &rootdse, "(objectclass=*)");
2146 if (rc != TLDAP_SUCCESS) {
2147 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2148 tldap_errstr(debug_ctx(), state->ld, rc)));
2149 status = NT_STATUS_LDAP(rc);
2152 if (talloc_array_length(rootdse) != 1) {
2153 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2157 state->domaindn = tldap_talloc_single_attribute(
2158 rootdse[0], "defaultNamingContext", state);
2159 if (state->domaindn == NULL) {
2160 DEBUG(10, ("Could not get defaultNamingContext\n"));
2161 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2164 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2166 state->configdn = tldap_talloc_single_attribute(
2167 rootdse[0], "configurationNamingContext", state);
2168 if (state->domaindn == NULL) {
2169 DEBUG(10, ("Could not get configurationNamingContext\n"));
2170 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2173 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2176 * Figure out our domain's SID
2178 rc = pdb_ads_search_fmt(
2179 state, state->domaindn, TLDAP_SCOPE_BASE,
2180 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2181 talloc_tos(), &domain, "(objectclass=*)");
2182 if (rc != TLDAP_SUCCESS) {
2183 DEBUG(10, ("Could not retrieve domain: %s\n",
2184 tldap_errstr(debug_ctx(), state->ld, rc)));
2185 status = NT_STATUS_LDAP(rc);
2189 num_domains = talloc_array_length(domain);
2190 if (num_domains != 1) {
2191 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2192 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2195 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2196 DEBUG(10, ("Could not retrieve domain SID\n"));
2197 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2200 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2203 * Figure out our domain's short name
2205 rc = pdb_ads_search_fmt(
2206 state, state->configdn, TLDAP_SCOPE_SUB,
2207 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2208 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2209 if (rc != TLDAP_SUCCESS) {
2210 DEBUG(10, ("Could not retrieve ncname: %s\n",
2211 tldap_errstr(debug_ctx(), state->ld, rc)));
2212 status = NT_STATUS_LDAP(rc);
2215 if (talloc_array_length(ncname) != 1) {
2216 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2220 state->netbiosname = tldap_talloc_single_attribute(
2221 ncname[0], "netbiosname", state);
2222 if (state->netbiosname == NULL) {
2223 DEBUG(10, ("Could not get netbiosname\n"));
2224 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2227 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2229 if (!strequal(lp_workgroup(), state->netbiosname)) {
2230 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2231 state->netbiosname, lp_workgroup()));
2232 status = NT_STATUS_NO_SUCH_DOMAIN;
2236 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2238 status = NT_STATUS_OK;
2244 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2245 const char *location)
2247 struct pdb_methods *m;
2248 struct pdb_ads_state *state;
2252 m = talloc(talloc_autofree_context(), struct pdb_methods);
2254 return NT_STATUS_NO_MEMORY;
2256 state = talloc_zero(m, struct pdb_ads_state);
2257 if (state == NULL) {
2260 m->private_data = state;
2261 m->free_private_data = free_private_data;
2262 pdb_ads_init_methods(m);
2264 if (location == NULL) {
2265 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2269 if (location == NULL) {
2273 status = pdb_ads_connect(state, location);
2274 if (!NT_STATUS_IS_OK(status)) {
2275 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2280 return NT_STATUS_OK;
2282 status = NT_STATUS_NO_MEMORY;
2288 NTSTATUS pdb_ads_init(void);
2289 NTSTATUS pdb_ads_init(void)
2291 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",