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 tldap_context *ld;
24 struct dom_sid domainsid;
30 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
31 struct samu *sam_acct,
33 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
35 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
36 struct dom_sid *psid);
37 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
38 const struct dom_sid *sid,
39 TALLOC_CTX *mem_ctx, char **pdn);
41 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
46 if (!tldap_pull_uint64(msg, attr, &tmp)) {
49 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
53 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
56 sid_peek_rid(sid, &rid);
60 struct pdb_ads_samu_private {
62 struct tldap_message *ldapmsg;
65 static struct samu *pdb_ads_init_guest(TALLOC_CTX *mem_ctx,
66 struct pdb_methods *m)
68 struct pdb_ads_state *state = talloc_get_type_abort(
69 m->private_data, struct pdb_ads_state);
70 struct dom_sid guest_sid;
74 sid_compose(&guest_sid, &state->domainsid, DOMAIN_USER_RID_GUEST);
76 guest = samu_new(mem_ctx);
81 status = pdb_ads_getsampwsid(m, guest, &guest_sid);
82 if (!NT_STATUS_IS_OK(status)) {
83 DEBUG(10, ("Could not init guest account: %s\n",
91 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
92 struct pdb_methods *m, struct samu *sam)
94 struct pdb_ads_samu_private *result;
97 result = (struct pdb_ads_samu_private *)
98 pdb_get_backend_private_data(sam, m);
100 if (result != NULL) {
101 return talloc_get_type_abort(
102 result, struct pdb_ads_samu_private);
106 * This is now a weirdness of the passdb API. For the guest user we
107 * are not asked first.
109 sid_peek_rid(pdb_get_user_sid(sam), &rid);
111 if (rid == DOMAIN_USER_RID_GUEST) {
112 struct samu *guest = pdb_ads_init_guest(talloc_tos(), m);
117 result = talloc_get_type_abort(
118 pdb_get_backend_private_data(guest, m),
119 struct pdb_ads_samu_private);
120 pdb_set_backend_private_data(
121 sam, talloc_move(sam, &result), NULL, m, PDB_SET);
123 return talloc_get_type_abort(
124 pdb_get_backend_private_data(sam, m),
125 struct pdb_ads_samu_private);
131 static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m,
133 struct tldap_message *entry)
135 struct pdb_ads_state *state = talloc_get_type_abort(
136 m->private_data, struct pdb_ads_state);
137 TALLOC_CTX *frame = talloc_stackframe();
138 struct pdb_ads_samu_private *priv;
139 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
146 priv = talloc(sam, struct pdb_ads_samu_private);
148 return NT_STATUS_NO_MEMORY;
150 if (!tldap_entry_dn(entry, &priv->dn)) {
152 return NT_STATUS_INTERNAL_DB_CORRUPTION;
155 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
157 DEBUG(10, ("no samAccountName\n"));
160 pdb_set_username(sam, str, PDB_SET);
163 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
164 pdb_set_logon_time(sam, tmp_time, PDB_SET);
166 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
167 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
169 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
170 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
172 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
173 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
176 str = tldap_talloc_single_attribute(entry, "samAccoutName",
179 pdb_set_username(sam, str, 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,
269 /* TODO: All fields :-) */
271 ret &= tldap_make_mod_fmt(
272 existing, mem_ctx, pnum_mods, pmods, "displayName",
273 "%s", pdb_get_fullname(sam));
275 ret &= tldap_make_mod_blob(
276 existing, mem_ctx, pnum_mods, pmods, "unicodePwd",
277 data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN));
279 ret &= tldap_make_mod_blob(
280 existing, mem_ctx, pnum_mods, pmods, "dBCSPwd",
281 data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN));
286 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
287 struct pdb_ads_state *state,
288 struct samu *sam_acct,
291 const char * attrs[] = {
292 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
293 "sAMAccountName", "displayName", "homeDirectory",
294 "homeDrive", "scriptPath", "profilePath", "description",
295 "userWorkstations", "comment", "userParameters", "objectSid",
296 "primaryGroupID", "userAccountControl", "logonHours",
297 "badPwdCount", "logonCount", "countryCode", "codePage",
298 "unicodePwd", "dBCSPwd" };
299 struct tldap_message **users;
302 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
303 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
304 &users, "%s", filter);
305 if (rc != TLDAP_SUCCESS) {
306 DEBUG(10, ("ldap_search failed %s\n",
307 tldap_errstr(debug_ctx(), state->ld, rc)));
308 return NT_STATUS_LDAP(rc);
311 count = talloc_array_length(users);
313 DEBUG(10, ("Expected 1 user, got %d\n", count));
314 return NT_STATUS_INTERNAL_DB_CORRUPTION;
317 return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]);
320 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
321 struct samu *sam_acct,
322 const char *username)
324 struct pdb_ads_state *state = talloc_get_type_abort(
325 m->private_data, struct pdb_ads_state);
328 filter = talloc_asprintf(
329 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
331 NT_STATUS_HAVE_NO_MEMORY(filter);
333 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
336 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
337 struct samu *sam_acct,
340 struct pdb_ads_state *state = talloc_get_type_abort(
341 m->private_data, struct pdb_ads_state);
342 char *sidstr, *filter;
344 sidstr = sid_binstring(talloc_tos(), sid);
345 NT_STATUS_HAVE_NO_MEMORY(sidstr);
347 filter = talloc_asprintf(
348 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
350 NT_STATUS_HAVE_NO_MEMORY(filter);
352 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
355 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
357 const char *name, uint32 acct_flags,
360 struct pdb_ads_state *state = talloc_get_type_abort(
361 m->private_data, struct pdb_ads_state);
362 const char *attrs[1] = { "objectSid" };
363 struct tldap_mod *mods = NULL;
365 struct tldap_message **user;
371 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
374 return NT_STATUS_NO_MEMORY;
377 /* TODO: Create machines etc */
380 ok &= tldap_make_mod_fmt(
381 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
382 ok &= tldap_make_mod_fmt(
383 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
386 return NT_STATUS_NO_MEMORY;
389 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
390 if (rc != TLDAP_SUCCESS) {
391 DEBUG(10, ("ldap_add failed %s\n",
392 tldap_errstr(debug_ctx(), state->ld, rc)));
394 return NT_STATUS_LDAP(rc);
397 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
398 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &user,
399 "(&(objectclass=user)(samaccountname=%s))",
401 if (rc != TLDAP_SUCCESS) {
402 DEBUG(10, ("Could not find just created user %s: %s\n",
403 name, tldap_errstr(debug_ctx(), state->ld, rc)));
405 return NT_STATUS_LDAP(rc);
408 if (talloc_array_length(user) != 1) {
409 DEBUG(10, ("Got %d users, expected one\n",
410 (int)talloc_array_length(user)));
412 return NT_STATUS_LDAP(rc);
415 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
416 DEBUG(10, ("Could not fetch objectSid from user %s\n",
419 return NT_STATUS_INTERNAL_DB_CORRUPTION;
422 sid_peek_rid(&sid, rid);
427 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
431 struct pdb_ads_state *state = talloc_get_type_abort(
432 m->private_data, struct pdb_ads_state);
433 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
436 rc = tldap_delete(state->ld, priv->dn, NULL, NULL);
437 if (rc != TLDAP_SUCCESS) {
438 DEBUG(10, ("ldap_delete for %s failed: %s\n", priv->dn,
439 tldap_errstr(debug_ctx(), state->ld, rc)));
440 return NT_STATUS_LDAP(rc);
445 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
446 struct samu *sampass)
448 return NT_STATUS_NOT_IMPLEMENTED;
451 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
454 struct pdb_ads_state *state = talloc_get_type_abort(
455 m->private_data, struct pdb_ads_state);
456 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
457 struct tldap_mod *mods = NULL;
458 int rc, num_mods = 0;
460 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
461 &num_mods, &mods, sam)) {
462 return NT_STATUS_NO_MEMORY;
465 rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, NULL);
466 if (rc != TLDAP_SUCCESS) {
467 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
468 tldap_errstr(debug_ctx(), state->ld, rc)));
469 return NT_STATUS_LDAP(rc);
477 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
478 struct samu *username)
480 return NT_STATUS_NOT_IMPLEMENTED;
483 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
484 struct samu *oldname,
487 return NT_STATUS_NOT_IMPLEMENTED;
490 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
491 struct samu *sam_acct,
494 return NT_STATUS_NOT_IMPLEMENTED;
497 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
500 struct pdb_ads_state *state = talloc_get_type_abort(
501 m->private_data, struct pdb_ads_state);
502 const char *attrs[4] = { "objectSid", "description", "samAccountName",
505 struct tldap_message **group;
509 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
510 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
511 &group, "%s", filter);
512 if (rc != TLDAP_SUCCESS) {
513 DEBUG(10, ("ldap_search failed %s\n",
514 tldap_errstr(debug_ctx(), state->ld, rc)));
515 return NT_STATUS_LDAP(rc);
517 if (talloc_array_length(group) != 1) {
518 DEBUG(10, ("Expected 1 user, got %d\n",
519 (int)talloc_array_length(group)));
520 return NT_STATUS_INTERNAL_DB_CORRUPTION;
523 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
524 return NT_STATUS_INTERNAL_DB_CORRUPTION;
526 map->gid = pdb_ads_sid2gid(&map->sid);
528 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
529 return NT_STATUS_INTERNAL_DB_CORRUPTION;
532 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
533 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
534 map->sid_name_use = SID_NAME_ALIAS;
536 case GTYPE_SECURITY_GLOBAL_GROUP:
537 map->sid_name_use = SID_NAME_DOM_GRP;
540 return NT_STATUS_INTERNAL_DB_CORRUPTION;
543 str = tldap_talloc_single_attribute(group[0], "samAccountName",
546 return NT_STATUS_INTERNAL_DB_CORRUPTION;
548 fstrcpy(map->nt_name, str);
551 str = tldap_talloc_single_attribute(group[0], "description",
554 fstrcpy(map->comment, str);
557 map->comment[0] = '\0';
564 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
570 filter = talloc_asprintf(talloc_tos(),
571 "(&(objectsid=%s)(objectclass=group))",
572 sid_string_talloc(talloc_tos(), &sid));
573 if (filter == NULL) {
574 return NT_STATUS_NO_MEMORY;
577 status = pdb_ads_getgrfilter(m, map, filter);
582 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
586 pdb_ads_gid_to_sid(m, gid, &sid);
587 return pdb_ads_getgrsid(m, map, sid);
590 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
596 filter = talloc_asprintf(talloc_tos(),
597 "(&(samaccountname=%s)(objectclass=group))",
599 if (filter == NULL) {
600 return NT_STATUS_NO_MEMORY;
603 status = pdb_ads_getgrfilter(m, map, filter);
608 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
609 TALLOC_CTX *mem_ctx, const char *name,
612 TALLOC_CTX *frame = talloc_stackframe();
613 struct pdb_ads_state *state = talloc_get_type_abort(
614 m->private_data, struct pdb_ads_state);
615 const char *attrs[1] = { "objectSid" };
617 struct tldap_mod *mods = NULL;
618 struct tldap_message **alias;
624 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
628 return NT_STATUS_NO_MEMORY;
631 ok &= tldap_make_mod_fmt(
632 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
634 ok &= tldap_make_mod_fmt(
635 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
636 ok &= tldap_make_mod_fmt(
637 NULL, talloc_tos(), &num_mods, &mods, "groupType",
638 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
642 return NT_STATUS_NO_MEMORY;
645 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
646 if (rc != TLDAP_SUCCESS) {
647 DEBUG(10, ("ldap_add failed %s\n",
648 tldap_errstr(debug_ctx(), state->ld, rc)));
650 return NT_STATUS_LDAP(rc);
653 rc = tldap_search_fmt(
654 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
655 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
656 "(&(objectclass=group)(samaccountname=%s))", name);
657 if (rc != TLDAP_SUCCESS) {
658 DEBUG(10, ("Could not find just created alias %s: %s\n",
659 name, tldap_errstr(debug_ctx(), state->ld, rc)));
661 return NT_STATUS_LDAP(rc);
664 if (talloc_array_length(alias) != 1) {
665 DEBUG(10, ("Got %d alias, expected one\n",
666 (int)talloc_array_length(alias)));
668 return NT_STATUS_LDAP(rc);
671 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
672 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
675 return NT_STATUS_INTERNAL_DB_CORRUPTION;
678 sid_peek_rid(&sid, rid);
683 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
684 TALLOC_CTX *mem_ctx, uint32 rid)
686 struct pdb_ads_state *state = talloc_get_type_abort(
687 m->private_data, struct pdb_ads_state);
690 struct tldap_message **msg;
694 sid_compose(&sid, &state->domainsid, rid);
696 sidstr = sid_binstring(talloc_tos(), &sid);
697 NT_STATUS_HAVE_NO_MEMORY(sidstr);
699 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
700 NULL, 0, 0, talloc_tos(), &msg,
701 ("(&(objectSid=%s)(objectClass=group))"),
704 if (rc != TLDAP_SUCCESS) {
705 DEBUG(10, ("ldap_search failed %s\n",
706 tldap_errstr(debug_ctx(), state->ld, rc)));
707 return NT_STATUS_LDAP(rc);
710 switch talloc_array_length(msg) {
712 return NT_STATUS_NO_SUCH_GROUP;
716 return NT_STATUS_INTERNAL_DB_CORRUPTION;
719 if (!tldap_entry_dn(msg[0], &dn)) {
720 return NT_STATUS_INTERNAL_DB_CORRUPTION;
723 rc = tldap_delete(state->ld, dn, NULL, NULL);
724 if (rc != TLDAP_SUCCESS) {
725 DEBUG(10, ("ldap_delete failed: %s\n",
726 tldap_errstr(debug_ctx(), state->ld, rc)));
728 return NT_STATUS_LDAP(rc);
735 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
738 return NT_STATUS_NOT_IMPLEMENTED;
741 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
744 return NT_STATUS_NOT_IMPLEMENTED;
747 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
750 return NT_STATUS_NOT_IMPLEMENTED;
753 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
755 enum lsa_SidType sid_name_use,
757 size_t *p_num_entries,
760 return NT_STATUS_NOT_IMPLEMENTED;
763 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
765 const DOM_SID *group,
767 size_t *pnum_members)
769 struct pdb_ads_state *state = talloc_get_type_abort(
770 m->private_data, struct pdb_ads_state);
771 const char *attrs[1] = { "member" };
773 struct tldap_message **msg;
774 int i, rc, num_members;
778 sidstr = sid_binstring(talloc_tos(), group);
779 NT_STATUS_HAVE_NO_MEMORY(sidstr);
781 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
782 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
783 "(objectsid=%s)", sidstr);
785 if (rc != TLDAP_SUCCESS) {
786 DEBUG(10, ("ldap_search failed %s\n",
787 tldap_errstr(debug_ctx(), state->ld, rc)));
788 return NT_STATUS_LDAP(rc);
790 switch talloc_array_length(msg) {
792 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
797 return NT_STATUS_INTERNAL_DB_CORRUPTION;
801 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
802 return NT_STATUS_INTERNAL_DB_CORRUPTION;
805 members = talloc_array(mem_ctx, uint32_t, num_members);
806 if (members == NULL) {
807 return NT_STATUS_NO_MEMORY;
810 for (i=0; i<num_members; i++) {
812 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &sid)
813 || !sid_peek_rid(&sid, &members[i])) {
814 TALLOC_FREE(members);
815 return NT_STATUS_INTERNAL_DB_CORRUPTION;
820 *pnum_members = num_members;
824 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
829 size_t *p_num_groups)
831 struct pdb_ads_state *state = talloc_get_type_abort(
832 m->private_data, struct pdb_ads_state);
833 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
835 const char *attrs[1] = { "objectSid" };
836 struct tldap_message **groups;
839 struct dom_sid *group_sids;
842 rc = tldap_search_fmt(
843 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
844 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
845 "(&(member=%s)(grouptype=%d)(objectclass=group))",
846 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
847 if (rc != TLDAP_SUCCESS) {
848 DEBUG(10, ("ldap_search failed %s\n",
849 tldap_errstr(debug_ctx(), state->ld, rc)));
850 return NT_STATUS_LDAP(rc);
853 count = talloc_array_length(groups);
855 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
856 if (group_sids == NULL) {
857 return NT_STATUS_NO_MEMORY;
859 gids = talloc_array(mem_ctx, gid_t, count);
861 TALLOC_FREE(group_sids);
862 return NT_STATUS_NO_MEMORY;
866 for (i=0; i<count; i++) {
867 if (!tldap_pull_binsid(groups[i], "objectSid",
868 &group_sids[num_groups])) {
871 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
874 if (num_groups == count) {
879 *pp_sids = group_sids;
881 *p_num_groups = num_groups;
885 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
889 return NT_STATUS_NOT_IMPLEMENTED;
892 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
894 uint32 grouprid, uint32 memberrid,
897 struct pdb_ads_state *state = talloc_get_type_abort(
898 m->private_data, struct pdb_ads_state);
899 TALLOC_CTX *frame = talloc_stackframe();
900 struct dom_sid groupsid, membersid;
901 char *groupdn, *memberdn;
902 struct tldap_mod *mods;
906 sid_compose(&groupsid, &state->domainsid, grouprid);
907 sid_compose(&membersid, &state->domainsid, memberrid);
909 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
910 if (!NT_STATUS_IS_OK(status)) {
913 return NT_STATUS_NO_SUCH_GROUP;
915 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
916 if (!NT_STATUS_IS_OK(status)) {
918 return NT_STATUS_NO_SUCH_USER;
923 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
924 "member", memberdn)) {
926 return NT_STATUS_NO_MEMORY;
929 rc = tldap_modify(state->ld, groupdn, 1, mods, NULL, NULL);
931 if (rc != TLDAP_SUCCESS) {
932 DEBUG(10, ("ldap_modify failed: %s\n",
933 tldap_errstr(debug_ctx(), state->ld, rc)));
934 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
935 return NT_STATUS_MEMBER_IN_GROUP;
937 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
938 return NT_STATUS_MEMBER_NOT_IN_GROUP;
940 return NT_STATUS_LDAP(rc);
946 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
948 uint32 group_rid, uint32 member_rid)
950 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
954 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
956 uint32 group_rid, uint32 member_rid)
958 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
962 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
963 const char *name, uint32 *rid)
965 TALLOC_CTX *frame = talloc_stackframe();
966 struct pdb_ads_state *state = talloc_get_type_abort(
967 m->private_data, struct pdb_ads_state);
968 const char *attrs[1] = { "objectSid" };
970 struct tldap_mod *mods = NULL;
971 struct tldap_message **alias;
977 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
981 return NT_STATUS_NO_MEMORY;
984 ok &= tldap_make_mod_fmt(
985 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
987 ok &= tldap_make_mod_fmt(
988 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
989 ok &= tldap_make_mod_fmt(
990 NULL, talloc_tos(), &num_mods, &mods, "groupType",
991 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
995 return NT_STATUS_NO_MEMORY;
998 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
999 if (rc != TLDAP_SUCCESS) {
1000 DEBUG(10, ("ldap_add failed %s\n",
1001 tldap_errstr(debug_ctx(), state->ld, rc)));
1003 return NT_STATUS_LDAP(rc);
1006 rc = tldap_search_fmt(
1007 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1008 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1009 "(&(objectclass=group)(samaccountname=%s))", name);
1010 if (rc != TLDAP_SUCCESS) {
1011 DEBUG(10, ("Could not find just created alias %s: %s\n",
1012 name, tldap_errstr(debug_ctx(), state->ld, rc)));
1014 return NT_STATUS_LDAP(rc);
1017 if (talloc_array_length(alias) != 1) {
1018 DEBUG(10, ("Got %d alias, expected one\n",
1019 (int)talloc_array_length(alias)));
1021 return NT_STATUS_LDAP(rc);
1024 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1025 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1028 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1031 sid_peek_rid(&sid, rid);
1033 return NT_STATUS_OK;
1036 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1039 struct pdb_ads_state *state = talloc_get_type_abort(
1040 m->private_data, struct pdb_ads_state);
1041 struct tldap_message **alias;
1045 sidstr = sid_binstring(talloc_tos(), sid);
1046 if (sidstr == NULL) {
1047 return NT_STATUS_NO_MEMORY;
1050 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1051 NULL, 0, 0, talloc_tos(), &alias,
1052 "(&(objectSid=%s)(objectclass=group)"
1053 "(|(grouptype=%d)(grouptype=%d)))",
1054 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1055 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1056 TALLOC_FREE(sidstr);
1057 if (rc != TLDAP_SUCCESS) {
1058 DEBUG(10, ("ldap_search failed: %s\n",
1059 tldap_errstr(debug_ctx(), state->ld, rc)));
1061 return NT_STATUS_LDAP(rc);
1063 if (talloc_array_length(alias) != 1) {
1064 DEBUG(10, ("Expected 1 alias, got %d\n",
1065 (int)talloc_array_length(alias)));
1066 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1068 if (!tldap_entry_dn(alias[0], &dn)) {
1069 DEBUG(10, ("Could not get DN for alias %s\n",
1070 sid_string_dbg(sid)));
1071 return NT_STATUS_INTERNAL_ERROR;
1074 rc = tldap_delete(state->ld, dn, NULL, NULL);
1075 if (rc != TLDAP_SUCCESS) {
1076 DEBUG(10, ("ldap_delete failed: %s\n",
1077 tldap_errstr(debug_ctx(), state->ld, rc)));
1079 return NT_STATUS_LDAP(rc);
1082 return NT_STATUS_OK;
1085 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
1087 struct acct_info *info)
1089 return NT_STATUS_NOT_IMPLEMENTED;
1092 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1094 struct acct_info *info)
1096 return NT_STATUS_NOT_IMPLEMENTED;
1099 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1100 const struct dom_sid *sid,
1101 TALLOC_CTX *mem_ctx, char **pdn)
1103 struct tldap_message **msg;
1107 sidstr = sid_binstring(talloc_tos(), sid);
1108 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1110 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1111 NULL, 0, 0, talloc_tos(), &msg,
1112 "(objectsid=%s)", sidstr);
1113 TALLOC_FREE(sidstr);
1114 if (rc != TLDAP_SUCCESS) {
1115 DEBUG(10, ("ldap_search failed %s\n",
1116 tldap_errstr(debug_ctx(), state->ld, rc)));
1117 return NT_STATUS_LDAP(rc);
1120 switch talloc_array_length(msg) {
1122 return NT_STATUS_NOT_FOUND;
1126 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1129 if (!tldap_entry_dn(msg[0], &dn)) {
1130 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1133 dn = talloc_strdup(mem_ctx, dn);
1135 return NT_STATUS_NO_MEMORY;
1140 return NT_STATUS_OK;
1143 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1144 const DOM_SID *alias,
1145 const DOM_SID *member,
1148 struct pdb_ads_state *state = talloc_get_type_abort(
1149 m->private_data, struct pdb_ads_state);
1150 TALLOC_CTX *frame = talloc_stackframe();
1151 struct tldap_mod *mods;
1153 char *aliasdn, *memberdn;
1156 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1157 if (!NT_STATUS_IS_OK(status)) {
1158 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1159 sid_string_dbg(alias), nt_errstr(status)));
1161 return NT_STATUS_NO_SUCH_ALIAS;
1163 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1164 if (!NT_STATUS_IS_OK(status)) {
1165 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1166 sid_string_dbg(member), nt_errstr(status)));
1173 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1174 "member", memberdn)) {
1176 return NT_STATUS_NO_MEMORY;
1179 rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
1181 if (rc != TLDAP_SUCCESS) {
1182 DEBUG(10, ("ldap_modify failed: %s\n",
1183 tldap_errstr(debug_ctx(), state->ld, rc)));
1184 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1185 return NT_STATUS_MEMBER_IN_ALIAS;
1187 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1188 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1190 return NT_STATUS_LDAP(rc);
1193 return NT_STATUS_OK;
1196 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1197 const DOM_SID *alias,
1198 const DOM_SID *member)
1200 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1203 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1204 const DOM_SID *alias,
1205 const DOM_SID *member)
1207 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1210 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1211 struct dom_sid *psid)
1213 const char *attrs[1] = { "objectSid" };
1214 struct tldap_message **msg;
1220 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1221 dnblob->data, dnblob->length, &dn, &len,
1225 rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1226 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1227 &msg, "(objectclass=*)");
1229 if (talloc_array_length(msg) != 1) {
1230 DEBUG(10, ("Got %d objects, expected one\n",
1231 (int)talloc_array_length(msg)));
1236 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1241 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1242 const DOM_SID *alias,
1243 TALLOC_CTX *mem_ctx,
1245 size_t *pnum_members)
1247 struct pdb_ads_state *state = talloc_get_type_abort(
1248 m->private_data, struct pdb_ads_state);
1249 const char *attrs[1] = { "member" };
1251 struct tldap_message **msg;
1252 int i, rc, num_members;
1254 struct dom_sid *members;
1256 sidstr = sid_binstring(talloc_tos(), alias);
1257 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1259 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1260 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1261 "(objectsid=%s)", sidstr);
1262 TALLOC_FREE(sidstr);
1263 if (rc != TLDAP_SUCCESS) {
1264 DEBUG(10, ("ldap_search failed %s\n",
1265 tldap_errstr(debug_ctx(), state->ld, rc)));
1266 return NT_STATUS_LDAP(rc);
1268 switch talloc_array_length(msg) {
1270 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1275 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1279 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1280 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1283 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1284 if (members == NULL) {
1285 return NT_STATUS_NO_MEMORY;
1288 for (i=0; i<num_members; i++) {
1289 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1290 TALLOC_FREE(members);
1291 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1295 *pmembers = members;
1296 *pnum_members = num_members;
1297 return NT_STATUS_OK;
1300 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1301 TALLOC_CTX *mem_ctx,
1302 const DOM_SID *domain_sid,
1303 const DOM_SID *members,
1305 uint32 **pp_alias_rids,
1306 size_t *p_num_alias_rids)
1308 return NT_STATUS_NOT_IMPLEMENTED;
1311 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1312 const DOM_SID *domain_sid,
1315 const char **pp_names,
1316 enum lsa_SidType *attrs)
1318 return NT_STATUS_NOT_IMPLEMENTED;
1321 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1322 const DOM_SID *domain_sid,
1324 const char **pp_names,
1326 enum lsa_SidType *attrs)
1328 return NT_STATUS_NOT_IMPLEMENTED;
1331 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1332 int policy_index, uint32 *value)
1334 return account_policy_get(policy_index, value)
1335 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1338 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1339 int policy_index, uint32 value)
1341 return account_policy_set(policy_index, value)
1342 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1345 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1348 return NT_STATUS_NOT_IMPLEMENTED;
1351 struct pdb_ads_search_state {
1352 uint32_t acct_flags;
1353 struct samr_displayentry *entries;
1354 uint32_t num_entries;
1359 static bool pdb_ads_next_entry(struct pdb_search *search,
1360 struct samr_displayentry *entry)
1362 struct pdb_ads_search_state *state = talloc_get_type_abort(
1363 search->private_data, struct pdb_ads_search_state);
1365 if (state->current == state->num_entries) {
1369 entry->idx = state->entries[state->current].idx;
1370 entry->rid = state->entries[state->current].rid;
1371 entry->acct_flags = state->entries[state->current].acct_flags;
1373 entry->account_name = talloc_strdup(
1374 search, state->entries[state->current].account_name);
1375 entry->fullname = talloc_strdup(
1376 search, state->entries[state->current].fullname);
1377 entry->description = talloc_strdup(
1378 search, state->entries[state->current].description);
1380 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1381 || (entry->description == NULL)) {
1382 DEBUG(0, ("talloc_strdup failed\n"));
1386 state->current += 1;
1390 static void pdb_ads_search_end(struct pdb_search *search)
1392 struct pdb_ads_search_state *state = talloc_get_type_abort(
1393 search->private_data, struct pdb_ads_search_state);
1397 static bool pdb_ads_search_filter(struct pdb_methods *m,
1398 struct pdb_search *search,
1400 struct pdb_ads_search_state **pstate)
1402 struct pdb_ads_state *state = talloc_get_type_abort(
1403 m->private_data, struct pdb_ads_state);
1404 struct pdb_ads_search_state *sstate;
1405 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1406 "userAccountControl", "description" };
1407 struct tldap_message **users;
1408 int i, rc, num_users;
1410 sstate = talloc_zero(search, struct pdb_ads_search_state);
1411 if (sstate == NULL) {
1415 rc = tldap_search_fmt(
1416 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1417 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1419 if (rc != TLDAP_SUCCESS) {
1420 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1421 tldap_errstr(debug_ctx(), state->ld, rc)));
1425 num_users = talloc_array_length(users);
1427 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1429 if (sstate->entries == NULL) {
1430 DEBUG(10, ("talloc failed\n"));
1434 sstate->num_entries = 0;
1436 for (i=0; i<num_users; i++) {
1437 struct samr_displayentry *e;
1440 e = &sstate->entries[sstate->num_entries];
1442 e->idx = sstate->num_entries;
1443 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1444 DEBUG(10, ("Could not pull sid\n"));
1447 sid_peek_rid(&sid, &e->rid);
1448 e->acct_flags = ACB_NORMAL;
1449 e->account_name = tldap_talloc_single_attribute(
1450 users[i], "samAccountName", sstate->entries);
1451 if (e->account_name == NULL) {
1454 e->fullname = tldap_talloc_single_attribute(
1455 users[i], "displayName", sstate->entries);
1456 if (e->fullname == NULL) {
1459 e->description = tldap_talloc_single_attribute(
1460 users[i], "description", sstate->entries);
1461 if (e->description == NULL) {
1462 e->description = "";
1465 sstate->num_entries += 1;
1466 if (sstate->num_entries >= num_users) {
1471 search->private_data = sstate;
1472 search->next_entry = pdb_ads_next_entry;
1473 search->search_end = pdb_ads_search_end;
1478 static bool pdb_ads_search_users(struct pdb_methods *m,
1479 struct pdb_search *search,
1482 struct pdb_ads_search_state *sstate;
1485 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1489 sstate->acct_flags = acct_flags;
1493 static bool pdb_ads_search_groups(struct pdb_methods *m,
1494 struct pdb_search *search)
1496 struct pdb_ads_search_state *sstate;
1500 filter = talloc_asprintf(talloc_tos(),
1501 "(&(grouptype=%d)(objectclass=group))",
1502 GTYPE_SECURITY_GLOBAL_GROUP);
1503 if (filter == NULL) {
1506 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1507 TALLOC_FREE(filter);
1511 sstate->acct_flags = 0;
1515 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1516 struct pdb_search *search,
1519 struct pdb_ads_search_state *sstate;
1523 filter = talloc_asprintf(
1524 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1525 sid_check_is_builtin(sid)
1526 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1527 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1529 if (filter == NULL) {
1532 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1533 TALLOC_FREE(filter);
1537 sstate->acct_flags = 0;
1541 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1547 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1550 struct pdb_ads_state *state = talloc_get_type_abort(
1551 m->private_data, struct pdb_ads_state);
1552 sid_compose(sid, &state->domainsid, uid);
1556 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1559 struct pdb_ads_state *state = talloc_get_type_abort(
1560 m->private_data, struct pdb_ads_state);
1561 sid_compose(sid, &state->domainsid, gid);
1565 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1566 union unid_t *id, enum lsa_SidType *type)
1568 struct pdb_ads_state *state = talloc_get_type_abort(
1569 m->private_data, struct pdb_ads_state);
1570 struct tldap_message **msg;
1576 * This is a big, big hack: Just hard-code the rid as uid/gid.
1579 sid_peek_rid(sid, &rid);
1581 sidstr = sid_binstring(talloc_tos(), sid);
1582 if (sidstr == NULL) {
1586 rc = tldap_search_fmt(
1587 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1588 NULL, 0, 0, talloc_tos(), &msg,
1589 "(&(objectsid=%s)(objectclass=user))", sidstr);
1590 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1592 *type = SID_NAME_USER;
1593 TALLOC_FREE(sidstr);
1597 rc = tldap_search_fmt(
1598 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1599 NULL, 0, 0, talloc_tos(), &msg,
1600 "(&(objectsid=%s)(objectclass=group))", sidstr);
1601 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1603 *type = SID_NAME_DOM_GRP;
1604 TALLOC_FREE(sidstr);
1608 TALLOC_FREE(sidstr);
1612 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1617 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1622 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1623 const char *domain, char** pwd,
1625 time_t *pass_last_set_time)
1630 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1631 const char* domain, const char* pwd,
1637 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1643 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1644 TALLOC_CTX *mem_ctx,
1645 uint32 *num_domains,
1646 struct trustdom_info ***domains)
1648 return NT_STATUS_NOT_IMPLEMENTED;
1651 static void pdb_ads_init_methods(struct pdb_methods *m)
1654 m->getsampwnam = pdb_ads_getsampwnam;
1655 m->getsampwsid = pdb_ads_getsampwsid;
1656 m->create_user = pdb_ads_create_user;
1657 m->delete_user = pdb_ads_delete_user;
1658 m->add_sam_account = pdb_ads_add_sam_account;
1659 m->update_sam_account = pdb_ads_update_sam_account;
1660 m->delete_sam_account = pdb_ads_delete_sam_account;
1661 m->rename_sam_account = pdb_ads_rename_sam_account;
1662 m->update_login_attempts = pdb_ads_update_login_attempts;
1663 m->getgrsid = pdb_ads_getgrsid;
1664 m->getgrgid = pdb_ads_getgrgid;
1665 m->getgrnam = pdb_ads_getgrnam;
1666 m->create_dom_group = pdb_ads_create_dom_group;
1667 m->delete_dom_group = pdb_ads_delete_dom_group;
1668 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1669 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1670 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1671 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1672 m->enum_group_members = pdb_ads_enum_group_members;
1673 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1674 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1675 m->add_groupmem = pdb_ads_add_groupmem;
1676 m->del_groupmem = pdb_ads_del_groupmem;
1677 m->create_alias = pdb_ads_create_alias;
1678 m->delete_alias = pdb_ads_delete_alias;
1679 m->get_aliasinfo = pdb_ads_get_aliasinfo;
1680 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1681 m->add_aliasmem = pdb_ads_add_aliasmem;
1682 m->del_aliasmem = pdb_ads_del_aliasmem;
1683 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1684 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1685 m->lookup_rids = pdb_ads_lookup_rids;
1686 m->lookup_names = pdb_ads_lookup_names;
1687 m->get_account_policy = pdb_ads_get_account_policy;
1688 m->set_account_policy = pdb_ads_set_account_policy;
1689 m->get_seq_num = pdb_ads_get_seq_num;
1690 m->search_users = pdb_ads_search_users;
1691 m->search_groups = pdb_ads_search_groups;
1692 m->search_aliases = pdb_ads_search_aliases;
1693 m->uid_to_rid = pdb_ads_uid_to_rid;
1694 m->uid_to_sid = pdb_ads_uid_to_sid;
1695 m->gid_to_sid = pdb_ads_gid_to_sid;
1696 m->sid_to_id = pdb_ads_sid_to_id;
1697 m->rid_algorithm = pdb_ads_rid_algorithm;
1698 m->new_rid = pdb_ads_new_rid;
1699 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1700 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1701 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1702 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1705 static void free_private_data(void **vp)
1707 struct pdb_ads_state *state = talloc_get_type_abort(
1708 *vp, struct pdb_ads_state);
1710 TALLOC_FREE(state->ld);
1714 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1715 const char *location)
1717 const char *rootdse_attrs[2] = {
1718 "defaultNamingContext", "configurationNamingContext" };
1719 const char *domain_attrs[1] = { "objectSid" };
1720 const char *ncname_attrs[1] = { "netbiosname" };
1721 struct tldap_message **rootdse, **domain, **ncname;
1722 TALLOC_CTX *frame = talloc_stackframe();
1723 struct sockaddr_un sunaddr;
1728 ZERO_STRUCT(sunaddr);
1729 sunaddr.sun_family = AF_UNIX;
1730 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1732 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1734 if (!NT_STATUS_IS_OK(status)) {
1735 DEBUG(10, ("Could not connect to %s: %s\n", location,
1736 nt_errstr(status)));
1740 state->ld = tldap_context_create(state, fd);
1741 if (state->ld == NULL) {
1743 status = NT_STATUS_NO_MEMORY;
1747 rc = tldap_search_fmt(
1748 state->ld, "", TLDAP_SCOPE_BASE,
1749 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1750 talloc_tos(), &rootdse, "(objectclass=*)");
1751 if (rc != TLDAP_SUCCESS) {
1752 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1753 tldap_errstr(debug_ctx(), state->ld, rc)));
1754 status = NT_STATUS_LDAP(rc);
1757 if (talloc_array_length(rootdse) != 1) {
1758 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1762 state->domaindn = tldap_talloc_single_attribute(
1763 rootdse[0], "defaultNamingContext", state);
1764 if (state->domaindn == NULL) {
1765 DEBUG(10, ("Could not get defaultNamingContext\n"));
1766 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1769 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1771 state->configdn = tldap_talloc_single_attribute(
1772 rootdse[0], "configurationNamingContext", state);
1773 if (state->domaindn == NULL) {
1774 DEBUG(10, ("Could not get configurationNamingContext\n"));
1775 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1778 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1781 * Figure out our domain's SID
1783 rc = tldap_search_fmt(
1784 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1785 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1786 talloc_tos(), &domain, "(objectclass=*)");
1787 if (rc != TLDAP_SUCCESS) {
1788 DEBUG(10, ("Could not retrieve domain: %s\n",
1789 tldap_errstr(debug_ctx(), state->ld, rc)));
1790 status = NT_STATUS_LDAP(rc);
1794 num_domains = talloc_array_length(domain);
1795 if (num_domains != 1) {
1796 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1797 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1800 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1801 DEBUG(10, ("Could not retrieve domain SID\n"));
1802 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1805 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1808 * Figure out our domain's short name
1810 rc = tldap_search_fmt(
1811 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1812 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1813 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1814 if (rc != TLDAP_SUCCESS) {
1815 DEBUG(10, ("Could not retrieve ncname: %s\n",
1816 tldap_errstr(debug_ctx(), state->ld, rc)));
1817 status = NT_STATUS_LDAP(rc);
1820 if (talloc_array_length(ncname) != 1) {
1821 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1825 state->netbiosname = tldap_talloc_single_attribute(
1826 ncname[0], "netbiosname", state);
1827 if (state->netbiosname == NULL) {
1828 DEBUG(10, ("Could not get netbiosname\n"));
1829 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1832 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1834 if (!strequal(lp_workgroup(), state->netbiosname)) {
1835 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1836 state->netbiosname, lp_workgroup()));
1837 status = NT_STATUS_NO_SUCH_DOMAIN;
1841 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1843 status = NT_STATUS_OK;
1849 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1850 const char *location)
1852 struct pdb_methods *m;
1853 struct pdb_ads_state *state;
1857 m = talloc(talloc_autofree_context(), struct pdb_methods);
1859 return NT_STATUS_NO_MEMORY;
1861 state = talloc(m, struct pdb_ads_state);
1862 if (state == NULL) {
1865 m->private_data = state;
1866 m->free_private_data = free_private_data;
1867 pdb_ads_init_methods(m);
1869 if (location == NULL) {
1870 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1874 if (location == NULL) {
1878 status = pdb_ads_connect(state, location);
1879 if (!NT_STATUS_IS_OK(status)) {
1880 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1885 return NT_STATUS_OK;
1887 status = NT_STATUS_NO_MEMORY;
1893 NTSTATUS pdb_ads_init(void);
1894 NTSTATUS pdb_ads_init(void)
1896 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",