WHATSNEW: Update changed parameters.
[Samba/gebeck_regimport.git] / source3 / passdb / pdb_ads.c
blob01f730eb20fbf872c0f5ea7e6ec7abcd96603c2d
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"
21 #include "tldap.h"
22 #include "tldap_util.h"
23 #include "../libds/common/flags.h"
24 #include "secrets.h"
25 #include "../librpc/gen_ndr/samr.h"
26 #include "../libcli/ldap/ldap_ndr.h"
27 #include "../libcli/security/security.h"
29 struct pdb_ads_state {
30 struct sockaddr_un socket_address;
31 struct tldap_context *ld;
32 struct dom_sid domainsid;
33 struct GUID domainguid;
34 char *domaindn;
35 char *configdn;
36 char *netbiosname;
39 struct pdb_ads_samu_private {
40 char *dn;
41 struct tldap_message *ldapmsg;
44 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
45 struct samu *sam_acct,
46 const struct dom_sid *sid);
47 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
48 struct dom_sid *sid);
49 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
50 struct dom_sid *psid);
51 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
52 const struct dom_sid *sid,
53 TALLOC_CTX *mem_ctx, char **pdn);
54 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state);
55 static int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
56 int scope, const char *attrs[], int num_attrs,
57 int attrsonly,
58 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
59 const char *fmt, ...);
60 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
61 const char *filter,
62 TALLOC_CTX *mem_ctx,
63 struct pdb_ads_samu_private **presult);
65 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
66 time_t *ptime)
68 uint64_t tmp;
70 if (!tldap_pull_uint64(msg, attr, &tmp)) {
71 return false;
73 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
74 return true;
77 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
79 uint32_t rid;
80 sid_peek_rid(sid, &rid);
81 return rid;
84 static char *pdb_ads_domaindn2dns(TALLOC_CTX *mem_ctx, char *dn)
86 char *result, *p;
88 result = talloc_string_sub2(mem_ctx, dn, "DC=", "", false, false,
89 true);
90 if (result == NULL) {
91 return NULL;
94 while ((p = strchr_m(result, ',')) != NULL) {
95 *p = '.';
98 return result;
101 static struct pdb_domain_info *pdb_ads_get_domain_info(
102 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
104 struct pdb_ads_state *state = talloc_get_type_abort(
105 m->private_data, struct pdb_ads_state);
106 struct pdb_domain_info *info;
107 struct tldap_message *rootdse;
108 char *tmp;
110 info = talloc(mem_ctx, struct pdb_domain_info);
111 if (info == NULL) {
112 return NULL;
114 info->name = talloc_strdup(info, state->netbiosname);
115 if (info->name == NULL) {
116 goto fail;
118 info->dns_domain = pdb_ads_domaindn2dns(info, state->domaindn);
119 if (info->dns_domain == NULL) {
120 goto fail;
123 rootdse = tldap_rootdse(state->ld);
124 tmp = tldap_talloc_single_attribute(rootdse, "rootDomainNamingContext",
125 talloc_tos());
126 if (tmp == NULL) {
127 goto fail;
129 info->dns_forest = pdb_ads_domaindn2dns(info, tmp);
130 TALLOC_FREE(tmp);
131 if (info->dns_forest == NULL) {
132 goto fail;
134 info->sid = state->domainsid;
135 info->guid = state->domainguid;
136 return info;
138 fail:
139 TALLOC_FREE(info);
140 return NULL;
143 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
144 struct pdb_methods *m, struct samu *sam)
146 struct pdb_ads_state *state = talloc_get_type_abort(
147 m->private_data, struct pdb_ads_state);
148 struct pdb_ads_samu_private *result;
149 char *sidstr, *filter;
150 NTSTATUS status;
152 result = (struct pdb_ads_samu_private *)
153 pdb_get_backend_private_data(sam, m);
155 if (result != NULL) {
156 return talloc_get_type_abort(
157 result, struct pdb_ads_samu_private);
160 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), pdb_get_user_sid(sam));
161 if (sidstr == NULL) {
162 return NULL;
165 filter = talloc_asprintf(
166 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
167 TALLOC_FREE(sidstr);
168 if (filter == NULL) {
169 return NULL;
172 status = pdb_ads_getsamupriv(state, filter, sam, &result);
173 TALLOC_FREE(filter);
174 if (!NT_STATUS_IS_OK(status)) {
175 return NULL;
178 return result;
181 static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m,
182 struct samu *sam,
183 struct pdb_ads_samu_private *priv)
185 struct pdb_ads_state *state = talloc_get_type_abort(
186 m->private_data, struct pdb_ads_state);
187 TALLOC_CTX *frame = talloc_stackframe();
188 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
189 struct tldap_message *entry = priv->ldapmsg;
190 char *str;
191 time_t tmp_time;
192 struct dom_sid sid;
193 uint64_t n;
194 DATA_BLOB blob;
196 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
197 if (str == NULL) {
198 DEBUG(10, ("no samAccountName\n"));
199 goto fail;
201 pdb_set_username(sam, str, PDB_SET);
203 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
204 pdb_set_logon_time(sam, tmp_time, PDB_SET);
206 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
207 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
209 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
210 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
212 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
213 pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
216 str = tldap_talloc_single_attribute(entry, "displayName",
217 talloc_tos());
218 if (str != NULL) {
219 pdb_set_fullname(sam, str, PDB_SET);
222 str = tldap_talloc_single_attribute(entry, "homeDirectory",
223 talloc_tos());
224 if (str != NULL) {
225 pdb_set_homedir(sam, str, PDB_SET);
228 str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
229 if (str != NULL) {
230 pdb_set_dir_drive(sam, str, PDB_SET);
233 str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
234 if (str != NULL) {
235 pdb_set_logon_script(sam, str, PDB_SET);
238 str = tldap_talloc_single_attribute(entry, "profilePath",
239 talloc_tos());
240 if (str != NULL) {
241 pdb_set_profile_path(sam, str, PDB_SET);
244 str = tldap_talloc_single_attribute(entry, "profilePath",
245 talloc_tos());
246 if (str != NULL) {
247 pdb_set_profile_path(sam, str, PDB_SET);
250 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
251 DEBUG(10, ("Could not pull SID\n"));
252 goto fail;
254 pdb_set_user_sid(sam, &sid, PDB_SET);
256 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
257 DEBUG(10, ("Could not pull userAccountControl\n"));
258 goto fail;
260 pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
262 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
263 if (blob.length != NT_HASH_LEN) {
264 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
265 (int)blob.length, NT_HASH_LEN));
266 goto fail;
268 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
271 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
272 if (blob.length != LM_HASH_LEN) {
273 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
274 (int)blob.length, LM_HASH_LEN));
275 goto fail;
277 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
280 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
281 sid_compose(&sid, &state->domainsid, n);
282 pdb_set_group_sid(sam, &sid, PDB_SET);
285 status = NT_STATUS_OK;
286 fail:
287 TALLOC_FREE(frame);
288 return status;
291 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
292 struct tldap_message *existing,
293 TALLOC_CTX *mem_ctx,
294 int *pnum_mods, struct tldap_mod **pmods,
295 struct samu *sam)
297 bool ret = true;
298 DATA_BLOB blob;
300 /* TODO: All fields :-) */
302 ret &= tldap_make_mod_fmt(
303 existing, mem_ctx, pnum_mods, pmods, "displayName",
304 "%s", pdb_get_fullname(sam));
306 blob = data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN);
307 if (blob.data != NULL) {
308 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
309 "unicodePwd", 1, &blob);
312 blob = data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN);
313 if (blob.data != NULL) {
314 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
315 "dBCSPwd", 1, &blob);
318 ret &= tldap_make_mod_fmt(
319 existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
320 "%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
322 ret &= tldap_make_mod_fmt(
323 existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
324 "%s", pdb_get_homedir(sam));
326 ret &= tldap_make_mod_fmt(
327 existing, mem_ctx, pnum_mods, pmods, "homeDrive",
328 "%s", pdb_get_dir_drive(sam));
330 ret &= tldap_make_mod_fmt(
331 existing, mem_ctx, pnum_mods, pmods, "scriptPath",
332 "%s", pdb_get_logon_script(sam));
334 ret &= tldap_make_mod_fmt(
335 existing, mem_ctx, pnum_mods, pmods, "profilePath",
336 "%s", pdb_get_profile_path(sam));
338 return ret;
341 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
342 const char *filter,
343 TALLOC_CTX *mem_ctx,
344 struct pdb_ads_samu_private **presult)
346 const char * attrs[] = {
347 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
348 "sAMAccountName", "displayName", "homeDirectory",
349 "homeDrive", "scriptPath", "profilePath", "description",
350 "userWorkstations", "comment", "userParameters", "objectSid",
351 "primaryGroupID", "userAccountControl", "logonHours",
352 "badPwdCount", "logonCount", "countryCode", "codePage",
353 "unicodePwd", "dBCSPwd" };
354 struct tldap_message **users;
355 int rc, count;
356 struct pdb_ads_samu_private *result;
358 result = talloc(mem_ctx, struct pdb_ads_samu_private);
359 if (result == NULL) {
360 return NT_STATUS_NO_MEMORY;
363 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
364 attrs, ARRAY_SIZE(attrs), 0, result,
365 &users, "%s", filter);
366 if (rc != TLDAP_SUCCESS) {
367 DEBUG(10, ("ldap_search failed %s\n",
368 tldap_errstr(talloc_tos(), state->ld, rc)));
369 TALLOC_FREE(result);
370 return NT_STATUS_LDAP(rc);
373 count = talloc_array_length(users);
374 if (count != 1) {
375 DEBUG(10, ("Expected 1 user, got %d\n", count));
376 TALLOC_FREE(result);
377 return NT_STATUS_INTERNAL_DB_CORRUPTION;
380 result->ldapmsg = users[0];
381 if (!tldap_entry_dn(result->ldapmsg, &result->dn)) {
382 DEBUG(10, ("Could not extract dn\n"));
383 TALLOC_FREE(result);
384 return NT_STATUS_INTERNAL_DB_CORRUPTION;
387 *presult = result;
388 return NT_STATUS_OK;
391 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
392 struct pdb_ads_state *state,
393 struct samu *sam_acct,
394 const char *filter)
396 struct pdb_ads_samu_private *priv;
397 NTSTATUS status;
399 status = pdb_ads_getsamupriv(state, filter, sam_acct, &priv);
400 if (!NT_STATUS_IS_OK(status)) {
401 DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n",
402 nt_errstr(status)));
403 return status;
406 status = pdb_ads_init_sam_from_priv(m, sam_acct, priv);
407 if (!NT_STATUS_IS_OK(status)) {
408 DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n",
409 nt_errstr(status)));
410 TALLOC_FREE(priv);
411 return status;
414 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
415 return NT_STATUS_OK;
418 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
419 struct samu *sam_acct,
420 const char *username)
422 struct pdb_ads_state *state = talloc_get_type_abort(
423 m->private_data, struct pdb_ads_state);
424 char *filter;
426 filter = talloc_asprintf(
427 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
428 username);
429 NT_STATUS_HAVE_NO_MEMORY(filter);
431 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
434 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
435 struct samu *sam_acct,
436 const struct dom_sid *sid)
438 struct pdb_ads_state *state = talloc_get_type_abort(
439 m->private_data, struct pdb_ads_state);
440 char *sidstr, *filter;
442 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
443 NT_STATUS_HAVE_NO_MEMORY(sidstr);
445 filter = talloc_asprintf(
446 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
447 TALLOC_FREE(sidstr);
448 NT_STATUS_HAVE_NO_MEMORY(filter);
450 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
453 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
454 TALLOC_CTX *tmp_ctx,
455 const char *name, uint32 acct_flags,
456 uint32 *rid)
458 struct pdb_ads_state *state = talloc_get_type_abort(
459 m->private_data, struct pdb_ads_state);
460 struct tldap_context *ld;
461 const char *attrs[1] = { "objectSid" };
462 struct tldap_mod *mods = NULL;
463 int num_mods = 0;
464 struct tldap_message **user;
465 struct dom_sid sid;
466 char *dn;
467 int rc;
468 bool ok;
470 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
471 state->domaindn);
472 if (dn == NULL) {
473 return NT_STATUS_NO_MEMORY;
476 ld = pdb_ads_ld(state);
477 if (ld == NULL) {
478 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
481 /* TODO: Create machines etc */
483 ok = true;
484 ok &= tldap_make_mod_fmt(
485 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
486 ok &= tldap_make_mod_fmt(
487 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
488 name);
489 if (!ok) {
490 return NT_STATUS_NO_MEMORY;
494 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
495 if (rc != TLDAP_SUCCESS) {
496 DEBUG(10, ("ldap_add failed %s\n",
497 tldap_errstr(talloc_tos(), ld, rc)));
498 TALLOC_FREE(dn);
499 return NT_STATUS_LDAP(rc);
502 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
503 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
504 &user,
505 "(&(objectclass=user)(samaccountname=%s))",
506 name);
507 if (rc != TLDAP_SUCCESS) {
508 DEBUG(10, ("Could not find just created user %s: %s\n",
509 name, tldap_errstr(talloc_tos(), state->ld, rc)));
510 TALLOC_FREE(dn);
511 return NT_STATUS_LDAP(rc);
514 if (talloc_array_length(user) != 1) {
515 DEBUG(10, ("Got %d users, expected one\n",
516 (int)talloc_array_length(user)));
517 TALLOC_FREE(dn);
518 return NT_STATUS_LDAP(rc);
521 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
522 DEBUG(10, ("Could not fetch objectSid from user %s\n",
523 name));
524 TALLOC_FREE(dn);
525 return NT_STATUS_INTERNAL_DB_CORRUPTION;
528 sid_peek_rid(&sid, rid);
529 TALLOC_FREE(dn);
530 return NT_STATUS_OK;
533 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
534 TALLOC_CTX *tmp_ctx,
535 struct samu *sam)
537 struct pdb_ads_state *state = talloc_get_type_abort(
538 m->private_data, struct pdb_ads_state);
539 NTSTATUS status;
540 struct tldap_context *ld;
541 char *dn;
542 int rc;
544 ld = pdb_ads_ld(state);
545 if (ld == NULL) {
546 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
549 status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
550 &dn);
551 if (!NT_STATUS_IS_OK(status)) {
552 return status;
555 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
556 TALLOC_FREE(dn);
557 if (rc != TLDAP_SUCCESS) {
558 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
559 tldap_errstr(talloc_tos(), ld, rc)));
560 return NT_STATUS_LDAP(rc);
562 return NT_STATUS_OK;
565 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
566 struct samu *sampass)
568 return NT_STATUS_NOT_IMPLEMENTED;
571 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
572 struct samu *sam)
574 struct pdb_ads_state *state = talloc_get_type_abort(
575 m->private_data, struct pdb_ads_state);
576 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
577 struct tldap_context *ld;
578 struct tldap_mod *mods = NULL;
579 int rc, num_mods = 0;
581 ld = pdb_ads_ld(state);
582 if (ld == NULL) {
583 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
586 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
587 &num_mods, &mods, sam)) {
588 return NT_STATUS_NO_MEMORY;
591 if (num_mods == 0) {
592 /* Nothing to do, just return success */
593 return NT_STATUS_OK;
596 rc = tldap_modify(ld, priv->dn, num_mods, mods, NULL, 0,
597 NULL, 0);
598 TALLOC_FREE(mods);
599 if (rc != TLDAP_SUCCESS) {
600 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
601 tldap_errstr(talloc_tos(), ld, rc)));
602 return NT_STATUS_LDAP(rc);
605 return NT_STATUS_OK;
608 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
609 struct samu *username)
611 return NT_STATUS_NOT_IMPLEMENTED;
614 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
615 struct samu *oldname,
616 const char *newname)
618 return NT_STATUS_NOT_IMPLEMENTED;
621 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
622 struct samu *sam_acct,
623 bool success)
625 return NT_STATUS_NOT_IMPLEMENTED;
628 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
629 const char *filter)
631 struct pdb_ads_state *state = talloc_get_type_abort(
632 m->private_data, struct pdb_ads_state);
633 const char *attrs[4] = { "objectSid", "description", "samAccountName",
634 "groupType" };
635 char *str;
636 struct tldap_message **group;
637 uint32_t grouptype;
638 int rc;
640 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
641 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
642 &group, "%s", filter);
643 if (rc != TLDAP_SUCCESS) {
644 DEBUG(10, ("ldap_search failed %s\n",
645 tldap_errstr(talloc_tos(), state->ld, rc)));
646 return NT_STATUS_LDAP(rc);
648 if (talloc_array_length(group) != 1) {
649 DEBUG(10, ("Expected 1 user, got %d\n",
650 (int)talloc_array_length(group)));
651 return NT_STATUS_INTERNAL_DB_CORRUPTION;
654 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
655 return NT_STATUS_INTERNAL_DB_CORRUPTION;
657 map->gid = pdb_ads_sid2gid(&map->sid);
659 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
660 return NT_STATUS_INTERNAL_DB_CORRUPTION;
662 switch (grouptype) {
663 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
664 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
665 map->sid_name_use = SID_NAME_ALIAS;
666 break;
667 case GTYPE_SECURITY_GLOBAL_GROUP:
668 map->sid_name_use = SID_NAME_DOM_GRP;
669 break;
670 default:
671 return NT_STATUS_INTERNAL_DB_CORRUPTION;
674 str = tldap_talloc_single_attribute(group[0], "samAccountName",
675 talloc_tos());
676 if (str == NULL) {
677 return NT_STATUS_INTERNAL_DB_CORRUPTION;
679 fstrcpy(map->nt_name, str);
680 TALLOC_FREE(str);
682 str = tldap_talloc_single_attribute(group[0], "description",
683 talloc_tos());
684 if (str != NULL) {
685 fstrcpy(map->comment, str);
686 TALLOC_FREE(str);
687 } else {
688 map->comment[0] = '\0';
691 TALLOC_FREE(group);
692 return NT_STATUS_OK;
695 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
696 struct dom_sid sid)
698 char *filter;
699 NTSTATUS status;
701 filter = talloc_asprintf(talloc_tos(),
702 "(&(objectsid=%s)(objectclass=group))",
703 sid_string_talloc(talloc_tos(), &sid));
704 if (filter == NULL) {
705 return NT_STATUS_NO_MEMORY;
708 status = pdb_ads_getgrfilter(m, map, filter);
709 TALLOC_FREE(filter);
710 return status;
713 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
714 gid_t gid)
716 struct dom_sid sid;
717 pdb_ads_gid_to_sid(m, gid, &sid);
718 return pdb_ads_getgrsid(m, map, sid);
721 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
722 const char *name)
724 char *filter;
725 NTSTATUS status;
727 filter = talloc_asprintf(talloc_tos(),
728 "(&(samaccountname=%s)(objectclass=group))",
729 name);
730 if (filter == NULL) {
731 return NT_STATUS_NO_MEMORY;
734 status = pdb_ads_getgrfilter(m, map, filter);
735 TALLOC_FREE(filter);
736 return status;
739 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
740 TALLOC_CTX *mem_ctx, const char *name,
741 uint32 *rid)
743 TALLOC_CTX *frame = talloc_stackframe();
744 struct pdb_ads_state *state = talloc_get_type_abort(
745 m->private_data, struct pdb_ads_state);
746 struct tldap_context *ld;
747 const char *attrs[1] = { "objectSid" };
748 int num_mods = 0;
749 struct tldap_mod *mods = NULL;
750 struct tldap_message **alias;
751 struct dom_sid sid;
752 char *dn;
753 int rc;
754 bool ok = true;
756 ld = pdb_ads_ld(state);
757 if (ld == NULL) {
758 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
761 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
762 state->domaindn);
763 if (dn == NULL) {
764 TALLOC_FREE(frame);
765 return NT_STATUS_NO_MEMORY;
768 ok &= tldap_make_mod_fmt(
769 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
770 name);
771 ok &= tldap_make_mod_fmt(
772 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
773 ok &= tldap_make_mod_fmt(
774 NULL, talloc_tos(), &num_mods, &mods, "groupType",
775 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
777 if (!ok) {
778 TALLOC_FREE(frame);
779 return NT_STATUS_NO_MEMORY;
782 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
783 if (rc != TLDAP_SUCCESS) {
784 DEBUG(10, ("ldap_add failed %s\n",
785 tldap_errstr(talloc_tos(), state->ld, rc)));
786 TALLOC_FREE(frame);
787 return NT_STATUS_LDAP(rc);
790 rc = pdb_ads_search_fmt(
791 state, state->domaindn, TLDAP_SCOPE_SUB,
792 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
793 "(&(objectclass=group)(samaccountname=%s))", name);
794 if (rc != TLDAP_SUCCESS) {
795 DEBUG(10, ("Could not find just created alias %s: %s\n",
796 name, tldap_errstr(talloc_tos(), state->ld, rc)));
797 TALLOC_FREE(frame);
798 return NT_STATUS_LDAP(rc);
801 if (talloc_array_length(alias) != 1) {
802 DEBUG(10, ("Got %d alias, expected one\n",
803 (int)talloc_array_length(alias)));
804 TALLOC_FREE(frame);
805 return NT_STATUS_LDAP(rc);
808 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
809 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
810 name));
811 TALLOC_FREE(frame);
812 return NT_STATUS_INTERNAL_DB_CORRUPTION;
815 sid_peek_rid(&sid, rid);
816 TALLOC_FREE(frame);
817 return NT_STATUS_OK;
820 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
821 TALLOC_CTX *mem_ctx, uint32 rid)
823 struct pdb_ads_state *state = talloc_get_type_abort(
824 m->private_data, struct pdb_ads_state);
825 struct tldap_context *ld;
826 struct dom_sid sid;
827 char *sidstr;
828 struct tldap_message **msg;
829 char *dn;
830 int rc;
832 sid_compose(&sid, &state->domainsid, rid);
834 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
835 NT_STATUS_HAVE_NO_MEMORY(sidstr);
837 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
838 NULL, 0, 0, talloc_tos(), &msg,
839 ("(&(objectSid=%s)(objectClass=group))"),
840 sidstr);
841 TALLOC_FREE(sidstr);
842 if (rc != TLDAP_SUCCESS) {
843 DEBUG(10, ("ldap_search failed %s\n",
844 tldap_errstr(talloc_tos(), state->ld, rc)));
845 return NT_STATUS_LDAP(rc);
848 switch talloc_array_length(msg) {
849 case 0:
850 return NT_STATUS_NO_SUCH_GROUP;
851 case 1:
852 break;
853 default:
854 return NT_STATUS_INTERNAL_DB_CORRUPTION;
857 if (!tldap_entry_dn(msg[0], &dn)) {
858 TALLOC_FREE(msg);
859 return NT_STATUS_INTERNAL_DB_CORRUPTION;
862 ld = pdb_ads_ld(state);
863 if (ld == NULL) {
864 TALLOC_FREE(msg);
865 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
868 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
869 TALLOC_FREE(msg);
870 if (rc != TLDAP_SUCCESS) {
871 DEBUG(10, ("ldap_delete failed: %s\n",
872 tldap_errstr(talloc_tos(), state->ld, rc)));
873 return NT_STATUS_LDAP(rc);
876 return NT_STATUS_OK;
879 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
880 GROUP_MAP *map)
882 return NT_STATUS_NOT_IMPLEMENTED;
885 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
886 GROUP_MAP *map)
888 return NT_STATUS_NOT_IMPLEMENTED;
891 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
892 struct dom_sid sid)
894 return NT_STATUS_NOT_IMPLEMENTED;
897 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
898 const struct dom_sid *sid,
899 enum lsa_SidType sid_name_use,
900 GROUP_MAP **pp_rmap,
901 size_t *p_num_entries,
902 bool unix_only)
904 return NT_STATUS_NOT_IMPLEMENTED;
907 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
908 TALLOC_CTX *mem_ctx,
909 const struct dom_sid *group,
910 uint32 **pmembers,
911 size_t *pnum_members)
913 struct pdb_ads_state *state = talloc_get_type_abort(
914 m->private_data, struct pdb_ads_state);
915 const char *attrs[1] = { "member" };
916 char *sidstr;
917 struct tldap_message **msg;
918 int i, rc, num_members;
919 DATA_BLOB *blobs;
920 uint32_t *members;
922 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), group);
923 NT_STATUS_HAVE_NO_MEMORY(sidstr);
925 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
926 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
927 &msg, "(objectsid=%s)", sidstr);
928 TALLOC_FREE(sidstr);
929 if (rc != TLDAP_SUCCESS) {
930 DEBUG(10, ("ldap_search failed %s\n",
931 tldap_errstr(talloc_tos(), state->ld, rc)));
932 return NT_STATUS_LDAP(rc);
934 switch talloc_array_length(msg) {
935 case 0:
936 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
937 break;
938 case 1:
939 break;
940 default:
941 return NT_STATUS_INTERNAL_DB_CORRUPTION;
942 break;
945 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
946 return NT_STATUS_INTERNAL_DB_CORRUPTION;
949 members = talloc_array(mem_ctx, uint32_t, num_members);
950 if (members == NULL) {
951 return NT_STATUS_NO_MEMORY;
954 for (i=0; i<num_members; i++) {
955 struct dom_sid sid;
956 if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
957 || !sid_peek_rid(&sid, &members[i])) {
958 TALLOC_FREE(members);
959 return NT_STATUS_INTERNAL_DB_CORRUPTION;
963 *pmembers = members;
964 *pnum_members = num_members;
965 return NT_STATUS_OK;
968 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
969 TALLOC_CTX *mem_ctx,
970 struct samu *user,
971 struct dom_sid **pp_sids,
972 gid_t **pp_gids,
973 size_t *p_num_groups)
975 struct pdb_ads_state *state = talloc_get_type_abort(
976 m->private_data, struct pdb_ads_state);
977 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
978 m, user);
979 const char *attrs[1] = { "objectSid" };
980 struct tldap_message **groups;
981 int i, rc, count;
982 size_t num_groups;
983 struct dom_sid *group_sids;
984 gid_t *gids;
986 rc = pdb_ads_search_fmt(
987 state, state->domaindn, TLDAP_SCOPE_SUB,
988 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
989 "(&(member=%s)(grouptype=%d)(objectclass=group))",
990 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
991 if (rc != TLDAP_SUCCESS) {
992 DEBUG(10, ("ldap_search failed %s\n",
993 tldap_errstr(talloc_tos(), state->ld, rc)));
994 return NT_STATUS_LDAP(rc);
997 count = talloc_array_length(groups);
999 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
1000 if (group_sids == NULL) {
1001 return NT_STATUS_NO_MEMORY;
1003 gids = talloc_array(mem_ctx, gid_t, count);
1004 if (gids == NULL) {
1005 TALLOC_FREE(group_sids);
1006 return NT_STATUS_NO_MEMORY;
1008 num_groups = 0;
1010 for (i=0; i<count; i++) {
1011 if (!tldap_pull_binsid(groups[i], "objectSid",
1012 &group_sids[num_groups])) {
1013 continue;
1015 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
1017 num_groups += 1;
1018 if (num_groups == count) {
1019 break;
1023 *pp_sids = group_sids;
1024 *pp_gids = gids;
1025 *p_num_groups = num_groups;
1026 return NT_STATUS_OK;
1029 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
1030 TALLOC_CTX *mem_ctx,
1031 struct samu *user)
1033 return NT_STATUS_NOT_IMPLEMENTED;
1036 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
1037 TALLOC_CTX *mem_ctx,
1038 uint32 grouprid, uint32 memberrid,
1039 int mod_op)
1041 struct pdb_ads_state *state = talloc_get_type_abort(
1042 m->private_data, struct pdb_ads_state);
1043 TALLOC_CTX *frame = talloc_stackframe();
1044 struct tldap_context *ld;
1045 struct dom_sid groupsid, membersid;
1046 char *groupdn, *memberdn;
1047 struct tldap_mod *mods;
1048 int rc;
1049 NTSTATUS status;
1051 ld = pdb_ads_ld(state);
1052 if (ld == NULL) {
1053 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1056 sid_compose(&groupsid, &state->domainsid, grouprid);
1057 sid_compose(&membersid, &state->domainsid, memberrid);
1059 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
1060 if (!NT_STATUS_IS_OK(status)) {
1061 TALLOC_FREE(frame);
1062 return NT_STATUS_NO_SUCH_GROUP;
1064 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
1065 if (!NT_STATUS_IS_OK(status)) {
1066 TALLOC_FREE(frame);
1067 return NT_STATUS_NO_SUCH_USER;
1070 mods = NULL;
1072 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1073 "member", memberdn)) {
1074 TALLOC_FREE(frame);
1075 return NT_STATUS_NO_MEMORY;
1078 rc = tldap_modify(ld, groupdn, 1, mods, NULL, 0, NULL, 0);
1079 TALLOC_FREE(frame);
1080 if (rc != TLDAP_SUCCESS) {
1081 DEBUG(10, ("ldap_modify failed: %s\n",
1082 tldap_errstr(talloc_tos(), state->ld, rc)));
1083 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1084 return NT_STATUS_MEMBER_IN_GROUP;
1086 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1087 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1089 return NT_STATUS_LDAP(rc);
1092 return NT_STATUS_OK;
1095 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
1096 TALLOC_CTX *mem_ctx,
1097 uint32 group_rid, uint32 member_rid)
1099 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1100 TLDAP_MOD_ADD);
1103 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
1104 TALLOC_CTX *mem_ctx,
1105 uint32 group_rid, uint32 member_rid)
1107 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1108 TLDAP_MOD_DELETE);
1111 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
1112 const char *name, uint32 *rid)
1114 TALLOC_CTX *frame = talloc_stackframe();
1115 struct pdb_ads_state *state = talloc_get_type_abort(
1116 m->private_data, struct pdb_ads_state);
1117 struct tldap_context *ld;
1118 const char *attrs[1] = { "objectSid" };
1119 int num_mods = 0;
1120 struct tldap_mod *mods = NULL;
1121 struct tldap_message **alias;
1122 struct dom_sid sid;
1123 char *dn;
1124 int rc;
1125 bool ok = true;
1127 ld = pdb_ads_ld(state);
1128 if (ld == NULL) {
1129 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1132 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1133 state->domaindn);
1134 if (dn == NULL) {
1135 TALLOC_FREE(frame);
1136 return NT_STATUS_NO_MEMORY;
1139 ok &= tldap_make_mod_fmt(
1140 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
1141 name);
1142 ok &= tldap_make_mod_fmt(
1143 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
1144 ok &= tldap_make_mod_fmt(
1145 NULL, talloc_tos(), &num_mods, &mods, "groupType",
1146 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1148 if (!ok) {
1149 TALLOC_FREE(frame);
1150 return NT_STATUS_NO_MEMORY;
1153 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1154 if (rc != TLDAP_SUCCESS) {
1155 DEBUG(10, ("ldap_add failed %s\n",
1156 tldap_errstr(talloc_tos(), state->ld, rc)));
1157 TALLOC_FREE(frame);
1158 return NT_STATUS_LDAP(rc);
1161 rc = pdb_ads_search_fmt(
1162 state, state->domaindn, TLDAP_SCOPE_SUB,
1163 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1164 "(&(objectclass=group)(samaccountname=%s))", name);
1165 if (rc != TLDAP_SUCCESS) {
1166 DEBUG(10, ("Could not find just created alias %s: %s\n",
1167 name, tldap_errstr(talloc_tos(), state->ld, rc)));
1168 TALLOC_FREE(frame);
1169 return NT_STATUS_LDAP(rc);
1172 if (talloc_array_length(alias) != 1) {
1173 DEBUG(10, ("Got %d alias, expected one\n",
1174 (int)talloc_array_length(alias)));
1175 TALLOC_FREE(frame);
1176 return NT_STATUS_LDAP(rc);
1179 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1180 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1181 name));
1182 TALLOC_FREE(frame);
1183 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1186 sid_peek_rid(&sid, rid);
1187 TALLOC_FREE(frame);
1188 return NT_STATUS_OK;
1191 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1192 const struct dom_sid *sid)
1194 struct pdb_ads_state *state = talloc_get_type_abort(
1195 m->private_data, struct pdb_ads_state);
1196 struct tldap_context *ld;
1197 struct tldap_message **alias;
1198 char *sidstr, *dn = NULL;
1199 int rc;
1201 ld = pdb_ads_ld(state);
1202 if (ld == NULL) {
1203 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1206 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1207 if (sidstr == NULL) {
1208 return NT_STATUS_NO_MEMORY;
1211 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1212 NULL, 0, 0, talloc_tos(), &alias,
1213 "(&(objectSid=%s)(objectclass=group)"
1214 "(|(grouptype=%d)(grouptype=%d)))",
1215 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1216 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1217 TALLOC_FREE(sidstr);
1218 if (rc != TLDAP_SUCCESS) {
1219 DEBUG(10, ("ldap_search failed: %s\n",
1220 tldap_errstr(talloc_tos(), state->ld, rc)));
1221 return NT_STATUS_LDAP(rc);
1223 if (talloc_array_length(alias) != 1) {
1224 DEBUG(10, ("Expected 1 alias, got %d\n",
1225 (int)talloc_array_length(alias)));
1226 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1228 if (!tldap_entry_dn(alias[0], &dn)) {
1229 DEBUG(10, ("Could not get DN for alias %s\n",
1230 sid_string_dbg(sid)));
1231 return NT_STATUS_INTERNAL_ERROR;
1234 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
1235 if (rc != TLDAP_SUCCESS) {
1236 DEBUG(10, ("ldap_delete failed: %s\n",
1237 tldap_errstr(talloc_tos(), state->ld, rc)));
1238 return NT_STATUS_LDAP(rc);
1241 return NT_STATUS_OK;
1244 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1245 const struct dom_sid *sid,
1246 struct acct_info *info)
1248 struct pdb_ads_state *state = talloc_get_type_abort(
1249 m->private_data, struct pdb_ads_state);
1250 struct tldap_context *ld;
1251 const char *attrs[3] = { "objectSid", "description",
1252 "samAccountName" };
1253 struct tldap_message **msg;
1254 char *sidstr, *dn;
1255 int rc;
1256 struct tldap_mod *mods;
1257 int num_mods;
1258 bool ok;
1260 ld = pdb_ads_ld(state);
1261 if (ld == NULL) {
1262 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1265 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1266 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1268 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1269 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1270 &msg, "(&(objectSid=%s)(objectclass=group)"
1271 "(|(grouptype=%d)(grouptype=%d)))",
1272 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1273 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1274 TALLOC_FREE(sidstr);
1275 if (rc != TLDAP_SUCCESS) {
1276 DEBUG(10, ("ldap_search failed %s\n",
1277 tldap_errstr(talloc_tos(), state->ld, rc)));
1278 return NT_STATUS_LDAP(rc);
1280 switch talloc_array_length(msg) {
1281 case 0:
1282 return NT_STATUS_NO_SUCH_ALIAS;
1283 case 1:
1284 break;
1285 default:
1286 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1289 if (!tldap_entry_dn(msg[0], &dn)) {
1290 TALLOC_FREE(msg);
1291 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1294 mods = NULL;
1295 num_mods = 0;
1296 ok = true;
1298 ok &= tldap_make_mod_fmt(
1299 msg[0], msg, &num_mods, &mods, "description",
1300 "%s", info->acct_desc);
1301 ok &= tldap_make_mod_fmt(
1302 msg[0], msg, &num_mods, &mods, "samAccountName",
1303 "%s", info->acct_name);
1304 if (!ok) {
1305 TALLOC_FREE(msg);
1306 return NT_STATUS_NO_MEMORY;
1308 if (num_mods == 0) {
1309 /* no change */
1310 TALLOC_FREE(msg);
1311 return NT_STATUS_OK;
1314 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1315 TALLOC_FREE(msg);
1316 if (rc != TLDAP_SUCCESS) {
1317 DEBUG(10, ("ldap_modify failed: %s\n",
1318 tldap_errstr(talloc_tos(), state->ld, rc)));
1319 return NT_STATUS_LDAP(rc);
1321 return NT_STATUS_OK;
1324 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1325 const struct dom_sid *sid,
1326 TALLOC_CTX *mem_ctx, char **pdn)
1328 struct tldap_message **msg;
1329 char *sidstr, *dn;
1330 int rc;
1332 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1333 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1335 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1336 NULL, 0, 0, talloc_tos(), &msg,
1337 "(objectsid=%s)", sidstr);
1338 TALLOC_FREE(sidstr);
1339 if (rc != TLDAP_SUCCESS) {
1340 DEBUG(10, ("ldap_search failed %s\n",
1341 tldap_errstr(talloc_tos(), state->ld, rc)));
1342 return NT_STATUS_LDAP(rc);
1345 switch talloc_array_length(msg) {
1346 case 0:
1347 return NT_STATUS_NOT_FOUND;
1348 case 1:
1349 break;
1350 default:
1351 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1354 if (!tldap_entry_dn(msg[0], &dn)) {
1355 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1358 dn = talloc_strdup(mem_ctx, dn);
1359 if (dn == NULL) {
1360 return NT_STATUS_NO_MEMORY;
1362 TALLOC_FREE(msg);
1364 *pdn = dn;
1365 return NT_STATUS_OK;
1368 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1369 const struct dom_sid *alias,
1370 const struct dom_sid *member,
1371 int mod_op)
1373 struct pdb_ads_state *state = talloc_get_type_abort(
1374 m->private_data, struct pdb_ads_state);
1375 struct tldap_context *ld;
1376 TALLOC_CTX *frame = talloc_stackframe();
1377 struct tldap_mod *mods;
1378 int rc;
1379 char *aliasdn, *memberdn;
1380 NTSTATUS status;
1382 ld = pdb_ads_ld(state);
1383 if (ld == NULL) {
1384 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1387 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1388 if (!NT_STATUS_IS_OK(status)) {
1389 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1390 sid_string_dbg(alias), nt_errstr(status)));
1391 TALLOC_FREE(frame);
1392 return NT_STATUS_NO_SUCH_ALIAS;
1394 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1395 if (!NT_STATUS_IS_OK(status)) {
1396 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1397 sid_string_dbg(member), nt_errstr(status)));
1398 TALLOC_FREE(frame);
1399 return status;
1402 mods = NULL;
1404 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1405 "member", memberdn)) {
1406 TALLOC_FREE(frame);
1407 return NT_STATUS_NO_MEMORY;
1410 rc = tldap_modify(ld, aliasdn, 1, mods, NULL, 0, NULL, 0);
1411 TALLOC_FREE(frame);
1412 if (rc != TLDAP_SUCCESS) {
1413 DEBUG(10, ("ldap_modify failed: %s\n",
1414 tldap_errstr(talloc_tos(), state->ld, rc)));
1415 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1416 return NT_STATUS_MEMBER_IN_ALIAS;
1418 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1419 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1421 return NT_STATUS_LDAP(rc);
1424 return NT_STATUS_OK;
1427 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1428 const struct dom_sid *alias,
1429 const struct dom_sid *member)
1431 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1434 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1435 const struct dom_sid *alias,
1436 const struct dom_sid *member)
1438 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1441 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
1442 struct dom_sid *psid)
1444 const char *attrs[1] = { "objectSid" };
1445 struct tldap_message **msg;
1446 char *dn;
1447 size_t len;
1448 int rc;
1449 bool ret;
1451 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1452 dnblob->data, dnblob->length, &dn, &len,
1453 false)) {
1454 return false;
1456 rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
1457 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1458 &msg, "(objectclass=*)");
1459 TALLOC_FREE(dn);
1460 if (talloc_array_length(msg) != 1) {
1461 DEBUG(10, ("Got %d objects, expected one\n",
1462 (int)talloc_array_length(msg)));
1463 TALLOC_FREE(msg);
1464 return false;
1467 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1468 TALLOC_FREE(msg);
1469 return ret;
1472 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1473 const struct dom_sid *alias,
1474 TALLOC_CTX *mem_ctx,
1475 struct dom_sid **pmembers,
1476 size_t *pnum_members)
1478 struct pdb_ads_state *state = talloc_get_type_abort(
1479 m->private_data, struct pdb_ads_state);
1480 const char *attrs[1] = { "member" };
1481 char *sidstr;
1482 struct tldap_message **msg;
1483 int i, rc, num_members;
1484 DATA_BLOB *blobs;
1485 struct dom_sid *members;
1487 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), alias);
1488 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1490 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1491 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1492 &msg, "(objectsid=%s)", sidstr);
1493 TALLOC_FREE(sidstr);
1494 if (rc != TLDAP_SUCCESS) {
1495 DEBUG(10, ("ldap_search failed %s\n",
1496 tldap_errstr(talloc_tos(), state->ld, rc)));
1497 return NT_STATUS_LDAP(rc);
1499 switch talloc_array_length(msg) {
1500 case 0:
1501 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1502 break;
1503 case 1:
1504 break;
1505 default:
1506 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1507 break;
1510 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1511 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1514 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1515 if (members == NULL) {
1516 return NT_STATUS_NO_MEMORY;
1519 for (i=0; i<num_members; i++) {
1520 if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
1521 TALLOC_FREE(members);
1522 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1526 *pmembers = members;
1527 *pnum_members = num_members;
1528 return NT_STATUS_OK;
1531 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1532 TALLOC_CTX *mem_ctx,
1533 const struct dom_sid *domain_sid,
1534 const struct dom_sid *members,
1535 size_t num_members,
1536 uint32_t **palias_rids,
1537 size_t *pnum_alias_rids)
1539 struct pdb_ads_state *state = talloc_get_type_abort(
1540 m->private_data, struct pdb_ads_state);
1541 const char *attrs[1] = { "objectSid" };
1542 struct tldap_message **msg = NULL;
1543 uint32_t *alias_rids = NULL;
1544 size_t num_alias_rids = 0;
1545 int i, rc, count;
1546 bool got_members = false;
1547 char *filter;
1548 NTSTATUS status;
1551 * TODO: Get the filter right so that we only get the aliases from
1552 * either the SAM or BUILTIN
1555 filter = talloc_asprintf(talloc_tos(),
1556 "(&(|(grouptype=%d)(grouptype=%d))"
1557 "(objectclass=group)(|",
1558 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1559 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1560 if (filter == NULL) {
1561 return NT_STATUS_NO_MEMORY;
1564 for (i=0; i<num_members; i++) {
1565 char *dn;
1567 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1568 if (!NT_STATUS_IS_OK(status)) {
1569 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1570 sid_string_dbg(&members[i]),
1571 nt_errstr(status)));
1572 continue;
1574 filter = talloc_asprintf_append_buffer(
1575 filter, "(member=%s)", dn);
1576 TALLOC_FREE(dn);
1577 if (filter == NULL) {
1578 return NT_STATUS_NO_MEMORY;
1580 got_members = true;
1583 if (!got_members) {
1584 goto done;
1587 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1588 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1589 &msg, "%s))", filter);
1590 TALLOC_FREE(filter);
1591 if (rc != TLDAP_SUCCESS) {
1592 DEBUG(10, ("tldap_search failed %s\n",
1593 tldap_errstr(talloc_tos(), state->ld, rc)));
1594 return NT_STATUS_LDAP(rc);
1597 count = talloc_array_length(msg);
1598 if (count == 0) {
1599 goto done;
1602 alias_rids = talloc_array(mem_ctx, uint32_t, count);
1603 if (alias_rids == NULL) {
1604 TALLOC_FREE(msg);
1605 return NT_STATUS_NO_MEMORY;
1608 for (i=0; i<count; i++) {
1609 struct dom_sid sid;
1611 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1612 DEBUG(10, ("Could not pull SID for member %d\n", i));
1613 continue;
1615 if (sid_peek_check_rid(domain_sid, &sid,
1616 &alias_rids[num_alias_rids])) {
1617 num_alias_rids += 1;
1620 done:
1621 TALLOC_FREE(msg);
1622 *palias_rids = alias_rids;
1623 *pnum_alias_rids = 0;
1624 return NT_STATUS_OK;
1627 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1628 const struct dom_sid *domain_sid,
1629 int num_rids,
1630 uint32 *rids,
1631 const char **names,
1632 enum lsa_SidType *lsa_attrs)
1634 struct pdb_ads_state *state = talloc_get_type_abort(
1635 m->private_data, struct pdb_ads_state);
1636 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1637 int i, num_mapped;
1639 if (num_rids == 0) {
1640 return NT_STATUS_NONE_MAPPED;
1643 num_mapped = 0;
1645 for (i=0; i<num_rids; i++) {
1646 struct dom_sid sid;
1647 struct tldap_message **msg;
1648 char *sidstr;
1649 uint32_t attr;
1650 int rc;
1652 lsa_attrs[i] = SID_NAME_UNKNOWN;
1654 sid_compose(&sid, domain_sid, rids[i]);
1656 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
1657 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1659 rc = pdb_ads_search_fmt(state, state->domaindn,
1660 TLDAP_SCOPE_SUB, attrs,
1661 ARRAY_SIZE(attrs), 0, talloc_tos(),
1662 &msg, "(objectsid=%s)", sidstr);
1663 TALLOC_FREE(sidstr);
1664 if (rc != TLDAP_SUCCESS) {
1665 DEBUG(10, ("ldap_search failed %s\n",
1666 tldap_errstr(talloc_tos(), state->ld, rc)));
1667 continue;
1670 switch talloc_array_length(msg) {
1671 case 0:
1672 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1673 continue;
1674 case 1:
1675 break;
1676 default:
1677 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1680 names[i] = tldap_talloc_single_attribute(
1681 msg[0], "samAccountName", talloc_tos());
1682 if (names[i] == NULL) {
1683 DEBUG(10, ("no samAccountName\n"));
1684 continue;
1686 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1687 DEBUG(10, ("no samAccountType"));
1688 continue;
1690 lsa_attrs[i] = ds_atype_map(attr);
1691 num_mapped += 1;
1694 if (num_mapped == 0) {
1695 return NT_STATUS_NONE_MAPPED;
1697 if (num_mapped < num_rids) {
1698 return STATUS_SOME_UNMAPPED;
1700 return NT_STATUS_OK;
1703 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1704 const struct dom_sid *domain_sid,
1705 int num_names,
1706 const char **pp_names,
1707 uint32 *rids,
1708 enum lsa_SidType *attrs)
1710 return NT_STATUS_NOT_IMPLEMENTED;
1713 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1714 enum pdb_policy_type type,
1715 uint32_t *value)
1717 return account_policy_get(type, value)
1718 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1721 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1722 enum pdb_policy_type type,
1723 uint32_t value)
1725 return account_policy_set(type, value)
1726 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1729 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1730 time_t *seq_num)
1732 return NT_STATUS_NOT_IMPLEMENTED;
1735 struct pdb_ads_search_state {
1736 uint32_t acct_flags;
1737 struct samr_displayentry *entries;
1738 uint32_t num_entries;
1739 ssize_t array_size;
1740 uint32_t current;
1743 static bool pdb_ads_next_entry(struct pdb_search *search,
1744 struct samr_displayentry *entry)
1746 struct pdb_ads_search_state *state = talloc_get_type_abort(
1747 search->private_data, struct pdb_ads_search_state);
1749 if (state->current == state->num_entries) {
1750 return false;
1753 entry->idx = state->entries[state->current].idx;
1754 entry->rid = state->entries[state->current].rid;
1755 entry->acct_flags = state->entries[state->current].acct_flags;
1757 entry->account_name = talloc_strdup(
1758 search, state->entries[state->current].account_name);
1759 entry->fullname = talloc_strdup(
1760 search, state->entries[state->current].fullname);
1761 entry->description = talloc_strdup(
1762 search, state->entries[state->current].description);
1764 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1765 || (entry->description == NULL)) {
1766 DEBUG(0, ("talloc_strdup failed\n"));
1767 return false;
1770 state->current += 1;
1771 return true;
1774 static void pdb_ads_search_end(struct pdb_search *search)
1776 struct pdb_ads_search_state *state = talloc_get_type_abort(
1777 search->private_data, struct pdb_ads_search_state);
1778 TALLOC_FREE(state);
1781 static bool pdb_ads_search_filter(struct pdb_methods *m,
1782 struct pdb_search *search,
1783 const char *filter,
1784 struct pdb_ads_search_state **pstate)
1786 struct pdb_ads_state *state = talloc_get_type_abort(
1787 m->private_data, struct pdb_ads_state);
1788 struct pdb_ads_search_state *sstate;
1789 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1790 "userAccountControl", "description" };
1791 struct tldap_message **users;
1792 int i, rc, num_users;
1794 sstate = talloc_zero(search, struct pdb_ads_search_state);
1795 if (sstate == NULL) {
1796 return false;
1799 rc = pdb_ads_search_fmt(
1800 state, state->domaindn, TLDAP_SCOPE_SUB,
1801 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1802 "%s", filter);
1803 if (rc != TLDAP_SUCCESS) {
1804 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1805 tldap_errstr(talloc_tos(), state->ld, rc)));
1806 return false;
1809 num_users = talloc_array_length(users);
1811 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1812 num_users);
1813 if (sstate->entries == NULL) {
1814 DEBUG(10, ("talloc failed\n"));
1815 return false;
1818 sstate->num_entries = 0;
1820 for (i=0; i<num_users; i++) {
1821 struct samr_displayentry *e;
1822 struct dom_sid sid;
1824 e = &sstate->entries[sstate->num_entries];
1826 e->idx = sstate->num_entries;
1827 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1828 DEBUG(10, ("Could not pull sid\n"));
1829 continue;
1831 sid_peek_rid(&sid, &e->rid);
1832 e->acct_flags = ACB_NORMAL;
1833 e->account_name = tldap_talloc_single_attribute(
1834 users[i], "samAccountName", sstate->entries);
1835 if (e->account_name == NULL) {
1836 return false;
1838 e->fullname = tldap_talloc_single_attribute(
1839 users[i], "displayName", sstate->entries);
1840 if (e->fullname == NULL) {
1841 e->fullname = "";
1843 e->description = tldap_talloc_single_attribute(
1844 users[i], "description", sstate->entries);
1845 if (e->description == NULL) {
1846 e->description = "";
1849 sstate->num_entries += 1;
1850 if (sstate->num_entries >= num_users) {
1851 break;
1855 search->private_data = sstate;
1856 search->next_entry = pdb_ads_next_entry;
1857 search->search_end = pdb_ads_search_end;
1858 *pstate = sstate;
1859 return true;
1862 static bool pdb_ads_search_users(struct pdb_methods *m,
1863 struct pdb_search *search,
1864 uint32 acct_flags)
1866 struct pdb_ads_search_state *sstate;
1867 bool ret;
1869 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1870 if (!ret) {
1871 return false;
1873 sstate->acct_flags = acct_flags;
1874 return true;
1877 static bool pdb_ads_search_groups(struct pdb_methods *m,
1878 struct pdb_search *search)
1880 struct pdb_ads_search_state *sstate;
1881 char *filter;
1882 bool ret;
1884 filter = talloc_asprintf(talloc_tos(),
1885 "(&(grouptype=%d)(objectclass=group))",
1886 GTYPE_SECURITY_GLOBAL_GROUP);
1887 if (filter == NULL) {
1888 return false;
1890 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1891 TALLOC_FREE(filter);
1892 if (!ret) {
1893 return false;
1895 sstate->acct_flags = 0;
1896 return true;
1899 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1900 struct pdb_search *search,
1901 const struct dom_sid *sid)
1903 struct pdb_ads_search_state *sstate;
1904 char *filter;
1905 bool ret;
1907 filter = talloc_asprintf(
1908 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1909 sid_check_is_builtin(sid)
1910 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1911 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1913 if (filter == NULL) {
1914 return false;
1916 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1917 TALLOC_FREE(filter);
1918 if (!ret) {
1919 return false;
1921 sstate->acct_flags = 0;
1922 return true;
1925 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1926 struct dom_sid *sid)
1928 struct pdb_ads_state *state = talloc_get_type_abort(
1929 m->private_data, struct pdb_ads_state);
1930 sid_compose(sid, &state->domainsid, uid);
1931 return true;
1934 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1935 struct dom_sid *sid)
1937 struct pdb_ads_state *state = talloc_get_type_abort(
1938 m->private_data, struct pdb_ads_state);
1939 sid_compose(sid, &state->domainsid, gid);
1940 return true;
1943 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
1944 union unid_t *id, enum lsa_SidType *type)
1946 struct pdb_ads_state *state = talloc_get_type_abort(
1947 m->private_data, struct pdb_ads_state);
1948 struct tldap_message **msg;
1949 char *sidstr;
1950 uint32_t rid;
1951 int rc;
1954 * This is a big, big hack: Just hard-code the rid as uid/gid.
1957 sid_peek_rid(sid, &rid);
1959 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1960 if (sidstr == NULL) {
1961 return false;
1964 rc = pdb_ads_search_fmt(
1965 state, state->domaindn, TLDAP_SCOPE_SUB,
1966 NULL, 0, 0, talloc_tos(), &msg,
1967 "(&(objectsid=%s)(objectclass=user))", sidstr);
1968 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1969 id->uid = rid;
1970 *type = SID_NAME_USER;
1971 TALLOC_FREE(sidstr);
1972 return true;
1975 rc = pdb_ads_search_fmt(
1976 state, state->domaindn, TLDAP_SCOPE_SUB,
1977 NULL, 0, 0, talloc_tos(), &msg,
1978 "(&(objectsid=%s)(objectclass=group))", sidstr);
1979 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1980 id->gid = rid;
1981 *type = SID_NAME_DOM_GRP;
1982 TALLOC_FREE(sidstr);
1983 return true;
1986 TALLOC_FREE(sidstr);
1987 return false;
1990 static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
1992 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
1995 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1997 return false;
2000 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
2001 const char *domain, char** pwd,
2002 struct dom_sid *sid,
2003 time_t *pass_last_set_time)
2005 return false;
2008 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
2009 const char* domain, const char* pwd,
2010 const struct dom_sid *sid)
2012 return false;
2015 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
2016 const char *domain)
2018 return false;
2021 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
2022 TALLOC_CTX *mem_ctx,
2023 uint32 *num_domains,
2024 struct trustdom_info ***domains)
2026 *num_domains = 0;
2027 *domains = NULL;
2028 return NT_STATUS_OK;
2031 static void pdb_ads_init_methods(struct pdb_methods *m)
2033 m->name = "ads";
2034 m->get_domain_info = pdb_ads_get_domain_info;
2035 m->getsampwnam = pdb_ads_getsampwnam;
2036 m->getsampwsid = pdb_ads_getsampwsid;
2037 m->create_user = pdb_ads_create_user;
2038 m->delete_user = pdb_ads_delete_user;
2039 m->add_sam_account = pdb_ads_add_sam_account;
2040 m->update_sam_account = pdb_ads_update_sam_account;
2041 m->delete_sam_account = pdb_ads_delete_sam_account;
2042 m->rename_sam_account = pdb_ads_rename_sam_account;
2043 m->update_login_attempts = pdb_ads_update_login_attempts;
2044 m->getgrsid = pdb_ads_getgrsid;
2045 m->getgrgid = pdb_ads_getgrgid;
2046 m->getgrnam = pdb_ads_getgrnam;
2047 m->create_dom_group = pdb_ads_create_dom_group;
2048 m->delete_dom_group = pdb_ads_delete_dom_group;
2049 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
2050 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
2051 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
2052 m->enum_group_mapping = pdb_ads_enum_group_mapping;
2053 m->enum_group_members = pdb_ads_enum_group_members;
2054 m->enum_group_memberships = pdb_ads_enum_group_memberships;
2055 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
2056 m->add_groupmem = pdb_ads_add_groupmem;
2057 m->del_groupmem = pdb_ads_del_groupmem;
2058 m->create_alias = pdb_ads_create_alias;
2059 m->delete_alias = pdb_ads_delete_alias;
2060 m->get_aliasinfo = pdb_default_get_aliasinfo;
2061 m->set_aliasinfo = pdb_ads_set_aliasinfo;
2062 m->add_aliasmem = pdb_ads_add_aliasmem;
2063 m->del_aliasmem = pdb_ads_del_aliasmem;
2064 m->enum_aliasmem = pdb_ads_enum_aliasmem;
2065 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
2066 m->lookup_rids = pdb_ads_lookup_rids;
2067 m->lookup_names = pdb_ads_lookup_names;
2068 m->get_account_policy = pdb_ads_get_account_policy;
2069 m->set_account_policy = pdb_ads_set_account_policy;
2070 m->get_seq_num = pdb_ads_get_seq_num;
2071 m->search_users = pdb_ads_search_users;
2072 m->search_groups = pdb_ads_search_groups;
2073 m->search_aliases = pdb_ads_search_aliases;
2074 m->uid_to_sid = pdb_ads_uid_to_sid;
2075 m->gid_to_sid = pdb_ads_gid_to_sid;
2076 m->sid_to_id = pdb_ads_sid_to_id;
2077 m->capabilities = pdb_ads_capabilities;
2078 m->new_rid = pdb_ads_new_rid;
2079 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2080 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2081 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2082 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2085 static void free_private_data(void **vp)
2087 struct pdb_ads_state *state = talloc_get_type_abort(
2088 *vp, struct pdb_ads_state);
2090 TALLOC_FREE(state->ld);
2091 return;
2095 this is used to catch debug messages from events
2097 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2098 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
2100 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2101 const char *fmt, va_list ap)
2103 int samba_level = -1;
2104 char *s = NULL;
2105 switch (level) {
2106 case TLDAP_DEBUG_FATAL:
2107 samba_level = 0;
2108 break;
2109 case TLDAP_DEBUG_ERROR:
2110 samba_level = 1;
2111 break;
2112 case TLDAP_DEBUG_WARNING:
2113 samba_level = 2;
2114 break;
2115 case TLDAP_DEBUG_TRACE:
2116 samba_level = 11;
2117 break;
2120 if (vasprintf(&s, fmt, ap) == -1) {
2121 return;
2123 DEBUG(samba_level, ("tldap: %s", s));
2124 free(s);
2127 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2129 NTSTATUS status;
2130 int fd;
2132 if (tldap_connection_ok(state->ld)) {
2133 return state->ld;
2135 TALLOC_FREE(state->ld);
2137 status = open_socket_out(
2138 (struct sockaddr_storage *)(void *)&state->socket_address,
2139 0, 0, &fd);
2140 if (!NT_STATUS_IS_OK(status)) {
2141 DEBUG(10, ("Could not connect to %s: %s\n",
2142 state->socket_address.sun_path, nt_errstr(status)));
2143 return NULL;
2146 set_blocking(fd, false);
2148 state->ld = tldap_context_create(state, fd);
2149 if (state->ld == NULL) {
2150 close(fd);
2151 return NULL;
2153 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2155 return state->ld;
2158 int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2159 int scope, const char *attrs[], int num_attrs,
2160 int attrsonly,
2161 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2162 const char *fmt, ...)
2164 struct tldap_context *ld;
2165 va_list ap;
2166 int ret;
2168 ld = pdb_ads_ld(state);
2169 if (ld == NULL) {
2170 return TLDAP_SERVER_DOWN;
2173 va_start(ap, fmt);
2174 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2175 mem_ctx, res, fmt, ap);
2176 va_end(ap);
2178 if (ret != TLDAP_SERVER_DOWN) {
2179 return ret;
2182 /* retry once */
2183 ld = pdb_ads_ld(state);
2184 if (ld == NULL) {
2185 return TLDAP_SERVER_DOWN;
2188 va_start(ap, fmt);
2189 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2190 mem_ctx, res, fmt, ap);
2191 va_end(ap);
2192 return ret;
2195 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2196 const char *location)
2198 const char *domain_attrs[2] = { "objectSid", "objectGUID" };
2199 const char *ncname_attrs[1] = { "netbiosname" };
2200 struct tldap_context *ld;
2201 struct tldap_message *rootdse, **domain, **ncname;
2202 TALLOC_CTX *frame = talloc_stackframe();
2203 NTSTATUS status;
2204 int num_domains;
2205 int rc;
2207 ZERO_STRUCT(state->socket_address);
2208 state->socket_address.sun_family = AF_UNIX;
2209 strncpy(state->socket_address.sun_path, location,
2210 sizeof(state->socket_address.sun_path) - 1);
2212 ld = pdb_ads_ld(state);
2213 if (ld == NULL) {
2214 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2215 goto done;
2218 rc = tldap_fetch_rootdse(ld);
2219 if (rc != TLDAP_SUCCESS) {
2220 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2221 tldap_errstr(talloc_tos(), state->ld, rc)));
2222 status = NT_STATUS_LDAP(rc);
2223 goto done;
2225 rootdse = tldap_rootdse(state->ld);
2227 state->domaindn = tldap_talloc_single_attribute(
2228 rootdse, "defaultNamingContext", state);
2229 if (state->domaindn == NULL) {
2230 DEBUG(10, ("Could not get defaultNamingContext\n"));
2231 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2232 goto done;
2234 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2236 state->configdn = tldap_talloc_single_attribute(
2237 rootdse, "configurationNamingContext", state);
2238 if (state->domaindn == NULL) {
2239 DEBUG(10, ("Could not get configurationNamingContext\n"));
2240 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2241 goto done;
2243 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2246 * Figure out our domain's SID
2248 rc = pdb_ads_search_fmt(
2249 state, state->domaindn, TLDAP_SCOPE_BASE,
2250 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2251 talloc_tos(), &domain, "(objectclass=*)");
2252 if (rc != TLDAP_SUCCESS) {
2253 DEBUG(10, ("Could not retrieve domain: %s\n",
2254 tldap_errstr(talloc_tos(), state->ld, rc)));
2255 status = NT_STATUS_LDAP(rc);
2256 goto done;
2259 num_domains = talloc_array_length(domain);
2260 if (num_domains != 1) {
2261 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2262 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2263 goto done;
2265 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2266 DEBUG(10, ("Could not retrieve domain SID\n"));
2267 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2268 goto done;
2270 if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) {
2271 DEBUG(10, ("Could not retrieve domain GUID\n"));
2272 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2273 goto done;
2275 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2278 * Figure out our domain's short name
2280 rc = pdb_ads_search_fmt(
2281 state, state->configdn, TLDAP_SCOPE_SUB,
2282 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2283 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2284 if (rc != TLDAP_SUCCESS) {
2285 DEBUG(10, ("Could not retrieve ncname: %s\n",
2286 tldap_errstr(talloc_tos(), state->ld, rc)));
2287 status = NT_STATUS_LDAP(rc);
2288 goto done;
2290 if (talloc_array_length(ncname) != 1) {
2291 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2292 goto done;
2295 state->netbiosname = tldap_talloc_single_attribute(
2296 ncname[0], "netbiosname", state);
2297 if (state->netbiosname == NULL) {
2298 DEBUG(10, ("Could not get netbiosname\n"));
2299 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2300 goto done;
2302 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2304 if (!strequal(lp_workgroup(), state->netbiosname)) {
2305 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2306 state->netbiosname, lp_workgroup()));
2307 status = NT_STATUS_NO_SUCH_DOMAIN;
2308 goto done;
2311 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2313 status = NT_STATUS_OK;
2314 done:
2315 TALLOC_FREE(frame);
2316 return status;
2319 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2320 const char *location)
2322 struct pdb_methods *m;
2323 struct pdb_ads_state *state;
2324 char *tmp = NULL;
2325 NTSTATUS status;
2327 m = talloc(NULL, struct pdb_methods);
2328 if (m == NULL) {
2329 return NT_STATUS_NO_MEMORY;
2331 state = talloc_zero(m, struct pdb_ads_state);
2332 if (state == NULL) {
2333 goto nomem;
2335 m->private_data = state;
2336 m->free_private_data = free_private_data;
2337 pdb_ads_init_methods(m);
2339 if (location == NULL) {
2340 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2341 lp_private_dir());
2342 location = tmp;
2344 if (location == NULL) {
2345 goto nomem;
2348 status = pdb_ads_connect(state, location);
2349 if (!NT_STATUS_IS_OK(status)) {
2350 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2351 goto fail;
2354 *pdb_method = m;
2355 return NT_STATUS_OK;
2356 nomem:
2357 status = NT_STATUS_NO_MEMORY;
2358 fail:
2359 TALLOC_FREE(m);
2360 return status;
2363 NTSTATUS pdb_ads_init(void);
2364 NTSTATUS pdb_ads_init(void)
2366 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
2367 pdb_init_ads);