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)) {
912 return NT_STATUS_NO_SUCH_GROUP;
914 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
915 if (!NT_STATUS_IS_OK(status)) {
917 return NT_STATUS_NO_SUCH_USER;
922 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
923 "member", memberdn)) {
925 return NT_STATUS_NO_MEMORY;
928 rc = tldap_modify(state->ld, groupdn, 1, mods, NULL, NULL);
930 if (rc != TLDAP_SUCCESS) {
931 DEBUG(10, ("ldap_modify failed: %s\n",
932 tldap_errstr(debug_ctx(), state->ld, rc)));
933 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
934 return NT_STATUS_MEMBER_IN_GROUP;
936 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
937 return NT_STATUS_MEMBER_NOT_IN_GROUP;
939 return NT_STATUS_LDAP(rc);
945 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
947 uint32 group_rid, uint32 member_rid)
949 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
953 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
955 uint32 group_rid, uint32 member_rid)
957 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
961 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
962 const char *name, uint32 *rid)
964 TALLOC_CTX *frame = talloc_stackframe();
965 struct pdb_ads_state *state = talloc_get_type_abort(
966 m->private_data, struct pdb_ads_state);
967 const char *attrs[1] = { "objectSid" };
969 struct tldap_mod *mods = NULL;
970 struct tldap_message **alias;
976 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
980 return NT_STATUS_NO_MEMORY;
983 ok &= tldap_make_mod_fmt(
984 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
986 ok &= tldap_make_mod_fmt(
987 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
988 ok &= tldap_make_mod_fmt(
989 NULL, talloc_tos(), &num_mods, &mods, "groupType",
990 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
994 return NT_STATUS_NO_MEMORY;
997 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
998 if (rc != TLDAP_SUCCESS) {
999 DEBUG(10, ("ldap_add failed %s\n",
1000 tldap_errstr(debug_ctx(), state->ld, rc)));
1002 return NT_STATUS_LDAP(rc);
1005 rc = tldap_search_fmt(
1006 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1007 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1008 "(&(objectclass=group)(samaccountname=%s))", name);
1009 if (rc != TLDAP_SUCCESS) {
1010 DEBUG(10, ("Could not find just created alias %s: %s\n",
1011 name, tldap_errstr(debug_ctx(), state->ld, rc)));
1013 return NT_STATUS_LDAP(rc);
1016 if (talloc_array_length(alias) != 1) {
1017 DEBUG(10, ("Got %d alias, expected one\n",
1018 (int)talloc_array_length(alias)));
1020 return NT_STATUS_LDAP(rc);
1023 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1024 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1027 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1030 sid_peek_rid(&sid, rid);
1032 return NT_STATUS_OK;
1035 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1038 struct pdb_ads_state *state = talloc_get_type_abort(
1039 m->private_data, struct pdb_ads_state);
1040 struct tldap_message **alias;
1044 sidstr = sid_binstring(talloc_tos(), sid);
1045 if (sidstr == NULL) {
1046 return NT_STATUS_NO_MEMORY;
1049 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1050 NULL, 0, 0, talloc_tos(), &alias,
1051 "(&(objectSid=%s)(objectclass=group)"
1052 "(|(grouptype=%d)(grouptype=%d)))",
1053 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1054 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1055 TALLOC_FREE(sidstr);
1056 if (rc != TLDAP_SUCCESS) {
1057 DEBUG(10, ("ldap_search failed: %s\n",
1058 tldap_errstr(debug_ctx(), state->ld, rc)));
1060 return NT_STATUS_LDAP(rc);
1062 if (talloc_array_length(alias) != 1) {
1063 DEBUG(10, ("Expected 1 alias, got %d\n",
1064 (int)talloc_array_length(alias)));
1065 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1067 if (!tldap_entry_dn(alias[0], &dn)) {
1068 DEBUG(10, ("Could not get DN for alias %s\n",
1069 sid_string_dbg(sid)));
1070 return NT_STATUS_INTERNAL_ERROR;
1073 rc = tldap_delete(state->ld, dn, NULL, NULL);
1074 if (rc != TLDAP_SUCCESS) {
1075 DEBUG(10, ("ldap_delete failed: %s\n",
1076 tldap_errstr(debug_ctx(), state->ld, rc)));
1078 return NT_STATUS_LDAP(rc);
1081 return NT_STATUS_OK;
1084 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
1086 struct acct_info *info)
1088 return NT_STATUS_NOT_IMPLEMENTED;
1091 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1093 struct acct_info *info)
1095 return NT_STATUS_NOT_IMPLEMENTED;
1098 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1099 const struct dom_sid *sid,
1100 TALLOC_CTX *mem_ctx, char **pdn)
1102 struct tldap_message **msg;
1106 sidstr = sid_binstring(talloc_tos(), sid);
1107 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1109 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1110 NULL, 0, 0, talloc_tos(), &msg,
1111 "(objectsid=%s)", sidstr);
1112 TALLOC_FREE(sidstr);
1113 if (rc != TLDAP_SUCCESS) {
1114 DEBUG(10, ("ldap_search failed %s\n",
1115 tldap_errstr(debug_ctx(), state->ld, rc)));
1116 return NT_STATUS_LDAP(rc);
1119 switch talloc_array_length(msg) {
1121 return NT_STATUS_NOT_FOUND;
1125 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1128 if (!tldap_entry_dn(msg[0], &dn)) {
1129 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1132 dn = talloc_strdup(mem_ctx, dn);
1134 return NT_STATUS_NO_MEMORY;
1139 return NT_STATUS_OK;
1142 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1143 const DOM_SID *alias,
1144 const DOM_SID *member,
1147 struct pdb_ads_state *state = talloc_get_type_abort(
1148 m->private_data, struct pdb_ads_state);
1149 TALLOC_CTX *frame = talloc_stackframe();
1150 struct tldap_mod *mods;
1152 char *aliasdn, *memberdn;
1155 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1156 if (!NT_STATUS_IS_OK(status)) {
1157 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1158 sid_string_dbg(alias), nt_errstr(status)));
1160 return NT_STATUS_NO_SUCH_ALIAS;
1162 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1163 if (!NT_STATUS_IS_OK(status)) {
1164 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1165 sid_string_dbg(member), nt_errstr(status)));
1172 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1173 "member", memberdn)) {
1175 return NT_STATUS_NO_MEMORY;
1178 rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
1180 if (rc != TLDAP_SUCCESS) {
1181 DEBUG(10, ("ldap_modify failed: %s\n",
1182 tldap_errstr(debug_ctx(), state->ld, rc)));
1183 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1184 return NT_STATUS_MEMBER_IN_ALIAS;
1186 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1187 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1189 return NT_STATUS_LDAP(rc);
1192 return NT_STATUS_OK;
1195 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1196 const DOM_SID *alias,
1197 const DOM_SID *member)
1199 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1202 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1203 const DOM_SID *alias,
1204 const DOM_SID *member)
1206 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1209 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1210 struct dom_sid *psid)
1212 const char *attrs[1] = { "objectSid" };
1213 struct tldap_message **msg;
1219 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1220 dnblob->data, dnblob->length, &dn, &len,
1224 rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1225 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1226 &msg, "(objectclass=*)");
1228 if (talloc_array_length(msg) != 1) {
1229 DEBUG(10, ("Got %d objects, expected one\n",
1230 (int)talloc_array_length(msg)));
1235 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1240 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1241 const DOM_SID *alias,
1242 TALLOC_CTX *mem_ctx,
1244 size_t *pnum_members)
1246 struct pdb_ads_state *state = talloc_get_type_abort(
1247 m->private_data, struct pdb_ads_state);
1248 const char *attrs[1] = { "member" };
1250 struct tldap_message **msg;
1251 int i, rc, num_members;
1253 struct dom_sid *members;
1255 sidstr = sid_binstring(talloc_tos(), alias);
1256 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1258 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1259 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1260 "(objectsid=%s)", sidstr);
1261 TALLOC_FREE(sidstr);
1262 if (rc != TLDAP_SUCCESS) {
1263 DEBUG(10, ("ldap_search failed %s\n",
1264 tldap_errstr(debug_ctx(), state->ld, rc)));
1265 return NT_STATUS_LDAP(rc);
1267 switch talloc_array_length(msg) {
1269 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1274 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1278 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1279 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1282 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1283 if (members == NULL) {
1284 return NT_STATUS_NO_MEMORY;
1287 for (i=0; i<num_members; i++) {
1288 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1289 TALLOC_FREE(members);
1290 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1294 *pmembers = members;
1295 *pnum_members = num_members;
1296 return NT_STATUS_OK;
1299 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1300 TALLOC_CTX *mem_ctx,
1301 const DOM_SID *domain_sid,
1302 const DOM_SID *members,
1304 uint32 **pp_alias_rids,
1305 size_t *p_num_alias_rids)
1307 return NT_STATUS_NOT_IMPLEMENTED;
1310 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1311 const DOM_SID *domain_sid,
1314 const char **pp_names,
1315 enum lsa_SidType *attrs)
1317 return NT_STATUS_NOT_IMPLEMENTED;
1320 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1321 const DOM_SID *domain_sid,
1323 const char **pp_names,
1325 enum lsa_SidType *attrs)
1327 return NT_STATUS_NOT_IMPLEMENTED;
1330 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1331 int policy_index, uint32 *value)
1333 return account_policy_get(policy_index, value)
1334 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1337 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1338 int policy_index, uint32 value)
1340 return account_policy_set(policy_index, value)
1341 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1344 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1347 return NT_STATUS_NOT_IMPLEMENTED;
1350 struct pdb_ads_search_state {
1351 uint32_t acct_flags;
1352 struct samr_displayentry *entries;
1353 uint32_t num_entries;
1358 static bool pdb_ads_next_entry(struct pdb_search *search,
1359 struct samr_displayentry *entry)
1361 struct pdb_ads_search_state *state = talloc_get_type_abort(
1362 search->private_data, struct pdb_ads_search_state);
1364 if (state->current == state->num_entries) {
1368 entry->idx = state->entries[state->current].idx;
1369 entry->rid = state->entries[state->current].rid;
1370 entry->acct_flags = state->entries[state->current].acct_flags;
1372 entry->account_name = talloc_strdup(
1373 search, state->entries[state->current].account_name);
1374 entry->fullname = talloc_strdup(
1375 search, state->entries[state->current].fullname);
1376 entry->description = talloc_strdup(
1377 search, state->entries[state->current].description);
1379 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1380 || (entry->description == NULL)) {
1381 DEBUG(0, ("talloc_strdup failed\n"));
1385 state->current += 1;
1389 static void pdb_ads_search_end(struct pdb_search *search)
1391 struct pdb_ads_search_state *state = talloc_get_type_abort(
1392 search->private_data, struct pdb_ads_search_state);
1396 static bool pdb_ads_search_filter(struct pdb_methods *m,
1397 struct pdb_search *search,
1399 struct pdb_ads_search_state **pstate)
1401 struct pdb_ads_state *state = talloc_get_type_abort(
1402 m->private_data, struct pdb_ads_state);
1403 struct pdb_ads_search_state *sstate;
1404 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1405 "userAccountControl", "description" };
1406 struct tldap_message **users;
1407 int i, rc, num_users;
1409 sstate = talloc_zero(search, struct pdb_ads_search_state);
1410 if (sstate == NULL) {
1414 rc = tldap_search_fmt(
1415 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1416 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1418 if (rc != TLDAP_SUCCESS) {
1419 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1420 tldap_errstr(debug_ctx(), state->ld, rc)));
1424 num_users = talloc_array_length(users);
1426 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1428 if (sstate->entries == NULL) {
1429 DEBUG(10, ("talloc failed\n"));
1433 sstate->num_entries = 0;
1435 for (i=0; i<num_users; i++) {
1436 struct samr_displayentry *e;
1439 e = &sstate->entries[sstate->num_entries];
1441 e->idx = sstate->num_entries;
1442 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1443 DEBUG(10, ("Could not pull sid\n"));
1446 sid_peek_rid(&sid, &e->rid);
1447 e->acct_flags = ACB_NORMAL;
1448 e->account_name = tldap_talloc_single_attribute(
1449 users[i], "samAccountName", sstate->entries);
1450 if (e->account_name == NULL) {
1453 e->fullname = tldap_talloc_single_attribute(
1454 users[i], "displayName", sstate->entries);
1455 if (e->fullname == NULL) {
1458 e->description = tldap_talloc_single_attribute(
1459 users[i], "description", sstate->entries);
1460 if (e->description == NULL) {
1461 e->description = "";
1464 sstate->num_entries += 1;
1465 if (sstate->num_entries >= num_users) {
1470 search->private_data = sstate;
1471 search->next_entry = pdb_ads_next_entry;
1472 search->search_end = pdb_ads_search_end;
1477 static bool pdb_ads_search_users(struct pdb_methods *m,
1478 struct pdb_search *search,
1481 struct pdb_ads_search_state *sstate;
1484 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1488 sstate->acct_flags = acct_flags;
1492 static bool pdb_ads_search_groups(struct pdb_methods *m,
1493 struct pdb_search *search)
1495 struct pdb_ads_search_state *sstate;
1499 filter = talloc_asprintf(talloc_tos(),
1500 "(&(grouptype=%d)(objectclass=group))",
1501 GTYPE_SECURITY_GLOBAL_GROUP);
1502 if (filter == NULL) {
1505 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1506 TALLOC_FREE(filter);
1510 sstate->acct_flags = 0;
1514 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1515 struct pdb_search *search,
1518 struct pdb_ads_search_state *sstate;
1522 filter = talloc_asprintf(
1523 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1524 sid_check_is_builtin(sid)
1525 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1526 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1528 if (filter == NULL) {
1531 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1532 TALLOC_FREE(filter);
1536 sstate->acct_flags = 0;
1540 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1546 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1549 struct pdb_ads_state *state = talloc_get_type_abort(
1550 m->private_data, struct pdb_ads_state);
1551 sid_compose(sid, &state->domainsid, uid);
1555 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1558 struct pdb_ads_state *state = talloc_get_type_abort(
1559 m->private_data, struct pdb_ads_state);
1560 sid_compose(sid, &state->domainsid, gid);
1564 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1565 union unid_t *id, enum lsa_SidType *type)
1567 struct pdb_ads_state *state = talloc_get_type_abort(
1568 m->private_data, struct pdb_ads_state);
1569 struct tldap_message **msg;
1575 * This is a big, big hack: Just hard-code the rid as uid/gid.
1578 sid_peek_rid(sid, &rid);
1580 sidstr = sid_binstring(talloc_tos(), sid);
1581 if (sidstr == NULL) {
1585 rc = tldap_search_fmt(
1586 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1587 NULL, 0, 0, talloc_tos(), &msg,
1588 "(&(objectsid=%s)(objectclass=user))", sidstr);
1589 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1591 *type = SID_NAME_USER;
1592 TALLOC_FREE(sidstr);
1596 rc = tldap_search_fmt(
1597 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1598 NULL, 0, 0, talloc_tos(), &msg,
1599 "(&(objectsid=%s)(objectclass=group))", sidstr);
1600 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1602 *type = SID_NAME_DOM_GRP;
1603 TALLOC_FREE(sidstr);
1607 TALLOC_FREE(sidstr);
1611 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1616 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1621 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1622 const char *domain, char** pwd,
1624 time_t *pass_last_set_time)
1629 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1630 const char* domain, const char* pwd,
1636 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1642 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1643 TALLOC_CTX *mem_ctx,
1644 uint32 *num_domains,
1645 struct trustdom_info ***domains)
1647 return NT_STATUS_NOT_IMPLEMENTED;
1650 static void pdb_ads_init_methods(struct pdb_methods *m)
1653 m->getsampwnam = pdb_ads_getsampwnam;
1654 m->getsampwsid = pdb_ads_getsampwsid;
1655 m->create_user = pdb_ads_create_user;
1656 m->delete_user = pdb_ads_delete_user;
1657 m->add_sam_account = pdb_ads_add_sam_account;
1658 m->update_sam_account = pdb_ads_update_sam_account;
1659 m->delete_sam_account = pdb_ads_delete_sam_account;
1660 m->rename_sam_account = pdb_ads_rename_sam_account;
1661 m->update_login_attempts = pdb_ads_update_login_attempts;
1662 m->getgrsid = pdb_ads_getgrsid;
1663 m->getgrgid = pdb_ads_getgrgid;
1664 m->getgrnam = pdb_ads_getgrnam;
1665 m->create_dom_group = pdb_ads_create_dom_group;
1666 m->delete_dom_group = pdb_ads_delete_dom_group;
1667 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1668 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1669 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1670 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1671 m->enum_group_members = pdb_ads_enum_group_members;
1672 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1673 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1674 m->add_groupmem = pdb_ads_add_groupmem;
1675 m->del_groupmem = pdb_ads_del_groupmem;
1676 m->create_alias = pdb_ads_create_alias;
1677 m->delete_alias = pdb_ads_delete_alias;
1678 m->get_aliasinfo = pdb_ads_get_aliasinfo;
1679 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1680 m->add_aliasmem = pdb_ads_add_aliasmem;
1681 m->del_aliasmem = pdb_ads_del_aliasmem;
1682 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1683 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1684 m->lookup_rids = pdb_ads_lookup_rids;
1685 m->lookup_names = pdb_ads_lookup_names;
1686 m->get_account_policy = pdb_ads_get_account_policy;
1687 m->set_account_policy = pdb_ads_set_account_policy;
1688 m->get_seq_num = pdb_ads_get_seq_num;
1689 m->search_users = pdb_ads_search_users;
1690 m->search_groups = pdb_ads_search_groups;
1691 m->search_aliases = pdb_ads_search_aliases;
1692 m->uid_to_rid = pdb_ads_uid_to_rid;
1693 m->uid_to_sid = pdb_ads_uid_to_sid;
1694 m->gid_to_sid = pdb_ads_gid_to_sid;
1695 m->sid_to_id = pdb_ads_sid_to_id;
1696 m->rid_algorithm = pdb_ads_rid_algorithm;
1697 m->new_rid = pdb_ads_new_rid;
1698 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1699 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1700 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1701 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1704 static void free_private_data(void **vp)
1706 struct pdb_ads_state *state = talloc_get_type_abort(
1707 *vp, struct pdb_ads_state);
1709 TALLOC_FREE(state->ld);
1713 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1714 const char *location)
1716 const char *rootdse_attrs[2] = {
1717 "defaultNamingContext", "configurationNamingContext" };
1718 const char *domain_attrs[1] = { "objectSid" };
1719 const char *ncname_attrs[1] = { "netbiosname" };
1720 struct tldap_message **rootdse, **domain, **ncname;
1721 TALLOC_CTX *frame = talloc_stackframe();
1722 struct sockaddr_un sunaddr;
1727 ZERO_STRUCT(sunaddr);
1728 sunaddr.sun_family = AF_UNIX;
1729 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1731 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1733 if (!NT_STATUS_IS_OK(status)) {
1734 DEBUG(10, ("Could not connect to %s: %s\n", location,
1735 nt_errstr(status)));
1739 state->ld = tldap_context_create(state, fd);
1740 if (state->ld == NULL) {
1742 status = NT_STATUS_NO_MEMORY;
1746 rc = tldap_search_fmt(
1747 state->ld, "", TLDAP_SCOPE_BASE,
1748 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1749 talloc_tos(), &rootdse, "(objectclass=*)");
1750 if (rc != TLDAP_SUCCESS) {
1751 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1752 tldap_errstr(debug_ctx(), state->ld, rc)));
1753 status = NT_STATUS_LDAP(rc);
1756 if (talloc_array_length(rootdse) != 1) {
1757 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1761 state->domaindn = tldap_talloc_single_attribute(
1762 rootdse[0], "defaultNamingContext", state);
1763 if (state->domaindn == NULL) {
1764 DEBUG(10, ("Could not get defaultNamingContext\n"));
1765 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1768 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1770 state->configdn = tldap_talloc_single_attribute(
1771 rootdse[0], "configurationNamingContext", state);
1772 if (state->domaindn == NULL) {
1773 DEBUG(10, ("Could not get configurationNamingContext\n"));
1774 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1777 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1780 * Figure out our domain's SID
1782 rc = tldap_search_fmt(
1783 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1784 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1785 talloc_tos(), &domain, "(objectclass=*)");
1786 if (rc != TLDAP_SUCCESS) {
1787 DEBUG(10, ("Could not retrieve domain: %s\n",
1788 tldap_errstr(debug_ctx(), state->ld, rc)));
1789 status = NT_STATUS_LDAP(rc);
1793 num_domains = talloc_array_length(domain);
1794 if (num_domains != 1) {
1795 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1796 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1799 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1800 DEBUG(10, ("Could not retrieve domain SID\n"));
1801 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1804 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1807 * Figure out our domain's short name
1809 rc = tldap_search_fmt(
1810 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1811 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1812 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1813 if (rc != TLDAP_SUCCESS) {
1814 DEBUG(10, ("Could not retrieve ncname: %s\n",
1815 tldap_errstr(debug_ctx(), state->ld, rc)));
1816 status = NT_STATUS_LDAP(rc);
1819 if (talloc_array_length(ncname) != 1) {
1820 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1824 state->netbiosname = tldap_talloc_single_attribute(
1825 ncname[0], "netbiosname", state);
1826 if (state->netbiosname == NULL) {
1827 DEBUG(10, ("Could not get netbiosname\n"));
1828 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1831 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1833 if (!strequal(lp_workgroup(), state->netbiosname)) {
1834 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1835 state->netbiosname, lp_workgroup()));
1836 status = NT_STATUS_NO_SUCH_DOMAIN;
1840 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1842 status = NT_STATUS_OK;
1848 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1849 const char *location)
1851 struct pdb_methods *m;
1852 struct pdb_ads_state *state;
1856 m = talloc(talloc_autofree_context(), struct pdb_methods);
1858 return NT_STATUS_NO_MEMORY;
1860 state = talloc(m, struct pdb_ads_state);
1861 if (state == NULL) {
1864 m->private_data = state;
1865 m->free_private_data = free_private_data;
1866 pdb_ads_init_methods(m);
1868 if (location == NULL) {
1869 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1873 if (location == NULL) {
1877 status = pdb_ads_connect(state, location);
1878 if (!NT_STATUS_IS_OK(status)) {
1879 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1884 return NT_STATUS_OK;
1886 status = NT_STATUS_NO_MEMORY;
1892 NTSTATUS pdb_ads_init(void);
1893 NTSTATUS pdb_ads_init(void)
1895 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",