Implement pdb_ads_delete_alias
[Samba/bb.git] / source3 / passdb / pdb_ads.c
blob1bfbdf0dce1e8c3e2bfa3020862f068460ea754f
1 /*
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/>.
20 #include "includes.h"
22 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
23 struct samu *sam_acct,
24 const DOM_SID *sid);
25 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
26 DOM_SID *sid);
29 struct pdb_ads_state {
30 struct tldap_context *ld;
31 struct dom_sid domainsid;
32 char *domaindn;
33 char *configdn;
34 char *netbiosname;
37 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
38 time_t *ptime)
40 uint64_t tmp;
42 if (!tldap_pull_uint64(msg, attr, &tmp)) {
43 return false;
45 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
46 return true;
49 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
51 uint32_t rid;
52 sid_peek_rid(sid, &rid);
53 return rid;
56 struct pdb_ads_samu_private {
57 char *dn;
58 struct tldap_message *ldapmsg;
61 static struct samu *pdb_ads_init_guest(TALLOC_CTX *mem_ctx,
62 struct pdb_methods *m)
64 struct pdb_ads_state *state = talloc_get_type_abort(
65 m->private_data, struct pdb_ads_state);
66 struct dom_sid guest_sid;
67 struct samu *guest;
68 NTSTATUS status;
70 sid_compose(&guest_sid, &state->domainsid, DOMAIN_USER_RID_GUEST);
72 guest = samu_new(mem_ctx);
73 if (guest == NULL) {
74 return NULL;
77 status = pdb_ads_getsampwsid(m, guest, &guest_sid);
78 if (!NT_STATUS_IS_OK(status)) {
79 DEBUG(10, ("Could not init guest account: %s\n",
80 nt_errstr(status)));
81 TALLOC_FREE(guest);
82 return NULL;
84 return guest;
87 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
88 struct pdb_methods *m, struct samu *sam)
90 struct pdb_ads_samu_private *result;
91 uint32_t rid;
93 result = (struct pdb_ads_samu_private *)
94 pdb_get_backend_private_data(sam, m);
96 if (result != NULL) {
97 return talloc_get_type_abort(
98 result, struct pdb_ads_samu_private);
102 * This is now a weirdness of the passdb API. For the guest user we
103 * are not asked first.
105 sid_peek_rid(pdb_get_user_sid(sam), &rid);
107 if (rid == DOMAIN_USER_RID_GUEST) {
108 struct samu *guest = pdb_ads_init_guest(talloc_tos(), m);
110 if (guest == NULL) {
111 return NULL;
113 result = talloc_get_type_abort(
114 pdb_get_backend_private_data(guest, m),
115 struct pdb_ads_samu_private);
116 pdb_set_backend_private_data(
117 sam, talloc_move(sam, &result), NULL, m, PDB_SET);
118 TALLOC_FREE(guest);
119 return talloc_get_type_abort(
120 pdb_get_backend_private_data(sam, m),
121 struct pdb_ads_samu_private);
124 return NULL;
127 static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m,
128 struct samu *sam,
129 struct tldap_message *entry)
131 struct pdb_ads_state *state = talloc_get_type_abort(
132 m->private_data, struct pdb_ads_state);
133 TALLOC_CTX *frame = talloc_stackframe();
134 struct pdb_ads_samu_private *priv;
135 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
136 char *str;
137 time_t tmp_time;
138 struct dom_sid sid;
139 uint64_t n;
140 DATA_BLOB blob;
142 priv = talloc(sam, struct pdb_ads_samu_private);
143 if (priv == NULL) {
144 return NT_STATUS_NO_MEMORY;
146 if (!tldap_entry_dn(entry, &priv->dn)) {
147 TALLOC_FREE(priv);
148 return NT_STATUS_INTERNAL_DB_CORRUPTION;
151 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
152 if (str == NULL) {
153 DEBUG(10, ("no samAccountName\n"));
154 goto fail;
156 pdb_set_username(sam, str, PDB_SET);
157 TALLOC_FREE(str);
159 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
160 pdb_set_logon_time(sam, tmp_time, PDB_SET);
162 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
163 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
165 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
166 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
168 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
169 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
172 str = tldap_talloc_single_attribute(entry, "samAccoutName",
173 talloc_tos());
174 if (str != NULL) {
175 pdb_set_username(sam, str, PDB_SET);
178 str = tldap_talloc_single_attribute(entry, "displayName",
179 talloc_tos());
180 if (str != NULL) {
181 pdb_set_fullname(sam, str, PDB_SET);
184 str = tldap_talloc_single_attribute(entry, "homeDirectory",
185 talloc_tos());
186 if (str != NULL) {
187 pdb_set_homedir(sam, str, PDB_SET);
190 str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
191 if (str != NULL) {
192 pdb_set_dir_drive(sam, str, PDB_SET);
195 str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
196 if (str != NULL) {
197 pdb_set_logon_script(sam, str, PDB_SET);
200 str = tldap_talloc_single_attribute(entry, "profilePath",
201 talloc_tos());
202 if (str != NULL) {
203 pdb_set_profile_path(sam, str, PDB_SET);
206 str = tldap_talloc_single_attribute(entry, "profilePath",
207 talloc_tos());
208 if (str != NULL) {
209 pdb_set_profile_path(sam, str, PDB_SET);
212 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
213 DEBUG(10, ("Could not pull SID\n"));
214 goto fail;
216 pdb_set_user_sid(sam, &sid, PDB_SET);
218 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
219 DEBUG(10, ("Could not pull userAccountControl\n"));
220 goto fail;
222 pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET);
224 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
225 if (blob.length != NT_HASH_LEN) {
226 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
227 (int)blob.length, NT_HASH_LEN));
228 goto fail;
230 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
233 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
234 if (blob.length != LM_HASH_LEN) {
235 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
236 (int)blob.length, LM_HASH_LEN));
237 goto fail;
239 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
242 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
243 sid_compose(&sid, &state->domainsid, n);
244 pdb_set_group_sid(sam, &sid, PDB_SET);
248 priv->ldapmsg = talloc_move(priv, &entry);
249 pdb_set_backend_private_data(sam, priv, NULL, m, PDB_SET);
251 status = NT_STATUS_OK;
252 fail:
253 TALLOC_FREE(frame);
254 return status;
257 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
258 struct tldap_message *existing,
259 TALLOC_CTX *mem_ctx,
260 int *pnum_mods, struct tldap_mod **pmods,
261 struct samu *sam)
263 bool ret = true;
265 /* TODO: All fields :-) */
267 ret &= tldap_make_mod_fmt(
268 existing, mem_ctx, pnum_mods, pmods, "displayName",
269 pdb_get_fullname(sam));
271 ret &= tldap_make_mod_blob(
272 existing, mem_ctx, pnum_mods, pmods, "unicodePwd",
273 data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN));
275 ret &= tldap_make_mod_blob(
276 existing, mem_ctx, pnum_mods, pmods, "dBCSPwd",
277 data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN));
279 return ret;
282 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
283 struct pdb_ads_state *state,
284 struct samu *sam_acct,
285 const char *filter)
287 const char * attrs[] = {
288 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
289 "sAMAccountName", "displayName", "homeDirectory",
290 "homeDrive", "scriptPath", "profilePath", "description",
291 "userWorkstations", "comment", "userParameters", "objectSid",
292 "primaryGroupID", "userAccountControl", "logonHours",
293 "badPwdCount", "logonCount", "countryCode", "codePage",
294 "unicodePwd", "dBCSPwd" };
295 struct tldap_message **users;
296 int rc, count;
298 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
299 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
300 &users, "%s", filter);
301 if (rc != TLDAP_SUCCESS) {
302 DEBUG(10, ("ldap_search failed %s\n",
303 tldap_errstr(debug_ctx(), state->ld, rc)));
304 return NT_STATUS_LDAP(rc);
307 count = talloc_array_length(users);
308 if (count != 1) {
309 DEBUG(10, ("Expected 1 user, got %d\n", count));
310 return NT_STATUS_INTERNAL_DB_CORRUPTION;
313 return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]);
316 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
317 struct samu *sam_acct,
318 const char *username)
320 struct pdb_ads_state *state = talloc_get_type_abort(
321 m->private_data, struct pdb_ads_state);
322 char *filter;
324 filter = talloc_asprintf(
325 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
326 username);
327 NT_STATUS_HAVE_NO_MEMORY(filter);
329 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
332 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
333 struct samu *sam_acct,
334 const DOM_SID *sid)
336 struct pdb_ads_state *state = talloc_get_type_abort(
337 m->private_data, struct pdb_ads_state);
338 char *sidstr, *filter;
340 sidstr = sid_binstring(talloc_tos(), sid);
341 NT_STATUS_HAVE_NO_MEMORY(sidstr);
343 filter = talloc_asprintf(
344 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
345 TALLOC_FREE(sidstr);
346 NT_STATUS_HAVE_NO_MEMORY(filter);
348 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
351 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
352 TALLOC_CTX *tmp_ctx,
353 const char *name, uint32 acct_flags,
354 uint32 *rid)
356 struct pdb_ads_state *state = talloc_get_type_abort(
357 m->private_data, struct pdb_ads_state);
358 const char *attrs[1] = { "objectSid" };
359 struct tldap_mod *mods = NULL;
360 int num_mods = 0;
361 struct tldap_message **user;
362 struct dom_sid sid;
363 char *dn;
364 int rc;
365 bool ok;
367 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
368 state->domaindn);
369 if (dn == NULL) {
370 return NT_STATUS_NO_MEMORY;
373 /* TODO: Create machines etc */
375 ok = true;
376 ok &= tldap_make_mod_fmt(
377 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
378 ok &= tldap_make_mod_fmt(
379 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
380 name);
381 if (!ok) {
382 return NT_STATUS_NO_MEMORY;
385 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
386 if (rc != TLDAP_SUCCESS) {
387 DEBUG(10, ("ldap_add failed %s\n",
388 tldap_errstr(debug_ctx(), state->ld, rc)));
389 TALLOC_FREE(dn);
390 return NT_STATUS_LDAP(rc);
393 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
394 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &user,
395 "(&(objectclass=user)(samaccountname=%s))",
396 name);
397 if (rc != TLDAP_SUCCESS) {
398 DEBUG(10, ("Could not find just created user %s: %s\n",
399 name, tldap_errstr(debug_ctx(), state->ld, rc)));
400 TALLOC_FREE(dn);
401 return NT_STATUS_LDAP(rc);
404 if (talloc_array_length(user) != 1) {
405 DEBUG(10, ("Got %d users, expected one\n",
406 (int)talloc_array_length(user)));
407 TALLOC_FREE(dn);
408 return NT_STATUS_LDAP(rc);
411 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
412 DEBUG(10, ("Could not fetch objectSid from user %s\n",
413 name));
414 TALLOC_FREE(dn);
415 return NT_STATUS_INTERNAL_DB_CORRUPTION;
418 sid_peek_rid(&sid, rid);
419 TALLOC_FREE(dn);
420 return NT_STATUS_OK;
423 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
424 TALLOC_CTX *tmp_ctx,
425 struct samu *sam)
427 struct pdb_ads_state *state = talloc_get_type_abort(
428 m->private_data, struct pdb_ads_state);
429 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
430 int rc;
432 rc = tldap_delete(state->ld, priv->dn, NULL, NULL);
433 if (rc != TLDAP_SUCCESS) {
434 DEBUG(10, ("ldap_delete for %s failed: %s\n", priv->dn,
435 tldap_errstr(debug_ctx(), state->ld, rc)));
436 return NT_STATUS_LDAP(rc);
438 return NT_STATUS_OK;
441 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
442 struct samu *sampass)
444 return NT_STATUS_NOT_IMPLEMENTED;
447 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
448 struct samu *sam)
450 struct pdb_ads_state *state = talloc_get_type_abort(
451 m->private_data, struct pdb_ads_state);
452 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
453 struct tldap_mod *mods = NULL;
454 int rc, num_mods = 0;
456 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
457 &num_mods, &mods, sam)) {
458 return NT_STATUS_NO_MEMORY;
461 rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, NULL);
462 if (rc != TLDAP_SUCCESS) {
463 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
464 tldap_errstr(debug_ctx(), state->ld, rc)));
465 return NT_STATUS_LDAP(rc);
468 TALLOC_FREE(mods);
470 return NT_STATUS_OK;
473 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
474 struct samu *username)
476 return NT_STATUS_NOT_IMPLEMENTED;
479 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
480 struct samu *oldname,
481 const char *newname)
483 return NT_STATUS_NOT_IMPLEMENTED;
486 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
487 struct samu *sam_acct,
488 bool success)
490 return NT_STATUS_NOT_IMPLEMENTED;
493 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
494 const char *filter)
496 struct pdb_ads_state *state = talloc_get_type_abort(
497 m->private_data, struct pdb_ads_state);
498 const char *attrs[4] = { "objectSid", "description", "samAccountName",
499 "groupType" };
500 char *str;
501 struct tldap_message **group;
502 uint32_t grouptype;
503 int rc;
505 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
506 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
507 &group, "%s", filter);
508 if (rc != TLDAP_SUCCESS) {
509 DEBUG(10, ("ldap_search failed %s\n",
510 tldap_errstr(debug_ctx(), state->ld, rc)));
511 return NT_STATUS_LDAP(rc);
513 if (talloc_array_length(group) != 1) {
514 DEBUG(10, ("Expected 1 user, got %d\n",
515 talloc_array_length(group)));
516 return NT_STATUS_INTERNAL_DB_CORRUPTION;
519 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
520 return NT_STATUS_INTERNAL_DB_CORRUPTION;
522 map->gid = pdb_ads_sid2gid(&map->sid);
524 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
525 return NT_STATUS_INTERNAL_DB_CORRUPTION;
527 switch (grouptype) {
528 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
529 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
530 map->sid_name_use = SID_NAME_ALIAS;
531 break;
532 case GTYPE_SECURITY_GLOBAL_GROUP:
533 map->sid_name_use = SID_NAME_DOM_GRP;
534 break;
535 default:
536 return NT_STATUS_INTERNAL_DB_CORRUPTION;
539 str = tldap_talloc_single_attribute(group[0], "samAccountName",
540 talloc_tos());
541 if (str == NULL) {
542 return NT_STATUS_INTERNAL_DB_CORRUPTION;
544 fstrcpy(map->nt_name, str);
545 TALLOC_FREE(str);
547 str = tldap_talloc_single_attribute(group[0], "description",
548 talloc_tos());
549 if (str != NULL) {
550 fstrcpy(map->comment, str);
551 TALLOC_FREE(str);
552 } else {
553 map->comment[0] = '\0';
556 TALLOC_FREE(group);
557 return NT_STATUS_OK;
560 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
561 DOM_SID sid)
563 char *filter;
564 NTSTATUS status;
566 filter = talloc_asprintf(talloc_tos(),
567 "(&(objectsid=%s)(objectclass=group))",
568 sid_string_talloc(talloc_tos(), &sid));
569 if (filter == NULL) {
570 return NT_STATUS_NO_MEMORY;
573 status = pdb_ads_getgrfilter(m, map, filter);
574 TALLOC_FREE(filter);
575 return status;
578 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
579 gid_t gid)
581 struct dom_sid sid;
582 pdb_ads_gid_to_sid(m, gid, &sid);
583 return pdb_ads_getgrsid(m, map, sid);
586 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
587 const char *name)
589 char *filter;
590 NTSTATUS status;
592 filter = talloc_asprintf(talloc_tos(),
593 "(&(samaccountname=%s)(objectclass=group))",
594 name);
595 if (filter == NULL) {
596 return NT_STATUS_NO_MEMORY;
599 status = pdb_ads_getgrfilter(m, map, filter);
600 TALLOC_FREE(filter);
601 return status;
604 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
605 TALLOC_CTX *mem_ctx, const char *name,
606 uint32 *rid)
608 TALLOC_CTX *frame = talloc_stackframe();
609 struct pdb_ads_state *state = talloc_get_type_abort(
610 m->private_data, struct pdb_ads_state);
611 const char *attrs[1] = { "objectSid" };
612 int num_mods = 0;
613 struct tldap_mod *mods = NULL;
614 struct tldap_message **alias;
615 struct dom_sid sid;
616 char *dn;
617 int rc;
618 bool ok = true;
620 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
621 state->domaindn);
622 if (dn == NULL) {
623 TALLOC_FREE(frame);
624 return NT_STATUS_NO_MEMORY;
627 ok &= tldap_make_mod_fmt(
628 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
629 name);
630 ok &= tldap_make_mod_fmt(
631 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
632 ok &= tldap_make_mod_fmt(
633 NULL, talloc_tos(), &num_mods, &mods, "groupType",
634 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
636 if (!ok) {
637 TALLOC_FREE(frame);
638 return NT_STATUS_NO_MEMORY;
641 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
642 if (rc != TLDAP_SUCCESS) {
643 DEBUG(10, ("ldap_add failed %s\n",
644 tldap_errstr(debug_ctx(), state->ld, rc)));
645 TALLOC_FREE(frame);
646 return NT_STATUS_LDAP(rc);
649 rc = tldap_search_fmt(
650 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
651 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
652 "(&(objectclass=group)(samaccountname=%s))", name);
653 if (rc != TLDAP_SUCCESS) {
654 DEBUG(10, ("Could not find just created alias %s: %s\n",
655 name, tldap_errstr(debug_ctx(), state->ld, rc)));
656 TALLOC_FREE(frame);
657 return NT_STATUS_LDAP(rc);
660 if (talloc_array_length(alias) != 1) {
661 DEBUG(10, ("Got %d alias, expected one\n",
662 (int)talloc_array_length(alias)));
663 TALLOC_FREE(frame);
664 return NT_STATUS_LDAP(rc);
667 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
668 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
669 name));
670 TALLOC_FREE(frame);
671 return NT_STATUS_INTERNAL_DB_CORRUPTION;
674 sid_peek_rid(&sid, rid);
675 TALLOC_FREE(frame);
676 return NT_STATUS_OK;
679 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
680 TALLOC_CTX *mem_ctx, uint32 rid)
682 return NT_STATUS_NOT_IMPLEMENTED;
685 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
686 GROUP_MAP *map)
688 return NT_STATUS_NOT_IMPLEMENTED;
691 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
692 GROUP_MAP *map)
694 return NT_STATUS_NOT_IMPLEMENTED;
697 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
698 DOM_SID sid)
700 return NT_STATUS_NOT_IMPLEMENTED;
703 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
704 const DOM_SID *sid,
705 enum lsa_SidType sid_name_use,
706 GROUP_MAP **pp_rmap,
707 size_t *p_num_entries,
708 bool unix_only)
710 return NT_STATUS_NOT_IMPLEMENTED;
713 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
714 TALLOC_CTX *mem_ctx,
715 const DOM_SID *group,
716 uint32 **pp_member_rids,
717 size_t *p_num_members)
719 return NT_STATUS_NOT_IMPLEMENTED;
722 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
723 TALLOC_CTX *mem_ctx,
724 struct samu *user,
725 DOM_SID **pp_sids,
726 gid_t **pp_gids,
727 size_t *p_num_groups)
729 struct pdb_ads_state *state = talloc_get_type_abort(
730 m->private_data, struct pdb_ads_state);
731 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
732 m, user);
733 const char *attrs[1] = { "objectSid" };
734 struct tldap_message **groups;
735 int i, rc, count;
736 size_t num_groups;
737 struct dom_sid *group_sids;
738 gid_t *gids;
740 rc = tldap_search_fmt(
741 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
742 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
743 "(&(member=%s)(grouptype=%d)(objectclass=group))",
744 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
745 if (rc != TLDAP_SUCCESS) {
746 DEBUG(10, ("ldap_search failed %s\n",
747 tldap_errstr(debug_ctx(), state->ld, rc)));
748 return NT_STATUS_LDAP(rc);
751 count = talloc_array_length(groups);
753 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
754 if (group_sids == NULL) {
755 return NT_STATUS_NO_MEMORY;
757 gids = talloc_array(mem_ctx, gid_t, count);
758 if (gids == NULL) {
759 TALLOC_FREE(group_sids);
760 return NT_STATUS_NO_MEMORY;
762 num_groups = 0;
764 for (i=0; i<count; i++) {
765 if (!tldap_pull_binsid(groups[i], "objectSid",
766 &group_sids[num_groups])) {
767 continue;
769 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
771 num_groups += 1;
772 if (num_groups == count) {
773 break;
777 *pp_sids = group_sids;
778 *pp_gids = gids;
779 *p_num_groups = num_groups;
780 return NT_STATUS_OK;
783 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
784 TALLOC_CTX *mem_ctx,
785 struct samu *user)
787 return NT_STATUS_NOT_IMPLEMENTED;
790 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
791 TALLOC_CTX *mem_ctx,
792 uint32 group_rid, uint32 member_rid)
794 return NT_STATUS_NOT_IMPLEMENTED;
797 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
798 TALLOC_CTX *mem_ctx,
799 uint32 group_rid, uint32 member_rid)
801 return NT_STATUS_NOT_IMPLEMENTED;
804 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
805 const char *name, uint32 *rid)
807 TALLOC_CTX *frame = talloc_stackframe();
808 struct pdb_ads_state *state = talloc_get_type_abort(
809 m->private_data, struct pdb_ads_state);
810 const char *attrs[1] = { "objectSid" };
811 int num_mods = 0;
812 struct tldap_mod *mods = NULL;
813 struct tldap_message **alias;
814 struct dom_sid sid;
815 char *dn;
816 int rc;
817 bool ok = true;
819 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
820 state->domaindn);
821 if (dn == NULL) {
822 TALLOC_FREE(frame);
823 return NT_STATUS_NO_MEMORY;
826 ok &= tldap_make_mod_fmt(
827 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
828 name);
829 ok &= tldap_make_mod_fmt(
830 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
831 ok &= tldap_make_mod_fmt(
832 NULL, talloc_tos(), &num_mods, &mods, "groupType",
833 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
835 if (!ok) {
836 TALLOC_FREE(frame);
837 return NT_STATUS_NO_MEMORY;
840 rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
841 if (rc != TLDAP_SUCCESS) {
842 DEBUG(10, ("ldap_add failed %s\n",
843 tldap_errstr(debug_ctx(), state->ld, rc)));
844 TALLOC_FREE(frame);
845 return NT_STATUS_LDAP(rc);
848 rc = tldap_search_fmt(
849 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
850 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
851 "(&(objectclass=group)(samaccountname=%s))", name);
852 if (rc != TLDAP_SUCCESS) {
853 DEBUG(10, ("Could not find just created alias %s: %s\n",
854 name, tldap_errstr(debug_ctx(), state->ld, rc)));
855 TALLOC_FREE(frame);
856 return NT_STATUS_LDAP(rc);
859 if (talloc_array_length(alias) != 1) {
860 DEBUG(10, ("Got %d alias, expected one\n",
861 (int)talloc_array_length(alias)));
862 TALLOC_FREE(frame);
863 return NT_STATUS_LDAP(rc);
866 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
867 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
868 name));
869 TALLOC_FREE(frame);
870 return NT_STATUS_INTERNAL_DB_CORRUPTION;
873 sid_peek_rid(&sid, rid);
874 TALLOC_FREE(frame);
875 return NT_STATUS_OK;
878 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
879 const DOM_SID *sid)
881 struct pdb_ads_state *state = talloc_get_type_abort(
882 m->private_data, struct pdb_ads_state);
883 struct tldap_message **alias;
884 char *sidstr, *dn;
885 int rc;
887 sidstr = sid_binstring(talloc_tos(), sid);
888 if (sidstr == NULL) {
889 return NT_STATUS_NO_MEMORY;
892 rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
893 NULL, 0, 0, talloc_tos(), &alias,
894 "(&(objectSid=%s)(objectclass=group)"
895 "(|(grouptype=%d)(grouptype=%d)))",
896 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
897 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
898 TALLOC_FREE(sidstr);
899 if (rc != TLDAP_SUCCESS) {
900 DEBUG(10, ("ldap_search failed: %s\n",
901 tldap_errstr(debug_ctx(), state->ld, rc)));
902 TALLOC_FREE(dn);
903 return NT_STATUS_LDAP(rc);
905 if (talloc_array_length(alias) != 1) {
906 DEBUG(10, ("Expected 1 alias, got %d\n",
907 talloc_array_length(alias)));
908 return NT_STATUS_INTERNAL_DB_CORRUPTION;
910 if (!tldap_entry_dn(alias[0], &dn)) {
911 DEBUG(10, ("Could not get DN for alias %s\n",
912 sid_string_dbg(sid)));
913 return NT_STATUS_INTERNAL_ERROR;
916 rc = tldap_delete(state->ld, dn, NULL, NULL);
917 if (rc != TLDAP_SUCCESS) {
918 DEBUG(10, ("ldap_delete failed: %s\n",
919 tldap_errstr(debug_ctx(), state->ld, rc)));
920 TALLOC_FREE(dn);
921 return NT_STATUS_LDAP(rc);
924 return NT_STATUS_OK;
927 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
928 const DOM_SID *sid,
929 struct acct_info *info)
931 return NT_STATUS_NOT_IMPLEMENTED;
934 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
935 const DOM_SID *sid,
936 struct acct_info *info)
938 return NT_STATUS_NOT_IMPLEMENTED;
941 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
942 const DOM_SID *alias,
943 const DOM_SID *member)
945 return NT_STATUS_NOT_IMPLEMENTED;
948 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
949 const DOM_SID *alias,
950 const DOM_SID *member)
952 return NT_STATUS_NOT_IMPLEMENTED;
955 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
956 const DOM_SID *alias, DOM_SID **members,
957 size_t *p_num_members)
959 return NT_STATUS_NOT_IMPLEMENTED;
962 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
963 TALLOC_CTX *mem_ctx,
964 const DOM_SID *domain_sid,
965 const DOM_SID *members,
966 size_t num_members,
967 uint32 **pp_alias_rids,
968 size_t *p_num_alias_rids)
970 return NT_STATUS_NOT_IMPLEMENTED;
973 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
974 const DOM_SID *domain_sid,
975 int num_rids,
976 uint32 *rids,
977 const char **pp_names,
978 enum lsa_SidType *attrs)
980 return NT_STATUS_NOT_IMPLEMENTED;
983 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
984 const DOM_SID *domain_sid,
985 int num_names,
986 const char **pp_names,
987 uint32 *rids,
988 enum lsa_SidType *attrs)
990 return NT_STATUS_NOT_IMPLEMENTED;
993 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
994 int policy_index, uint32 *value)
996 return account_policy_get(policy_index, value)
997 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1000 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1001 int policy_index, uint32 value)
1003 return account_policy_set(policy_index, value)
1004 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1007 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1008 time_t *seq_num)
1010 return NT_STATUS_NOT_IMPLEMENTED;
1013 struct pdb_ads_search_state {
1014 uint32_t acct_flags;
1015 struct samr_displayentry *entries;
1016 uint32_t num_entries;
1017 ssize_t array_size;
1018 uint32_t current;
1021 static bool pdb_ads_next_entry(struct pdb_search *search,
1022 struct samr_displayentry *entry)
1024 struct pdb_ads_search_state *state = talloc_get_type_abort(
1025 search->private_data, struct pdb_ads_search_state);
1027 if (state->current == state->num_entries) {
1028 return false;
1031 entry->idx = state->entries[state->current].idx;
1032 entry->rid = state->entries[state->current].rid;
1033 entry->acct_flags = state->entries[state->current].acct_flags;
1035 entry->account_name = talloc_strdup(
1036 search, state->entries[state->current].account_name);
1037 entry->fullname = talloc_strdup(
1038 search, state->entries[state->current].fullname);
1039 entry->description = talloc_strdup(
1040 search, state->entries[state->current].description);
1042 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1043 || (entry->description == NULL)) {
1044 DEBUG(0, ("talloc_strdup failed\n"));
1045 return false;
1048 state->current += 1;
1049 return true;
1052 static void pdb_ads_search_end(struct pdb_search *search)
1054 struct pdb_ads_search_state *state = talloc_get_type_abort(
1055 search->private_data, struct pdb_ads_search_state);
1056 TALLOC_FREE(state);
1059 static bool pdb_ads_search_filter(struct pdb_methods *m,
1060 struct pdb_search *search,
1061 const char *filter,
1062 struct pdb_ads_search_state **pstate)
1064 struct pdb_ads_state *state = talloc_get_type_abort(
1065 m->private_data, struct pdb_ads_state);
1066 struct pdb_ads_search_state *sstate;
1067 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1068 "userAccountControl", "description" };
1069 struct tldap_message **users;
1070 int i, rc, num_users;
1072 sstate = talloc_zero(search, struct pdb_ads_search_state);
1073 if (sstate == NULL) {
1074 return false;
1077 rc = tldap_search_fmt(
1078 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1079 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1080 "%s", filter);
1081 if (rc != TLDAP_SUCCESS) {
1082 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1083 tldap_errstr(debug_ctx(), state->ld, rc)));
1084 return false;
1087 num_users = talloc_array_length(users);
1089 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1090 num_users);
1091 if (sstate->entries == NULL) {
1092 DEBUG(10, ("talloc failed\n"));
1093 return false;
1096 sstate->num_entries = 0;
1098 for (i=0; i<num_users; i++) {
1099 struct samr_displayentry *e;
1100 struct dom_sid sid;
1102 e = &sstate->entries[sstate->num_entries];
1104 e->idx = sstate->num_entries;
1105 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1106 DEBUG(10, ("Could not pull sid\n"));
1107 continue;
1109 sid_peek_rid(&sid, &e->rid);
1110 e->acct_flags = ACB_NORMAL;
1111 e->account_name = tldap_talloc_single_attribute(
1112 users[i], "samAccountName", sstate->entries);
1113 if (e->account_name == NULL) {
1114 return false;
1116 e->fullname = tldap_talloc_single_attribute(
1117 users[i], "displayName", sstate->entries);
1118 if (e->fullname == NULL) {
1119 e->fullname = "";
1121 e->description = tldap_talloc_single_attribute(
1122 users[i], "description", sstate->entries);
1123 if (e->description == NULL) {
1124 e->description = "";
1127 sstate->num_entries += 1;
1128 if (sstate->num_entries >= num_users) {
1129 break;
1133 search->private_data = sstate;
1134 search->next_entry = pdb_ads_next_entry;
1135 search->search_end = pdb_ads_search_end;
1136 *pstate = sstate;
1137 return true;
1140 static bool pdb_ads_search_users(struct pdb_methods *m,
1141 struct pdb_search *search,
1142 uint32 acct_flags)
1144 struct pdb_ads_search_state *sstate;
1145 bool ret;
1147 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1148 if (!ret) {
1149 return false;
1151 sstate->acct_flags = acct_flags;
1152 return true;
1155 static bool pdb_ads_search_groups(struct pdb_methods *m,
1156 struct pdb_search *search)
1158 struct pdb_ads_search_state *sstate;
1159 char *filter;
1160 bool ret;
1162 filter = talloc_asprintf(talloc_tos(),
1163 "(&(grouptype=%d)(objectclass=group))",
1164 GTYPE_SECURITY_GLOBAL_GROUP);
1165 if (filter == NULL) {
1166 return false;
1168 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1169 TALLOC_FREE(filter);
1170 if (!ret) {
1171 return false;
1173 sstate->acct_flags = 0;
1174 return true;
1177 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1178 struct pdb_search *search,
1179 const DOM_SID *sid)
1181 struct pdb_ads_search_state *sstate;
1182 char *filter;
1183 bool ret;
1185 filter = talloc_asprintf(
1186 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1187 sid_check_is_builtin(sid)
1188 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1189 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1191 if (filter == NULL) {
1192 return false;
1194 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1195 TALLOC_FREE(filter);
1196 if (!ret) {
1197 return false;
1199 sstate->acct_flags = 0;
1200 return true;
1203 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1204 uint32 *rid)
1206 return false;
1209 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1210 DOM_SID *sid)
1212 struct pdb_ads_state *state = talloc_get_type_abort(
1213 m->private_data, struct pdb_ads_state);
1214 sid_compose(sid, &state->domainsid, uid);
1215 return true;
1218 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1219 DOM_SID *sid)
1221 struct pdb_ads_state *state = talloc_get_type_abort(
1222 m->private_data, struct pdb_ads_state);
1223 sid_compose(sid, &state->domainsid, gid);
1224 return true;
1227 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1228 union unid_t *id, enum lsa_SidType *type)
1230 struct pdb_ads_state *state = talloc_get_type_abort(
1231 m->private_data, struct pdb_ads_state);
1232 struct tldap_message **msg;
1233 char *sidstr;
1234 uint32_t rid;
1235 int rc;
1238 * This is a big, big hack: Just hard-code the rid as uid/gid.
1241 sid_peek_rid(sid, &rid);
1243 sidstr = sid_binstring(talloc_tos(), sid);
1244 if (sidstr == NULL) {
1245 return false;
1248 rc = tldap_search_fmt(
1249 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1250 NULL, 0, 0, talloc_tos(), &msg,
1251 "(&(objectsid=%s)(objectclass=user))", sidstr);
1252 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1253 id->uid = rid;
1254 *type = SID_NAME_USER;
1255 TALLOC_FREE(sidstr);
1256 return true;
1259 rc = tldap_search_fmt(
1260 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1261 NULL, 0, 0, talloc_tos(), &msg,
1262 "(&(objectsid=%s)(objectclass=group))", sidstr);
1263 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1264 id->gid = rid;
1265 *type = SID_NAME_DOM_GRP;
1266 TALLOC_FREE(sidstr);
1267 return true;
1270 TALLOC_FREE(sidstr);
1271 return false;
1274 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1276 return false;
1279 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1281 return false;
1284 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1285 const char *domain, char** pwd,
1286 DOM_SID *sid,
1287 time_t *pass_last_set_time)
1289 return false;
1292 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1293 const char* domain, const char* pwd,
1294 const DOM_SID *sid)
1296 return false;
1299 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1300 const char *domain)
1302 return false;
1305 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1306 TALLOC_CTX *mem_ctx,
1307 uint32 *num_domains,
1308 struct trustdom_info ***domains)
1310 return NT_STATUS_NOT_IMPLEMENTED;
1313 static void pdb_ads_init_methods(struct pdb_methods *m)
1315 m->name = "ads";
1316 m->getsampwnam = pdb_ads_getsampwnam;
1317 m->getsampwsid = pdb_ads_getsampwsid;
1318 m->create_user = pdb_ads_create_user;
1319 m->delete_user = pdb_ads_delete_user;
1320 m->add_sam_account = pdb_ads_add_sam_account;
1321 m->update_sam_account = pdb_ads_update_sam_account;
1322 m->delete_sam_account = pdb_ads_delete_sam_account;
1323 m->rename_sam_account = pdb_ads_rename_sam_account;
1324 m->update_login_attempts = pdb_ads_update_login_attempts;
1325 m->getgrsid = pdb_ads_getgrsid;
1326 m->getgrgid = pdb_ads_getgrgid;
1327 m->getgrnam = pdb_ads_getgrnam;
1328 m->create_dom_group = pdb_ads_create_dom_group;
1329 m->delete_dom_group = pdb_ads_delete_dom_group;
1330 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1331 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1332 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1333 m->enum_group_mapping = pdb_ads_enum_group_mapping;
1334 m->enum_group_members = pdb_ads_enum_group_members;
1335 m->enum_group_memberships = pdb_ads_enum_group_memberships;
1336 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1337 m->add_groupmem = pdb_ads_add_groupmem;
1338 m->del_groupmem = pdb_ads_del_groupmem;
1339 m->create_alias = pdb_ads_create_alias;
1340 m->delete_alias = pdb_ads_delete_alias;
1341 m->get_aliasinfo = pdb_ads_get_aliasinfo;
1342 m->set_aliasinfo = pdb_ads_set_aliasinfo;
1343 m->add_aliasmem = pdb_ads_add_aliasmem;
1344 m->del_aliasmem = pdb_ads_del_aliasmem;
1345 m->enum_aliasmem = pdb_ads_enum_aliasmem;
1346 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1347 m->lookup_rids = pdb_ads_lookup_rids;
1348 m->lookup_names = pdb_ads_lookup_names;
1349 m->get_account_policy = pdb_ads_get_account_policy;
1350 m->set_account_policy = pdb_ads_set_account_policy;
1351 m->get_seq_num = pdb_ads_get_seq_num;
1352 m->search_users = pdb_ads_search_users;
1353 m->search_groups = pdb_ads_search_groups;
1354 m->search_aliases = pdb_ads_search_aliases;
1355 m->uid_to_rid = pdb_ads_uid_to_rid;
1356 m->uid_to_sid = pdb_ads_uid_to_sid;
1357 m->gid_to_sid = pdb_ads_gid_to_sid;
1358 m->sid_to_id = pdb_ads_sid_to_id;
1359 m->rid_algorithm = pdb_ads_rid_algorithm;
1360 m->new_rid = pdb_ads_new_rid;
1361 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1362 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1363 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1364 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1367 static void free_private_data(void **vp)
1369 struct pdb_ads_state *state = talloc_get_type_abort(
1370 *vp, struct pdb_ads_state);
1372 TALLOC_FREE(state->ld);
1373 return;
1376 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1377 const char *location)
1379 const char *rootdse_attrs[2] = {
1380 "defaultNamingContext", "configurationNamingContext" };
1381 const char *domain_attrs[1] = { "objectSid" };
1382 const char *ncname_attrs[1] = { "netbiosname" };
1383 struct tldap_message **rootdse, **domain, **ncname;
1384 TALLOC_CTX *frame = talloc_stackframe();
1385 struct sockaddr_un sunaddr;
1386 NTSTATUS status;
1387 int num_domains;
1388 int fd, rc;
1390 ZERO_STRUCT(sunaddr);
1391 sunaddr.sun_family = AF_UNIX;
1392 strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1394 status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1395 0, 0, &fd);
1396 if (!NT_STATUS_IS_OK(status)) {
1397 DEBUG(10, ("Could not connect to %s: %s\n", location,
1398 nt_errstr(status)));
1399 goto done;
1402 state->ld = tldap_context_create(state, fd);
1403 if (state->ld == NULL) {
1404 close(fd);
1405 status = NT_STATUS_NO_MEMORY;
1406 goto done;
1409 rc = tldap_search_fmt(
1410 state->ld, "", TLDAP_SCOPE_BASE,
1411 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1412 talloc_tos(), &rootdse, "(objectclass=*)");
1413 if (rc != TLDAP_SUCCESS) {
1414 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1415 tldap_errstr(debug_ctx(), state->ld, rc)));
1416 status = NT_STATUS_LDAP(rc);
1417 goto done;
1419 if (talloc_array_length(rootdse) != 1) {
1420 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1421 goto done;
1424 state->domaindn = tldap_talloc_single_attribute(
1425 rootdse[0], "defaultNamingContext", state);
1426 if (state->domaindn == NULL) {
1427 DEBUG(10, ("Could not get defaultNamingContext\n"));
1428 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1429 goto done;
1431 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1433 state->configdn = tldap_talloc_single_attribute(
1434 rootdse[0], "configurationNamingContext", state);
1435 if (state->domaindn == NULL) {
1436 DEBUG(10, ("Could not get configurationNamingContext\n"));
1437 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1438 goto done;
1440 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1443 * Figure out our domain's SID
1445 rc = tldap_search_fmt(
1446 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1447 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1448 talloc_tos(), &domain, "(objectclass=*)");
1449 if (rc != TLDAP_SUCCESS) {
1450 DEBUG(10, ("Could not retrieve domain: %s\n",
1451 tldap_errstr(debug_ctx(), state->ld, rc)));
1452 status = NT_STATUS_LDAP(rc);
1453 goto done;
1456 num_domains = talloc_array_length(domain);
1457 if (num_domains != 1) {
1458 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1459 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1460 goto done;
1462 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1463 DEBUG(10, ("Could not retrieve domain SID\n"));
1464 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1465 goto done;
1467 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1470 * Figure out our domain's short name
1472 rc = tldap_search_fmt(
1473 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1474 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1475 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1476 if (rc != TLDAP_SUCCESS) {
1477 DEBUG(10, ("Could not retrieve ncname: %s\n",
1478 tldap_errstr(debug_ctx(), state->ld, rc)));
1479 status = NT_STATUS_LDAP(rc);
1480 goto done;
1482 if (talloc_array_length(ncname) != 1) {
1483 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1484 goto done;
1487 state->netbiosname = tldap_talloc_single_attribute(
1488 ncname[0], "netbiosname", state);
1489 if (state->netbiosname == NULL) {
1490 DEBUG(10, ("Could not get netbiosname\n"));
1491 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1492 goto done;
1494 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1496 if (!strequal(lp_workgroup(), state->netbiosname)) {
1497 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1498 state->netbiosname, lp_workgroup()));
1499 status = NT_STATUS_NO_SUCH_DOMAIN;
1500 goto done;
1503 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1505 status = NT_STATUS_OK;
1506 done:
1507 TALLOC_FREE(frame);
1508 return status;
1511 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1512 const char *location)
1514 struct pdb_methods *m;
1515 struct pdb_ads_state *state;
1516 char *tmp = NULL;
1517 NTSTATUS status;
1519 m = talloc(talloc_autofree_context(), struct pdb_methods);
1520 if (m == NULL) {
1521 return NT_STATUS_NO_MEMORY;
1523 state = talloc(m, struct pdb_ads_state);
1524 if (state == NULL) {
1525 goto nomem;
1527 m->private_data = state;
1528 m->free_private_data = free_private_data;
1529 pdb_ads_init_methods(m);
1531 if (location == NULL) {
1532 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1533 lp_private_dir());
1534 location = tmp;
1536 if (location == NULL) {
1537 goto nomem;
1540 status = pdb_ads_connect(state, location);
1541 if (!NT_STATUS_IS_OK(status)) {
1542 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1543 goto fail;
1546 *pdb_method = m;
1547 return NT_STATUS_OK;
1548 nomem:
1549 status = NT_STATUS_NO_MEMORY;
1550 fail:
1551 TALLOC_FREE(m);
1552 return status;
1555 NTSTATUS pdb_ads_init(void);
1556 NTSTATUS pdb_ads_init(void)
1558 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
1559 pdb_init_ads);