s3: Fix Coverity ID 2195: NO_EFFECT
[Samba.git] / source3 / passdb / pdb_ads.c
blob654bc5de6fbeb2727471c5b3eb180435d787c9c0
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"
28 #include "../libds/common/flag_mapping.h"
30 struct pdb_ads_state {
31 struct sockaddr_un socket_address;
32 struct tldap_context *ld;
33 struct dom_sid domainsid;
34 struct GUID domainguid;
35 char *domaindn;
36 char *configdn;
37 char *netbiosname;
40 struct pdb_ads_samu_private {
41 char *dn;
42 struct tldap_message *ldapmsg;
45 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
46 struct dom_sid *sid);
47 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
48 struct dom_sid *psid);
49 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
50 const struct dom_sid *sid,
51 TALLOC_CTX *mem_ctx, char **pdn);
52 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state);
53 static int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
54 int scope, const char *attrs[], int num_attrs,
55 int attrsonly,
56 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
57 const char *fmt, ...);
58 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
59 const char *filter,
60 TALLOC_CTX *mem_ctx,
61 struct pdb_ads_samu_private **presult);
63 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
64 time_t *ptime)
66 uint64_t tmp;
68 if (!tldap_pull_uint64(msg, attr, &tmp)) {
69 return false;
71 *ptime = nt_time_to_unix(tmp);
72 return true;
75 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
77 uint32_t rid;
78 sid_peek_rid(sid, &rid);
79 return rid;
82 static char *pdb_ads_domaindn2dns(TALLOC_CTX *mem_ctx, char *dn)
84 char *result, *p;
86 result = talloc_string_sub2(mem_ctx, dn, "DC=", "", false, false,
87 true);
88 if (result == NULL) {
89 return NULL;
92 while ((p = strchr_m(result, ',')) != NULL) {
93 *p = '.';
96 return result;
99 static struct pdb_domain_info *pdb_ads_get_domain_info(
100 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
102 struct pdb_ads_state *state = talloc_get_type_abort(
103 m->private_data, struct pdb_ads_state);
104 struct pdb_domain_info *info;
105 struct tldap_message *rootdse;
106 char *tmp;
108 info = talloc(mem_ctx, struct pdb_domain_info);
109 if (info == NULL) {
110 return NULL;
112 info->name = talloc_strdup(info, state->netbiosname);
113 if (info->name == NULL) {
114 goto fail;
116 info->dns_domain = pdb_ads_domaindn2dns(info, state->domaindn);
117 if (info->dns_domain == NULL) {
118 goto fail;
121 rootdse = tldap_rootdse(state->ld);
122 tmp = tldap_talloc_single_attribute(rootdse, "rootDomainNamingContext",
123 talloc_tos());
124 if (tmp == NULL) {
125 goto fail;
127 info->dns_forest = pdb_ads_domaindn2dns(info, tmp);
128 TALLOC_FREE(tmp);
129 if (info->dns_forest == NULL) {
130 goto fail;
132 info->sid = state->domainsid;
133 info->guid = state->domainguid;
134 return info;
136 fail:
137 TALLOC_FREE(info);
138 return NULL;
141 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
142 struct pdb_methods *m, struct samu *sam)
144 struct pdb_ads_state *state = talloc_get_type_abort(
145 m->private_data, struct pdb_ads_state);
146 struct pdb_ads_samu_private *result;
147 char *sidstr, *filter;
148 NTSTATUS status;
150 result = (struct pdb_ads_samu_private *)
151 pdb_get_backend_private_data(sam, m);
153 if (result != NULL) {
154 return talloc_get_type_abort(
155 result, struct pdb_ads_samu_private);
158 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), pdb_get_user_sid(sam));
159 if (sidstr == NULL) {
160 return NULL;
163 filter = talloc_asprintf(
164 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
165 TALLOC_FREE(sidstr);
166 if (filter == NULL) {
167 return NULL;
170 status = pdb_ads_getsamupriv(state, filter, sam, &result);
171 TALLOC_FREE(filter);
172 if (!NT_STATUS_IS_OK(status)) {
173 return NULL;
176 return result;
179 static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m,
180 struct samu *sam,
181 struct pdb_ads_samu_private *priv)
183 struct pdb_ads_state *state = talloc_get_type_abort(
184 m->private_data, struct pdb_ads_state);
185 TALLOC_CTX *frame = talloc_stackframe();
186 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
187 struct tldap_message *entry = priv->ldapmsg;
188 char *str;
189 time_t tmp_time;
190 struct dom_sid sid;
191 uint64_t n;
192 uint32_t i;
193 DATA_BLOB blob;
195 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
196 if (str == NULL) {
197 DEBUG(10, ("no samAccountName\n"));
198 goto fail;
200 pdb_set_username(sam, str, PDB_SET);
202 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
203 pdb_set_logon_time(sam, tmp_time, PDB_SET);
205 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
206 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
208 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
209 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
211 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
212 pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
215 str = tldap_talloc_single_attribute(entry, "displayName",
216 talloc_tos());
217 if (str != NULL) {
218 pdb_set_fullname(sam, str, PDB_SET);
221 str = tldap_talloc_single_attribute(entry, "homeDirectory",
222 talloc_tos());
223 if (str != NULL) {
224 pdb_set_homedir(sam, str, PDB_SET);
227 str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
228 if (str != NULL) {
229 pdb_set_dir_drive(sam, str, PDB_SET);
232 str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
233 if (str != NULL) {
234 pdb_set_logon_script(sam, str, PDB_SET);
237 str = tldap_talloc_single_attribute(entry, "profilePath",
238 talloc_tos());
239 if (str != NULL) {
240 pdb_set_profile_path(sam, str, PDB_SET);
243 str = tldap_talloc_single_attribute(entry, "profilePath",
244 talloc_tos());
245 if (str != NULL) {
246 pdb_set_profile_path(sam, str, PDB_SET);
249 str = tldap_talloc_single_attribute(entry, "comment",
250 talloc_tos());
251 if (str != NULL) {
252 pdb_set_comment(sam, str, PDB_SET);
255 str = tldap_talloc_single_attribute(entry, "description",
256 talloc_tos());
257 if (str != NULL) {
258 pdb_set_acct_desc(sam, str, PDB_SET);
261 str = tldap_talloc_single_attribute(entry, "userWorkstations",
262 talloc_tos());
263 if (str != NULL) {
264 pdb_set_workstations(sam, str, PDB_SET);
267 str = tldap_talloc_single_attribute(entry, "userParameters",
268 talloc_tos());
269 if (str != NULL) {
270 pdb_set_munged_dial(sam, str, PDB_SET);
273 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
274 DEBUG(10, ("Could not pull SID\n"));
275 goto fail;
277 pdb_set_user_sid(sam, &sid, PDB_SET);
279 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
280 DEBUG(10, ("Could not pull userAccountControl\n"));
281 goto fail;
283 pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
285 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
286 if (blob.length != NT_HASH_LEN) {
287 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
288 (int)blob.length, NT_HASH_LEN));
289 goto fail;
291 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
294 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
295 if (blob.length != LM_HASH_LEN) {
296 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
297 (int)blob.length, LM_HASH_LEN));
298 goto fail;
300 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
303 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
304 sid_compose(&sid, &state->domainsid, n);
305 pdb_set_group_sid(sam, &sid, PDB_SET);
309 if (tldap_pull_uint32(entry, "countryCode", &i)) {
310 pdb_set_country_code(sam, i, PDB_SET);
313 if (tldap_pull_uint32(entry, "codePage", &i)) {
314 pdb_set_code_page(sam, i, PDB_SET);
317 if (tldap_get_single_valueblob(entry, "logonHours", &blob)) {
319 if (blob.length > MAX_HOURS_LEN) {
320 status = NT_STATUS_INVALID_PARAMETER;
321 goto fail;
323 pdb_set_logon_divs(sam, blob.length * 8, PDB_SET);
324 pdb_set_hours_len(sam, blob.length, PDB_SET);
325 pdb_set_hours(sam, blob.data, blob.length, PDB_SET);
327 } else {
328 uint8_t hours[21];
329 pdb_set_logon_divs(sam, sizeof(hours)/8, PDB_SET);
330 pdb_set_hours_len(sam, sizeof(hours), PDB_SET);
331 memset(hours, 0xff, sizeof(hours));
332 pdb_set_hours(sam, hours, sizeof(hours), PDB_SET);
335 status = NT_STATUS_OK;
336 fail:
337 TALLOC_FREE(frame);
338 return status;
341 static bool pdb_ads_make_time_mod(struct tldap_message *existing,
342 TALLOC_CTX *mem_ctx,
343 struct tldap_mod **pmods, int *pnum_mods,
344 const char *attrib, time_t t)
346 uint64_t nt_time;
348 unix_to_nt_time(&nt_time, t);
350 return tldap_make_mod_fmt(
351 existing, mem_ctx, pmods, pnum_mods, attrib,
352 "%llu", nt_time);
355 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
356 struct tldap_message *existing,
357 TALLOC_CTX *mem_ctx,
358 struct tldap_mod **pmods, int *pnum_mods,
359 struct samu *sam)
361 bool ret = true;
362 DATA_BLOB blob;
363 const char *pw;
365 /* TODO: All fields :-) */
367 ret &= tldap_make_mod_fmt(
368 existing, mem_ctx, pmods, pnum_mods, "displayName",
369 "%s", pdb_get_fullname(sam));
371 pw = pdb_get_plaintext_passwd(sam);
374 * If we have the plain text pw, this is probably about to be
375 * set. Is this true always?
377 if (pw != NULL) {
378 char *pw_quote;
379 uint8_t *pw_utf16;
380 size_t pw_utf16_len;
382 pw_quote = talloc_asprintf(talloc_tos(), "\"%s\"", pw);
383 if (pw_quote == NULL) {
384 ret = false;
385 goto fail;
388 ret &= convert_string_talloc(talloc_tos(),
389 CH_UNIX, CH_UTF16LE,
390 pw_quote, strlen(pw_quote),
391 &pw_utf16, &pw_utf16_len, false);
392 if (!ret) {
393 goto fail;
395 blob = data_blob_const(pw_utf16, pw_utf16_len);
397 ret &= tldap_add_mod_blobs(mem_ctx, pmods, pnum_mods,
398 TLDAP_MOD_REPLACE,
399 "unicodePwd", &blob, 1);
400 TALLOC_FREE(pw_utf16);
401 TALLOC_FREE(pw_quote);
404 ret &= tldap_make_mod_fmt(
405 existing, mem_ctx, pmods, pnum_mods, "userAccountControl",
406 "%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
408 ret &= tldap_make_mod_fmt(
409 existing, mem_ctx, pmods, pnum_mods, "homeDirectory",
410 "%s", pdb_get_homedir(sam));
412 ret &= tldap_make_mod_fmt(
413 existing, mem_ctx, pmods, pnum_mods, "homeDrive",
414 "%s", pdb_get_dir_drive(sam));
416 ret &= tldap_make_mod_fmt(
417 existing, mem_ctx, pmods, pnum_mods, "scriptPath",
418 "%s", pdb_get_logon_script(sam));
420 ret &= tldap_make_mod_fmt(
421 existing, mem_ctx, pmods, pnum_mods, "profilePath",
422 "%s", pdb_get_profile_path(sam));
424 ret &= tldap_make_mod_fmt(
425 existing, mem_ctx, pmods, pnum_mods, "comment",
426 "%s", pdb_get_comment(sam));
428 ret &= tldap_make_mod_fmt(
429 existing, mem_ctx, pmods, pnum_mods, "description",
430 "%s", pdb_get_acct_desc(sam));
432 ret &= tldap_make_mod_fmt(
433 existing, mem_ctx, pmods, pnum_mods, "userWorkstations",
434 "%s", pdb_get_workstations(sam));
436 ret &= tldap_make_mod_fmt(
437 existing, mem_ctx, pmods, pnum_mods, "userParameters",
438 "%s", pdb_get_munged_dial(sam));
440 ret &= tldap_make_mod_fmt(
441 existing, mem_ctx, pmods, pnum_mods, "countryCode",
442 "%i", (int)pdb_get_country_code(sam));
444 ret &= tldap_make_mod_fmt(
445 existing, mem_ctx, pmods, pnum_mods, "codePage",
446 "%i", (int)pdb_get_code_page(sam));
448 ret &= pdb_ads_make_time_mod(
449 existing, mem_ctx, pmods, pnum_mods, "accountExpires",
450 (int)pdb_get_kickoff_time(sam));
452 ret &= tldap_make_mod_blob(
453 existing, mem_ctx, pmods, pnum_mods, "logonHours",
454 data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam)));
456 fail:
457 return ret;
460 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
461 const char *filter,
462 TALLOC_CTX *mem_ctx,
463 struct pdb_ads_samu_private **presult)
465 const char * attrs[] = {
466 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
467 "sAMAccountName", "displayName", "homeDirectory",
468 "homeDrive", "scriptPath", "profilePath", "description",
469 "userWorkstations", "comment", "userParameters", "objectSid",
470 "primaryGroupID", "userAccountControl", "logonHours",
471 "badPwdCount", "logonCount", "countryCode", "codePage",
472 "unicodePwd", "dBCSPwd" };
473 struct tldap_message **users;
474 int rc, count;
475 struct pdb_ads_samu_private *result;
477 result = talloc(mem_ctx, struct pdb_ads_samu_private);
478 if (result == NULL) {
479 return NT_STATUS_NO_MEMORY;
482 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
483 attrs, ARRAY_SIZE(attrs), 0, result,
484 &users, "%s", filter);
485 if (rc != TLDAP_SUCCESS) {
486 DEBUG(10, ("ldap_search failed %s\n",
487 tldap_errstr(talloc_tos(), state->ld, rc)));
488 TALLOC_FREE(result);
489 return NT_STATUS_LDAP(rc);
492 count = talloc_array_length(users);
493 if (count != 1) {
494 DEBUG(10, ("Expected 1 user, got %d\n", count));
495 TALLOC_FREE(result);
496 return NT_STATUS_NO_SUCH_USER;
499 result->ldapmsg = users[0];
500 if (!tldap_entry_dn(result->ldapmsg, &result->dn)) {
501 DEBUG(10, ("Could not extract dn\n"));
502 TALLOC_FREE(result);
503 return NT_STATUS_INTERNAL_DB_CORRUPTION;
506 *presult = result;
507 return NT_STATUS_OK;
510 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
511 struct pdb_ads_state *state,
512 struct samu *sam_acct,
513 const char *filter)
515 struct pdb_ads_samu_private *priv;
516 NTSTATUS status;
518 status = pdb_ads_getsamupriv(state, filter, sam_acct, &priv);
519 if (!NT_STATUS_IS_OK(status)) {
520 DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n",
521 nt_errstr(status)));
522 return status;
525 status = pdb_ads_init_sam_from_priv(m, sam_acct, priv);
526 if (!NT_STATUS_IS_OK(status)) {
527 DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n",
528 nt_errstr(status)));
529 TALLOC_FREE(priv);
530 return status;
533 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
534 return NT_STATUS_OK;
537 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
538 struct samu *sam_acct,
539 const char *username)
541 struct pdb_ads_state *state = talloc_get_type_abort(
542 m->private_data, struct pdb_ads_state);
543 char *filter;
545 filter = talloc_asprintf(
546 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
547 username);
548 NT_STATUS_HAVE_NO_MEMORY(filter);
550 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
553 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
554 struct samu *sam_acct,
555 const struct dom_sid *sid)
557 struct pdb_ads_state *state = talloc_get_type_abort(
558 m->private_data, struct pdb_ads_state);
559 char *sidstr, *filter;
561 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
562 NT_STATUS_HAVE_NO_MEMORY(sidstr);
564 filter = talloc_asprintf(
565 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
566 TALLOC_FREE(sidstr);
567 NT_STATUS_HAVE_NO_MEMORY(filter);
569 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
572 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
573 TALLOC_CTX *tmp_ctx,
574 const char *name, uint32 acct_flags,
575 uint32 *rid)
577 struct pdb_ads_state *state = talloc_get_type_abort(
578 m->private_data, struct pdb_ads_state);
579 struct tldap_context *ld;
580 const char *attrs[1] = { "objectSid" };
581 struct tldap_mod *mods = NULL;
582 int num_mods = 0;
583 struct tldap_message **user;
584 struct dom_sid sid;
585 char *dn;
586 int rc;
587 bool ok;
589 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
590 state->domaindn);
591 if (dn == NULL) {
592 return NT_STATUS_NO_MEMORY;
595 ld = pdb_ads_ld(state);
596 if (ld == NULL) {
597 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
600 /* TODO: Create machines etc */
602 ok = true;
603 ok &= tldap_make_mod_fmt(
604 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "user");
605 ok &= tldap_make_mod_fmt(
606 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
607 name);
608 if (!ok) {
609 return NT_STATUS_NO_MEMORY;
613 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
614 if (rc != TLDAP_SUCCESS) {
615 DEBUG(10, ("ldap_add failed %s\n",
616 tldap_errstr(talloc_tos(), ld, rc)));
617 TALLOC_FREE(dn);
618 return NT_STATUS_LDAP(rc);
621 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
622 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
623 &user,
624 "(&(objectclass=user)(samaccountname=%s))",
625 name);
626 if (rc != TLDAP_SUCCESS) {
627 DEBUG(10, ("Could not find just created user %s: %s\n",
628 name, tldap_errstr(talloc_tos(), state->ld, rc)));
629 TALLOC_FREE(dn);
630 return NT_STATUS_LDAP(rc);
633 if (talloc_array_length(user) != 1) {
634 DEBUG(10, ("Got %d users, expected one\n",
635 (int)talloc_array_length(user)));
636 TALLOC_FREE(dn);
637 return NT_STATUS_LDAP(rc);
640 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
641 DEBUG(10, ("Could not fetch objectSid from user %s\n",
642 name));
643 TALLOC_FREE(dn);
644 return NT_STATUS_INTERNAL_DB_CORRUPTION;
647 sid_peek_rid(&sid, rid);
648 TALLOC_FREE(dn);
649 return NT_STATUS_OK;
652 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
653 TALLOC_CTX *tmp_ctx,
654 struct samu *sam)
656 struct pdb_ads_state *state = talloc_get_type_abort(
657 m->private_data, struct pdb_ads_state);
658 NTSTATUS status;
659 struct tldap_context *ld;
660 char *dn;
661 int rc;
663 ld = pdb_ads_ld(state);
664 if (ld == NULL) {
665 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
668 status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
669 &dn);
670 if (!NT_STATUS_IS_OK(status)) {
671 return status;
674 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
675 TALLOC_FREE(dn);
676 if (rc != TLDAP_SUCCESS) {
677 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
678 tldap_errstr(talloc_tos(), ld, rc)));
679 return NT_STATUS_LDAP(rc);
681 return NT_STATUS_OK;
684 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
685 struct samu *sampass)
687 return NT_STATUS_NOT_IMPLEMENTED;
690 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
691 struct samu *sam)
693 struct pdb_ads_state *state = talloc_get_type_abort(
694 m->private_data, struct pdb_ads_state);
695 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
696 struct tldap_context *ld;
697 struct tldap_mod *mods = NULL;
698 int rc, num_mods = 0;
700 ld = pdb_ads_ld(state);
701 if (ld == NULL) {
702 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
705 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
706 &mods, &num_mods, sam)) {
707 return NT_STATUS_NO_MEMORY;
710 if (num_mods == 0) {
711 /* Nothing to do, just return success */
712 return NT_STATUS_OK;
715 rc = tldap_modify(ld, priv->dn, mods, num_mods, NULL, 0,
716 NULL, 0);
717 TALLOC_FREE(mods);
718 if (rc != TLDAP_SUCCESS) {
719 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
720 tldap_errstr(talloc_tos(), ld, rc)));
721 return NT_STATUS_LDAP(rc);
724 return NT_STATUS_OK;
727 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
728 struct samu *username)
730 return NT_STATUS_NOT_IMPLEMENTED;
733 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
734 struct samu *oldname,
735 const char *newname)
737 return NT_STATUS_NOT_IMPLEMENTED;
740 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
741 struct samu *sam_acct,
742 bool success)
744 return NT_STATUS_NOT_IMPLEMENTED;
747 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
748 const char *filter,
749 TALLOC_CTX *mem_ctx,
750 struct tldap_message **pmsg)
752 struct pdb_ads_state *state = talloc_get_type_abort(
753 m->private_data, struct pdb_ads_state);
754 const char *attrs[4] = { "objectSid", "description", "samAccountName",
755 "groupType" };
756 char *str;
757 struct tldap_message **group;
758 uint32_t grouptype;
759 int rc;
761 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
762 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
763 &group, "%s", filter);
764 if (rc != TLDAP_SUCCESS) {
765 DEBUG(10, ("ldap_search failed %s\n",
766 tldap_errstr(talloc_tos(), state->ld, rc)));
767 return NT_STATUS_LDAP(rc);
769 if (talloc_array_length(group) != 1) {
770 DEBUG(10, ("Expected 1 group, got %d\n",
771 (int)talloc_array_length(group)));
772 return NT_STATUS_INTERNAL_DB_CORRUPTION;
775 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
776 return NT_STATUS_INTERNAL_DB_CORRUPTION;
778 map->gid = pdb_ads_sid2gid(&map->sid);
780 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
781 return NT_STATUS_INTERNAL_DB_CORRUPTION;
783 switch (grouptype) {
784 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
785 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
786 map->sid_name_use = SID_NAME_ALIAS;
787 break;
788 case GTYPE_SECURITY_GLOBAL_GROUP:
789 map->sid_name_use = SID_NAME_DOM_GRP;
790 break;
791 default:
792 return NT_STATUS_INTERNAL_DB_CORRUPTION;
795 str = tldap_talloc_single_attribute(group[0], "samAccountName",
796 talloc_tos());
797 if (str == NULL) {
798 return NT_STATUS_INTERNAL_DB_CORRUPTION;
800 fstrcpy(map->nt_name, str);
801 TALLOC_FREE(str);
803 str = tldap_talloc_single_attribute(group[0], "description",
804 talloc_tos());
805 if (str != NULL) {
806 fstrcpy(map->comment, str);
807 TALLOC_FREE(str);
808 } else {
809 map->comment[0] = '\0';
812 if (pmsg != NULL) {
813 *pmsg = talloc_move(mem_ctx, &group[0]);
815 TALLOC_FREE(group);
816 return NT_STATUS_OK;
819 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
820 struct dom_sid sid)
822 char *filter;
823 NTSTATUS status;
825 filter = talloc_asprintf(talloc_tos(),
826 "(&(objectsid=%s)(objectclass=group))",
827 sid_string_talloc(talloc_tos(), &sid));
828 if (filter == NULL) {
829 return NT_STATUS_NO_MEMORY;
832 status = pdb_ads_getgrfilter(m, map, filter, NULL, NULL);
833 TALLOC_FREE(filter);
834 return status;
837 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
838 gid_t gid)
840 struct dom_sid sid;
841 pdb_ads_gid_to_sid(m, gid, &sid);
842 return pdb_ads_getgrsid(m, map, sid);
845 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
846 const char *name)
848 char *filter;
849 NTSTATUS status;
851 filter = talloc_asprintf(talloc_tos(),
852 "(&(samaccountname=%s)(objectclass=group))",
853 name);
854 if (filter == NULL) {
855 return NT_STATUS_NO_MEMORY;
858 status = pdb_ads_getgrfilter(m, map, filter, NULL, NULL);
859 TALLOC_FREE(filter);
860 return status;
863 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
864 TALLOC_CTX *mem_ctx, const char *name,
865 uint32 *rid)
867 TALLOC_CTX *frame = talloc_stackframe();
868 struct pdb_ads_state *state = talloc_get_type_abort(
869 m->private_data, struct pdb_ads_state);
870 struct tldap_context *ld;
871 const char *attrs[1] = { "objectSid" };
872 int num_mods = 0;
873 struct tldap_mod *mods = NULL;
874 struct tldap_message **alias;
875 struct dom_sid sid;
876 char *dn;
877 int rc;
878 bool ok = true;
880 ld = pdb_ads_ld(state);
881 if (ld == NULL) {
882 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
885 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
886 state->domaindn);
887 if (dn == NULL) {
888 TALLOC_FREE(frame);
889 return NT_STATUS_NO_MEMORY;
892 ok &= tldap_make_mod_fmt(
893 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
894 name);
895 ok &= tldap_make_mod_fmt(
896 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group");
897 ok &= tldap_make_mod_fmt(
898 NULL, talloc_tos(), &mods, &num_mods, "groupType",
899 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
901 if (!ok) {
902 TALLOC_FREE(frame);
903 return NT_STATUS_NO_MEMORY;
906 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
907 if (rc != TLDAP_SUCCESS) {
908 DEBUG(10, ("ldap_add failed %s\n",
909 tldap_errstr(talloc_tos(), state->ld, rc)));
910 TALLOC_FREE(frame);
911 return NT_STATUS_LDAP(rc);
914 rc = pdb_ads_search_fmt(
915 state, state->domaindn, TLDAP_SCOPE_SUB,
916 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
917 "(&(objectclass=group)(samaccountname=%s))", name);
918 if (rc != TLDAP_SUCCESS) {
919 DEBUG(10, ("Could not find just created alias %s: %s\n",
920 name, tldap_errstr(talloc_tos(), state->ld, rc)));
921 TALLOC_FREE(frame);
922 return NT_STATUS_LDAP(rc);
925 if (talloc_array_length(alias) != 1) {
926 DEBUG(10, ("Got %d alias, expected one\n",
927 (int)talloc_array_length(alias)));
928 TALLOC_FREE(frame);
929 return NT_STATUS_LDAP(rc);
932 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
933 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
934 name));
935 TALLOC_FREE(frame);
936 return NT_STATUS_INTERNAL_DB_CORRUPTION;
939 sid_peek_rid(&sid, rid);
940 TALLOC_FREE(frame);
941 return NT_STATUS_OK;
944 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
945 TALLOC_CTX *mem_ctx, uint32 rid)
947 struct pdb_ads_state *state = talloc_get_type_abort(
948 m->private_data, struct pdb_ads_state);
949 struct tldap_context *ld;
950 struct dom_sid sid;
951 char *sidstr;
952 struct tldap_message **msg;
953 char *dn;
954 int rc;
956 sid_compose(&sid, &state->domainsid, rid);
958 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
959 NT_STATUS_HAVE_NO_MEMORY(sidstr);
961 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
962 NULL, 0, 0, talloc_tos(), &msg,
963 ("(&(objectSid=%s)(objectClass=group))"),
964 sidstr);
965 TALLOC_FREE(sidstr);
966 if (rc != TLDAP_SUCCESS) {
967 DEBUG(10, ("ldap_search failed %s\n",
968 tldap_errstr(talloc_tos(), state->ld, rc)));
969 return NT_STATUS_LDAP(rc);
972 switch talloc_array_length(msg) {
973 case 0:
974 return NT_STATUS_NO_SUCH_GROUP;
975 case 1:
976 break;
977 default:
978 return NT_STATUS_INTERNAL_DB_CORRUPTION;
981 if (!tldap_entry_dn(msg[0], &dn)) {
982 TALLOC_FREE(msg);
983 return NT_STATUS_INTERNAL_DB_CORRUPTION;
986 ld = pdb_ads_ld(state);
987 if (ld == NULL) {
988 TALLOC_FREE(msg);
989 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
992 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
993 TALLOC_FREE(msg);
994 if (rc != TLDAP_SUCCESS) {
995 DEBUG(10, ("ldap_delete failed: %s\n",
996 tldap_errstr(talloc_tos(), state->ld, rc)));
997 return NT_STATUS_LDAP(rc);
1000 return NT_STATUS_OK;
1003 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
1004 GROUP_MAP *map)
1006 return NT_STATUS_NOT_IMPLEMENTED;
1009 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
1010 GROUP_MAP *map)
1012 struct pdb_ads_state *state = talloc_get_type_abort(
1013 m->private_data, struct pdb_ads_state);
1014 struct tldap_context *ld;
1015 struct tldap_mod *mods = NULL;
1016 char *filter;
1017 struct tldap_message *existing;
1018 char *dn;
1019 GROUP_MAP existing_map;
1020 int rc, num_mods = 0;
1021 bool ret;
1022 NTSTATUS status;
1024 ld = pdb_ads_ld(state);
1025 if (ld == NULL) {
1026 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1029 filter = talloc_asprintf(talloc_tos(),
1030 "(&(objectsid=%s)(objectclass=group))",
1031 sid_string_talloc(talloc_tos(), &map->sid));
1032 if (filter == NULL) {
1033 return NT_STATUS_NO_MEMORY;
1035 status = pdb_ads_getgrfilter(m, &existing_map, filter,
1036 talloc_tos(), &existing);
1037 TALLOC_FREE(filter);
1039 if (!tldap_entry_dn(existing, &dn)) {
1040 return NT_STATUS_LDAP(TLDAP_DECODING_ERROR);
1043 ret = true;
1045 ret &= tldap_make_mod_fmt(
1046 existing, talloc_tos(), &mods, &num_mods, "description",
1047 "%s", map->comment);
1048 ret &= tldap_make_mod_fmt(
1049 existing, talloc_tos(), &mods, &num_mods, "samaccountname",
1050 "%s", map->nt_name);
1052 if (!ret) {
1053 return NT_STATUS_NO_MEMORY;
1056 if (num_mods == 0) {
1057 TALLOC_FREE(existing);
1058 return NT_STATUS_OK;
1061 rc = tldap_modify(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1062 if (rc != TLDAP_SUCCESS) {
1063 DEBUG(10, ("ldap_modify for %s failed: %s\n", dn,
1064 tldap_errstr(talloc_tos(), ld, rc)));
1065 TALLOC_FREE(existing);
1066 return NT_STATUS_LDAP(rc);
1068 TALLOC_FREE(existing);
1069 return NT_STATUS_OK;
1072 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
1073 struct dom_sid sid)
1075 return NT_STATUS_NOT_IMPLEMENTED;
1078 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
1079 const struct dom_sid *sid,
1080 enum lsa_SidType sid_name_use,
1081 GROUP_MAP **pp_rmap,
1082 size_t *p_num_entries,
1083 bool unix_only)
1085 return NT_STATUS_NOT_IMPLEMENTED;
1088 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
1089 TALLOC_CTX *mem_ctx,
1090 const struct dom_sid *group,
1091 uint32 **pmembers,
1092 size_t *pnum_members)
1094 struct pdb_ads_state *state = talloc_get_type_abort(
1095 m->private_data, struct pdb_ads_state);
1096 const char *attrs[1] = { "member" };
1097 char *sidstr;
1098 struct tldap_message **msg;
1099 int i, rc, num_members;
1100 DATA_BLOB *blobs;
1101 uint32_t *members;
1103 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), group);
1104 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1106 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1107 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1108 &msg, "(objectsid=%s)", sidstr);
1109 TALLOC_FREE(sidstr);
1110 if (rc != TLDAP_SUCCESS) {
1111 DEBUG(10, ("ldap_search failed %s\n",
1112 tldap_errstr(talloc_tos(), state->ld, rc)));
1113 return NT_STATUS_LDAP(rc);
1115 switch talloc_array_length(msg) {
1116 case 0:
1117 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1118 break;
1119 case 1:
1120 break;
1121 default:
1122 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1123 break;
1126 if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
1127 *pmembers = NULL;
1128 *pnum_members = 0;
1129 return NT_STATUS_OK;
1132 members = talloc_array(mem_ctx, uint32_t, num_members);
1133 if (members == NULL) {
1134 return NT_STATUS_NO_MEMORY;
1137 for (i=0; i<num_members; i++) {
1138 struct dom_sid sid;
1139 if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
1140 || !sid_peek_rid(&sid, &members[i])) {
1141 TALLOC_FREE(members);
1142 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1146 *pmembers = members;
1147 *pnum_members = num_members;
1148 return NT_STATUS_OK;
1151 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
1152 TALLOC_CTX *mem_ctx,
1153 struct samu *user,
1154 struct dom_sid **pp_sids,
1155 gid_t **pp_gids,
1156 uint32_t *p_num_groups)
1158 struct pdb_ads_state *state = talloc_get_type_abort(
1159 m->private_data, struct pdb_ads_state);
1160 struct pdb_ads_samu_private *priv;
1161 const char *attrs[1] = { "objectSid" };
1162 struct tldap_message **groups;
1163 int i, rc, count;
1164 size_t num_groups;
1165 struct dom_sid *group_sids;
1166 gid_t *gids;
1168 priv = pdb_ads_get_samu_private(m, user);
1169 if (priv != NULL) {
1170 rc = pdb_ads_search_fmt(
1171 state, state->domaindn, TLDAP_SCOPE_SUB,
1172 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
1173 "(&(member=%s)(grouptype=%d)(objectclass=group))",
1174 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
1175 if (rc != TLDAP_SUCCESS) {
1176 DEBUG(10, ("ldap_search failed %s\n",
1177 tldap_errstr(talloc_tos(), state->ld, rc)));
1178 return NT_STATUS_LDAP(rc);
1180 count = talloc_array_length(groups);
1181 } else {
1183 * This happens for artificial samu users
1185 DEBUG(10, ("Could not get pdb_ads_samu_private\n"));
1186 count = 0;
1189 group_sids = talloc_array(mem_ctx, struct dom_sid, count+1);
1190 if (group_sids == NULL) {
1191 return NT_STATUS_NO_MEMORY;
1193 gids = talloc_array(mem_ctx, gid_t, count+1);
1194 if (gids == NULL) {
1195 TALLOC_FREE(group_sids);
1196 return NT_STATUS_NO_MEMORY;
1199 sid_copy(&group_sids[0], pdb_get_group_sid(user));
1200 if (!sid_to_gid(&group_sids[0], &gids[0])) {
1201 TALLOC_FREE(gids);
1202 TALLOC_FREE(group_sids);
1203 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1205 num_groups = 1;
1207 for (i=0; i<count; i++) {
1208 if (!tldap_pull_binsid(groups[i], "objectSid",
1209 &group_sids[num_groups])) {
1210 continue;
1212 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
1214 num_groups += 1;
1215 if (num_groups == count) {
1216 break;
1220 *pp_sids = group_sids;
1221 *pp_gids = gids;
1222 *p_num_groups = num_groups;
1223 return NT_STATUS_OK;
1226 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
1227 TALLOC_CTX *mem_ctx,
1228 struct samu *user)
1230 return NT_STATUS_NOT_IMPLEMENTED;
1233 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
1234 TALLOC_CTX *mem_ctx,
1235 uint32 grouprid, uint32 memberrid,
1236 int mod_op)
1238 struct pdb_ads_state *state = talloc_get_type_abort(
1239 m->private_data, struct pdb_ads_state);
1240 TALLOC_CTX *frame = talloc_stackframe();
1241 struct tldap_context *ld;
1242 struct dom_sid groupsid, membersid;
1243 char *groupdn, *memberdn;
1244 struct tldap_mod *mods;
1245 int num_mods;
1246 int rc;
1247 NTSTATUS status;
1249 ld = pdb_ads_ld(state);
1250 if (ld == NULL) {
1251 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1254 sid_compose(&groupsid, &state->domainsid, grouprid);
1255 sid_compose(&membersid, &state->domainsid, memberrid);
1257 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
1258 if (!NT_STATUS_IS_OK(status)) {
1259 TALLOC_FREE(frame);
1260 return NT_STATUS_NO_SUCH_GROUP;
1262 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
1263 if (!NT_STATUS_IS_OK(status)) {
1264 TALLOC_FREE(frame);
1265 return NT_STATUS_NO_SUCH_USER;
1268 mods = NULL;
1269 num_mods = 0;
1271 if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op,
1272 "member", memberdn)) {
1273 TALLOC_FREE(frame);
1274 return NT_STATUS_NO_MEMORY;
1277 rc = tldap_modify(ld, groupdn, mods, num_mods, NULL, 0, NULL, 0);
1278 TALLOC_FREE(frame);
1279 if (rc != TLDAP_SUCCESS) {
1280 DEBUG(10, ("ldap_modify failed: %s\n",
1281 tldap_errstr(talloc_tos(), state->ld, rc)));
1282 if ((mod_op == TLDAP_MOD_ADD) &&
1283 (rc == TLDAP_ALREADY_EXISTS)) {
1284 return NT_STATUS_MEMBER_IN_GROUP;
1286 if ((mod_op == TLDAP_MOD_DELETE) &&
1287 (rc == TLDAP_UNWILLING_TO_PERFORM)) {
1288 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1290 return NT_STATUS_LDAP(rc);
1293 return NT_STATUS_OK;
1296 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
1297 TALLOC_CTX *mem_ctx,
1298 uint32 group_rid, uint32 member_rid)
1300 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1301 TLDAP_MOD_ADD);
1304 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
1305 TALLOC_CTX *mem_ctx,
1306 uint32 group_rid, uint32 member_rid)
1308 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1309 TLDAP_MOD_DELETE);
1312 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
1313 const char *name, uint32 *rid)
1315 TALLOC_CTX *frame = talloc_stackframe();
1316 struct pdb_ads_state *state = talloc_get_type_abort(
1317 m->private_data, struct pdb_ads_state);
1318 struct tldap_context *ld;
1319 const char *attrs[1] = { "objectSid" };
1320 int num_mods = 0;
1321 struct tldap_mod *mods = NULL;
1322 struct tldap_message **alias;
1323 struct dom_sid sid;
1324 char *dn;
1325 int rc;
1326 bool ok = true;
1328 ld = pdb_ads_ld(state);
1329 if (ld == NULL) {
1330 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1333 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1334 state->domaindn);
1335 if (dn == NULL) {
1336 TALLOC_FREE(frame);
1337 return NT_STATUS_NO_MEMORY;
1340 ok &= tldap_make_mod_fmt(
1341 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
1342 name);
1343 ok &= tldap_make_mod_fmt(
1344 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group");
1345 ok &= tldap_make_mod_fmt(
1346 NULL, talloc_tos(), &mods, &num_mods, "groupType",
1347 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1349 if (!ok) {
1350 TALLOC_FREE(frame);
1351 return NT_STATUS_NO_MEMORY;
1354 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1355 if (rc != TLDAP_SUCCESS) {
1356 DEBUG(10, ("ldap_add failed %s\n",
1357 tldap_errstr(talloc_tos(), state->ld, rc)));
1358 TALLOC_FREE(frame);
1359 return NT_STATUS_LDAP(rc);
1362 rc = pdb_ads_search_fmt(
1363 state, state->domaindn, TLDAP_SCOPE_SUB,
1364 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1365 "(&(objectclass=group)(samaccountname=%s))", name);
1366 if (rc != TLDAP_SUCCESS) {
1367 DEBUG(10, ("Could not find just created alias %s: %s\n",
1368 name, tldap_errstr(talloc_tos(), state->ld, rc)));
1369 TALLOC_FREE(frame);
1370 return NT_STATUS_LDAP(rc);
1373 if (talloc_array_length(alias) != 1) {
1374 DEBUG(10, ("Got %d alias, expected one\n",
1375 (int)talloc_array_length(alias)));
1376 TALLOC_FREE(frame);
1377 return NT_STATUS_LDAP(rc);
1380 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1381 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1382 name));
1383 TALLOC_FREE(frame);
1384 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1387 sid_peek_rid(&sid, rid);
1388 TALLOC_FREE(frame);
1389 return NT_STATUS_OK;
1392 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1393 const struct dom_sid *sid)
1395 struct pdb_ads_state *state = talloc_get_type_abort(
1396 m->private_data, struct pdb_ads_state);
1397 struct tldap_context *ld;
1398 struct tldap_message **alias;
1399 char *sidstr, *dn = NULL;
1400 int rc;
1402 ld = pdb_ads_ld(state);
1403 if (ld == NULL) {
1404 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1407 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1408 if (sidstr == NULL) {
1409 return NT_STATUS_NO_MEMORY;
1412 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1413 NULL, 0, 0, talloc_tos(), &alias,
1414 "(&(objectSid=%s)(objectclass=group)"
1415 "(|(grouptype=%d)(grouptype=%d)))",
1416 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1417 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1418 TALLOC_FREE(sidstr);
1419 if (rc != TLDAP_SUCCESS) {
1420 DEBUG(10, ("ldap_search failed: %s\n",
1421 tldap_errstr(talloc_tos(), state->ld, rc)));
1422 return NT_STATUS_LDAP(rc);
1424 if (talloc_array_length(alias) != 1) {
1425 DEBUG(10, ("Expected 1 alias, got %d\n",
1426 (int)talloc_array_length(alias)));
1427 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1429 if (!tldap_entry_dn(alias[0], &dn)) {
1430 DEBUG(10, ("Could not get DN for alias %s\n",
1431 sid_string_dbg(sid)));
1432 return NT_STATUS_INTERNAL_ERROR;
1435 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
1436 if (rc != TLDAP_SUCCESS) {
1437 DEBUG(10, ("ldap_delete failed: %s\n",
1438 tldap_errstr(talloc_tos(), state->ld, rc)));
1439 return NT_STATUS_LDAP(rc);
1442 return NT_STATUS_OK;
1445 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1446 const struct dom_sid *sid,
1447 struct acct_info *info)
1449 struct pdb_ads_state *state = talloc_get_type_abort(
1450 m->private_data, struct pdb_ads_state);
1451 struct tldap_context *ld;
1452 const char *attrs[3] = { "objectSid", "description",
1453 "samAccountName" };
1454 struct tldap_message **msg;
1455 char *sidstr, *dn;
1456 int rc;
1457 struct tldap_mod *mods;
1458 int num_mods;
1459 bool ok;
1461 ld = pdb_ads_ld(state);
1462 if (ld == NULL) {
1463 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1466 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1467 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1469 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1470 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1471 &msg, "(&(objectSid=%s)(objectclass=group)"
1472 "(|(grouptype=%d)(grouptype=%d)))",
1473 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1474 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1475 TALLOC_FREE(sidstr);
1476 if (rc != TLDAP_SUCCESS) {
1477 DEBUG(10, ("ldap_search failed %s\n",
1478 tldap_errstr(talloc_tos(), state->ld, rc)));
1479 return NT_STATUS_LDAP(rc);
1481 switch talloc_array_length(msg) {
1482 case 0:
1483 return NT_STATUS_NO_SUCH_ALIAS;
1484 case 1:
1485 break;
1486 default:
1487 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1490 if (!tldap_entry_dn(msg[0], &dn)) {
1491 TALLOC_FREE(msg);
1492 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1495 mods = NULL;
1496 num_mods = 0;
1497 ok = true;
1499 ok &= tldap_make_mod_fmt(
1500 msg[0], msg, &mods, &num_mods, "description",
1501 "%s", info->acct_desc);
1502 ok &= tldap_make_mod_fmt(
1503 msg[0], msg, &mods, &num_mods, "samAccountName",
1504 "%s", info->acct_name);
1505 if (!ok) {
1506 TALLOC_FREE(msg);
1507 return NT_STATUS_NO_MEMORY;
1509 if (num_mods == 0) {
1510 /* no change */
1511 TALLOC_FREE(msg);
1512 return NT_STATUS_OK;
1515 rc = tldap_modify(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1516 TALLOC_FREE(msg);
1517 if (rc != TLDAP_SUCCESS) {
1518 DEBUG(10, ("ldap_modify failed: %s\n",
1519 tldap_errstr(talloc_tos(), state->ld, rc)));
1520 return NT_STATUS_LDAP(rc);
1522 return NT_STATUS_OK;
1525 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1526 const struct dom_sid *sid,
1527 TALLOC_CTX *mem_ctx, char **pdn)
1529 struct tldap_message **msg;
1530 char *sidstr, *dn;
1531 int rc;
1533 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1534 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1536 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1537 NULL, 0, 0, talloc_tos(), &msg,
1538 "(objectsid=%s)", sidstr);
1539 TALLOC_FREE(sidstr);
1540 if (rc != TLDAP_SUCCESS) {
1541 DEBUG(10, ("ldap_search failed %s\n",
1542 tldap_errstr(talloc_tos(), state->ld, rc)));
1543 return NT_STATUS_LDAP(rc);
1546 switch talloc_array_length(msg) {
1547 case 0:
1548 return NT_STATUS_NOT_FOUND;
1549 case 1:
1550 break;
1551 default:
1552 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1555 if (!tldap_entry_dn(msg[0], &dn)) {
1556 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1559 dn = talloc_strdup(mem_ctx, dn);
1560 if (dn == NULL) {
1561 return NT_STATUS_NO_MEMORY;
1563 TALLOC_FREE(msg);
1565 *pdn = dn;
1566 return NT_STATUS_OK;
1569 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1570 const struct dom_sid *alias,
1571 const struct dom_sid *member,
1572 int mod_op)
1574 struct pdb_ads_state *state = talloc_get_type_abort(
1575 m->private_data, struct pdb_ads_state);
1576 struct tldap_context *ld;
1577 TALLOC_CTX *frame = talloc_stackframe();
1578 struct tldap_mod *mods;
1579 int num_mods;
1580 int rc;
1581 char *aliasdn, *memberdn;
1582 NTSTATUS status;
1584 ld = pdb_ads_ld(state);
1585 if (ld == NULL) {
1586 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1589 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1590 if (!NT_STATUS_IS_OK(status)) {
1591 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1592 sid_string_dbg(alias), nt_errstr(status)));
1593 TALLOC_FREE(frame);
1594 return NT_STATUS_NO_SUCH_ALIAS;
1596 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1597 if (!NT_STATUS_IS_OK(status)) {
1598 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1599 sid_string_dbg(member), nt_errstr(status)));
1600 TALLOC_FREE(frame);
1601 return status;
1604 mods = NULL;
1605 num_mods = 0;
1607 if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op,
1608 "member", memberdn)) {
1609 TALLOC_FREE(frame);
1610 return NT_STATUS_NO_MEMORY;
1613 rc = tldap_modify(ld, aliasdn, mods, num_mods, NULL, 0, NULL, 0);
1614 TALLOC_FREE(frame);
1615 if (rc != TLDAP_SUCCESS) {
1616 DEBUG(10, ("ldap_modify failed: %s\n",
1617 tldap_errstr(talloc_tos(), state->ld, rc)));
1618 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1619 return NT_STATUS_MEMBER_IN_ALIAS;
1621 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1622 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1624 return NT_STATUS_LDAP(rc);
1627 return NT_STATUS_OK;
1630 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1631 const struct dom_sid *alias,
1632 const struct dom_sid *member)
1634 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1637 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1638 const struct dom_sid *alias,
1639 const struct dom_sid *member)
1641 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1644 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
1645 struct dom_sid *psid)
1647 const char *attrs[1] = { "objectSid" };
1648 struct tldap_message **msg;
1649 char *dn;
1650 size_t len;
1651 int rc;
1652 bool ret;
1654 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1655 dnblob->data, dnblob->length, &dn, &len,
1656 false)) {
1657 return false;
1659 rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
1660 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1661 &msg, "(objectclass=*)");
1662 TALLOC_FREE(dn);
1663 if (talloc_array_length(msg) != 1) {
1664 DEBUG(10, ("Got %d objects, expected one\n",
1665 (int)talloc_array_length(msg)));
1666 TALLOC_FREE(msg);
1667 return false;
1670 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1671 TALLOC_FREE(msg);
1672 return ret;
1675 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1676 const struct dom_sid *alias,
1677 TALLOC_CTX *mem_ctx,
1678 struct dom_sid **pmembers,
1679 size_t *pnum_members)
1681 struct pdb_ads_state *state = talloc_get_type_abort(
1682 m->private_data, struct pdb_ads_state);
1683 const char *attrs[1] = { "member" };
1684 char *sidstr;
1685 struct tldap_message **msg;
1686 int i, rc, num_members;
1687 DATA_BLOB *blobs;
1688 struct dom_sid *members;
1690 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), alias);
1691 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1693 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1694 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1695 &msg, "(objectsid=%s)", sidstr);
1696 TALLOC_FREE(sidstr);
1697 if (rc != TLDAP_SUCCESS) {
1698 DEBUG(10, ("ldap_search failed %s\n",
1699 tldap_errstr(talloc_tos(), state->ld, rc)));
1700 return NT_STATUS_LDAP(rc);
1702 switch talloc_array_length(msg) {
1703 case 0:
1704 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1705 break;
1706 case 1:
1707 break;
1708 default:
1709 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1710 break;
1713 if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
1714 *pmembers = NULL;
1715 *pnum_members = 0;
1716 return NT_STATUS_OK;
1719 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1720 if (members == NULL) {
1721 return NT_STATUS_NO_MEMORY;
1724 for (i=0; i<num_members; i++) {
1725 if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
1726 TALLOC_FREE(members);
1727 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1731 *pmembers = members;
1732 *pnum_members = num_members;
1733 return NT_STATUS_OK;
1736 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1737 TALLOC_CTX *mem_ctx,
1738 const struct dom_sid *domain_sid,
1739 const struct dom_sid *members,
1740 size_t num_members,
1741 uint32_t **palias_rids,
1742 size_t *pnum_alias_rids)
1744 struct pdb_ads_state *state = talloc_get_type_abort(
1745 m->private_data, struct pdb_ads_state);
1746 const char *attrs[1] = { "objectSid" };
1747 struct tldap_message **msg = NULL;
1748 uint32_t *alias_rids = NULL;
1749 size_t num_alias_rids = 0;
1750 int i, rc, count;
1751 bool got_members = false;
1752 char *filter;
1753 NTSTATUS status;
1756 * TODO: Get the filter right so that we only get the aliases from
1757 * either the SAM or BUILTIN
1760 filter = talloc_asprintf(talloc_tos(),
1761 "(&(|(grouptype=%d)(grouptype=%d))"
1762 "(objectclass=group)(|",
1763 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1764 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1765 if (filter == NULL) {
1766 return NT_STATUS_NO_MEMORY;
1769 for (i=0; i<num_members; i++) {
1770 char *dn;
1772 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1773 if (!NT_STATUS_IS_OK(status)) {
1774 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1775 sid_string_dbg(&members[i]),
1776 nt_errstr(status)));
1777 continue;
1779 filter = talloc_asprintf_append_buffer(
1780 filter, "(member=%s)", dn);
1781 TALLOC_FREE(dn);
1782 if (filter == NULL) {
1783 return NT_STATUS_NO_MEMORY;
1785 got_members = true;
1788 if (!got_members) {
1789 goto done;
1792 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1793 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1794 &msg, "%s))", filter);
1795 TALLOC_FREE(filter);
1796 if (rc != TLDAP_SUCCESS) {
1797 DEBUG(10, ("tldap_search failed %s\n",
1798 tldap_errstr(talloc_tos(), state->ld, rc)));
1799 return NT_STATUS_LDAP(rc);
1802 count = talloc_array_length(msg);
1803 if (count == 0) {
1804 goto done;
1807 alias_rids = talloc_array(mem_ctx, uint32_t, count);
1808 if (alias_rids == NULL) {
1809 TALLOC_FREE(msg);
1810 return NT_STATUS_NO_MEMORY;
1813 for (i=0; i<count; i++) {
1814 struct dom_sid sid;
1816 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1817 DEBUG(10, ("Could not pull SID for member %d\n", i));
1818 continue;
1820 if (sid_peek_check_rid(domain_sid, &sid,
1821 &alias_rids[num_alias_rids])) {
1822 num_alias_rids += 1;
1825 done:
1826 TALLOC_FREE(msg);
1827 *palias_rids = alias_rids;
1828 *pnum_alias_rids = 0;
1829 return NT_STATUS_OK;
1832 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1833 const struct dom_sid *domain_sid,
1834 int num_rids,
1835 uint32 *rids,
1836 const char **names,
1837 enum lsa_SidType *lsa_attrs)
1839 struct pdb_ads_state *state = talloc_get_type_abort(
1840 m->private_data, struct pdb_ads_state);
1841 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1842 int i, num_mapped;
1844 if (num_rids == 0) {
1845 return NT_STATUS_NONE_MAPPED;
1848 num_mapped = 0;
1850 for (i=0; i<num_rids; i++) {
1851 struct dom_sid sid;
1852 struct tldap_message **msg;
1853 char *sidstr;
1854 uint32_t attr;
1855 int rc;
1857 lsa_attrs[i] = SID_NAME_UNKNOWN;
1859 sid_compose(&sid, domain_sid, rids[i]);
1861 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
1862 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1864 rc = pdb_ads_search_fmt(state, state->domaindn,
1865 TLDAP_SCOPE_SUB, attrs,
1866 ARRAY_SIZE(attrs), 0, talloc_tos(),
1867 &msg, "(objectsid=%s)", sidstr);
1868 TALLOC_FREE(sidstr);
1869 if (rc != TLDAP_SUCCESS) {
1870 DEBUG(10, ("ldap_search failed %s\n",
1871 tldap_errstr(talloc_tos(), state->ld, rc)));
1872 continue;
1875 switch talloc_array_length(msg) {
1876 case 0:
1877 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1878 continue;
1879 case 1:
1880 break;
1881 default:
1882 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1885 names[i] = tldap_talloc_single_attribute(
1886 msg[0], "samAccountName", talloc_tos());
1887 if (names[i] == NULL) {
1888 DEBUG(10, ("no samAccountName\n"));
1889 continue;
1891 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1892 DEBUG(10, ("no samAccountType"));
1893 continue;
1895 lsa_attrs[i] = ds_atype_map(attr);
1896 num_mapped += 1;
1899 if (num_mapped == 0) {
1900 return NT_STATUS_NONE_MAPPED;
1902 if (num_mapped < num_rids) {
1903 return STATUS_SOME_UNMAPPED;
1905 return NT_STATUS_OK;
1908 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1909 const struct dom_sid *domain_sid,
1910 int num_names,
1911 const char **pp_names,
1912 uint32 *rids,
1913 enum lsa_SidType *attrs)
1915 return NT_STATUS_NOT_IMPLEMENTED;
1918 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1919 enum pdb_policy_type type,
1920 uint32_t *value)
1922 return account_policy_get(type, value)
1923 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1926 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1927 enum pdb_policy_type type,
1928 uint32_t value)
1930 return account_policy_set(type, value)
1931 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1934 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1935 time_t *seq_num)
1937 return NT_STATUS_NOT_IMPLEMENTED;
1940 struct pdb_ads_search_state {
1941 uint32_t acct_flags;
1942 struct samr_displayentry *entries;
1943 uint32_t num_entries;
1944 ssize_t array_size;
1945 uint32_t current;
1948 static bool pdb_ads_next_entry(struct pdb_search *search,
1949 struct samr_displayentry *entry)
1951 struct pdb_ads_search_state *state = talloc_get_type_abort(
1952 search->private_data, struct pdb_ads_search_state);
1954 if (state->current == state->num_entries) {
1955 return false;
1958 entry->idx = state->entries[state->current].idx;
1959 entry->rid = state->entries[state->current].rid;
1960 entry->acct_flags = state->entries[state->current].acct_flags;
1962 entry->account_name = talloc_strdup(
1963 search, state->entries[state->current].account_name);
1964 entry->fullname = talloc_strdup(
1965 search, state->entries[state->current].fullname);
1966 entry->description = talloc_strdup(
1967 search, state->entries[state->current].description);
1969 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1970 || (entry->description == NULL)) {
1971 DEBUG(0, ("talloc_strdup failed\n"));
1972 return false;
1975 state->current += 1;
1976 return true;
1979 static void pdb_ads_search_end(struct pdb_search *search)
1981 struct pdb_ads_search_state *state = talloc_get_type_abort(
1982 search->private_data, struct pdb_ads_search_state);
1983 TALLOC_FREE(state);
1986 static bool pdb_ads_search_filter(struct pdb_methods *m,
1987 struct pdb_search *search,
1988 const char *filter,
1989 uint32_t acct_flags,
1990 struct pdb_ads_search_state **pstate)
1992 struct pdb_ads_state *state = talloc_get_type_abort(
1993 m->private_data, struct pdb_ads_state);
1994 struct pdb_ads_search_state *sstate;
1995 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1996 "userAccountControl", "description" };
1997 struct tldap_message **users;
1998 int i, rc, num_users;
2000 sstate = talloc_zero(search, struct pdb_ads_search_state);
2001 if (sstate == NULL) {
2002 return false;
2004 sstate->acct_flags = acct_flags;
2006 rc = pdb_ads_search_fmt(
2007 state, state->domaindn, TLDAP_SCOPE_SUB,
2008 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
2009 "%s", filter);
2010 if (rc != TLDAP_SUCCESS) {
2011 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
2012 tldap_errstr(talloc_tos(), state->ld, rc)));
2013 return false;
2016 num_users = talloc_array_length(users);
2018 sstate->entries = talloc_array(sstate, struct samr_displayentry,
2019 num_users);
2020 if (sstate->entries == NULL) {
2021 DEBUG(10, ("talloc failed\n"));
2022 return false;
2025 sstate->num_entries = 0;
2027 for (i=0; i<num_users; i++) {
2028 struct samr_displayentry *e;
2029 struct dom_sid sid;
2030 uint32_t ctrl;
2032 e = &sstate->entries[sstate->num_entries];
2034 e->idx = sstate->num_entries;
2035 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
2036 DEBUG(10, ("Could not pull sid\n"));
2037 continue;
2039 sid_peek_rid(&sid, &e->rid);
2041 if (tldap_pull_uint32(users[i], "userAccountControl", &ctrl)) {
2043 e->acct_flags = ds_uf2acb(ctrl);
2045 DEBUG(10, ("pdb_ads_search_filter: Found %x, "
2046 "filter %x\n", (int)e->acct_flags,
2047 (int)sstate->acct_flags));
2050 if ((sstate->acct_flags != 0) &&
2051 ((sstate->acct_flags & e->acct_flags) == 0)) {
2052 continue;
2055 if (e->acct_flags & (ACB_WSTRUST|ACB_SVRTRUST)) {
2056 e->acct_flags |= ACB_NORMAL;
2058 } else {
2059 e->acct_flags = ACB_NORMAL;
2062 if (e->rid == DOMAIN_RID_GUEST) {
2064 * Guest is specially crafted in s3. Make
2065 * QueryDisplayInfo match QueryUserInfo
2067 e->account_name = lp_guestaccount();
2068 e->fullname = lp_guestaccount();
2069 e->description = "";
2070 e->acct_flags = ACB_NORMAL;
2071 } else {
2072 e->account_name = tldap_talloc_single_attribute(
2073 users[i], "samAccountName", sstate->entries);
2074 e->fullname = tldap_talloc_single_attribute(
2075 users[i], "displayName", sstate->entries);
2076 e->description = tldap_talloc_single_attribute(
2077 users[i], "description", sstate->entries);
2079 if (e->account_name == NULL) {
2080 return false;
2082 if (e->fullname == NULL) {
2083 e->fullname = "";
2085 if (e->description == NULL) {
2086 e->description = "";
2089 sstate->num_entries += 1;
2090 if (sstate->num_entries >= num_users) {
2091 break;
2095 search->private_data = sstate;
2096 search->next_entry = pdb_ads_next_entry;
2097 search->search_end = pdb_ads_search_end;
2098 *pstate = sstate;
2099 return true;
2102 static bool pdb_ads_search_users(struct pdb_methods *m,
2103 struct pdb_search *search,
2104 uint32 acct_flags)
2106 struct pdb_ads_search_state *sstate;
2107 char *filter;
2108 bool ret;
2110 DEBUG(10, ("pdb_ads_search_users got flags %x\n", acct_flags));
2112 if (acct_flags & ACB_NORMAL) {
2113 filter = talloc_asprintf(
2114 talloc_tos(),
2115 "(&(objectclass=user)(sAMAccountType=%d))",
2116 ATYPE_NORMAL_ACCOUNT);
2117 } else if (acct_flags & ACB_WSTRUST) {
2118 filter = talloc_asprintf(
2119 talloc_tos(),
2120 "(&(objectclass=user)(sAMAccountType=%d))",
2121 ATYPE_WORKSTATION_TRUST);
2122 } else {
2123 filter = talloc_strdup(talloc_tos(), "(objectclass=user)");
2125 if (filter == NULL) {
2126 return false;
2129 ret = pdb_ads_search_filter(m, search, filter, acct_flags, &sstate);
2130 TALLOC_FREE(filter);
2131 if (!ret) {
2132 return false;
2134 return true;
2137 static bool pdb_ads_search_groups(struct pdb_methods *m,
2138 struct pdb_search *search)
2140 struct pdb_ads_search_state *sstate;
2141 char *filter;
2142 bool ret;
2144 filter = talloc_asprintf(talloc_tos(),
2145 "(&(grouptype=%d)(objectclass=group))",
2146 GTYPE_SECURITY_GLOBAL_GROUP);
2147 if (filter == NULL) {
2148 return false;
2150 ret = pdb_ads_search_filter(m, search, filter, 0, &sstate);
2151 TALLOC_FREE(filter);
2152 if (!ret) {
2153 return false;
2155 return true;
2158 static bool pdb_ads_search_aliases(struct pdb_methods *m,
2159 struct pdb_search *search,
2160 const struct dom_sid *sid)
2162 struct pdb_ads_search_state *sstate;
2163 char *filter;
2164 bool ret;
2166 filter = talloc_asprintf(
2167 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
2168 sid_check_is_builtin(sid)
2169 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2170 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
2172 if (filter == NULL) {
2173 return false;
2175 ret = pdb_ads_search_filter(m, search, filter, 0, &sstate);
2176 TALLOC_FREE(filter);
2177 if (!ret) {
2178 return false;
2180 return true;
2183 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
2184 struct dom_sid *sid)
2186 struct pdb_ads_state *state = talloc_get_type_abort(
2187 m->private_data, struct pdb_ads_state);
2188 sid_compose(sid, &state->domainsid, uid);
2189 return true;
2192 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
2193 struct dom_sid *sid)
2195 struct pdb_ads_state *state = talloc_get_type_abort(
2196 m->private_data, struct pdb_ads_state);
2197 sid_compose(sid, &state->domainsid, gid);
2198 return true;
2201 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2202 union unid_t *id, enum lsa_SidType *type)
2204 struct pdb_ads_state *state = talloc_get_type_abort(
2205 m->private_data, struct pdb_ads_state);
2206 const char *attrs[4] = { "objectClass", "samAccountType",
2207 "uidNumber", "gidNumber" };
2208 struct tldap_message **msg;
2209 char *sidstr, *base;
2210 uint32_t atype;
2211 int rc;
2212 bool ret = false;
2214 sidstr = sid_binstring_hex(sid);
2215 if (sidstr == NULL) {
2216 return false;
2218 base = talloc_asprintf(talloc_tos(), "<SID=%s>", sidstr);
2219 SAFE_FREE(sidstr);
2221 rc = pdb_ads_search_fmt(
2222 state, base, TLDAP_SCOPE_BASE,
2223 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
2224 "(objectclass=*)");
2225 TALLOC_FREE(base);
2227 if (rc != TLDAP_SUCCESS) {
2228 DEBUG(10, ("pdb_ads_search_fmt failed: %s\n",
2229 tldap_errstr(talloc_tos(), state->ld, rc)));
2230 return false;
2232 if (talloc_array_length(msg) != 1) {
2233 DEBUG(10, ("Got %d objects, expected 1\n",
2234 (int)talloc_array_length(msg)));
2235 goto fail;
2237 if (!tldap_pull_uint32(msg[0], "samAccountType", &atype)) {
2238 DEBUG(10, ("samAccountType not found\n"));
2239 goto fail;
2241 if (atype == ATYPE_ACCOUNT) {
2242 uint32_t uid;
2243 *type = SID_NAME_USER;
2244 if (!tldap_pull_uint32(msg[0], "uidNumber", &uid)) {
2245 DEBUG(10, ("Did not find uidNumber\n"));
2246 goto fail;
2248 id->uid = uid;
2249 } else {
2250 uint32_t gid;
2251 *type = SID_NAME_DOM_GRP;
2252 if (!tldap_pull_uint32(msg[0], "gidNumber", &gid)) {
2253 DEBUG(10, ("Did not find gidNumber\n"));
2254 goto fail;
2256 id->gid = gid;
2258 ret = true;
2259 fail:
2260 TALLOC_FREE(msg);
2261 return ret;
2264 static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
2266 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2269 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
2271 return false;
2274 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
2275 const char *domain, char** pwd,
2276 struct dom_sid *sid,
2277 time_t *pass_last_set_time)
2279 return false;
2282 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
2283 const char* domain, const char* pwd,
2284 const struct dom_sid *sid)
2286 return false;
2289 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
2290 const char *domain)
2292 return false;
2295 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
2296 TALLOC_CTX *mem_ctx,
2297 uint32 *num_domains,
2298 struct trustdom_info ***domains)
2300 *num_domains = 0;
2301 *domains = NULL;
2302 return NT_STATUS_OK;
2305 static void pdb_ads_init_methods(struct pdb_methods *m)
2307 m->name = "ads";
2308 m->get_domain_info = pdb_ads_get_domain_info;
2309 m->getsampwnam = pdb_ads_getsampwnam;
2310 m->getsampwsid = pdb_ads_getsampwsid;
2311 m->create_user = pdb_ads_create_user;
2312 m->delete_user = pdb_ads_delete_user;
2313 m->add_sam_account = pdb_ads_add_sam_account;
2314 m->update_sam_account = pdb_ads_update_sam_account;
2315 m->delete_sam_account = pdb_ads_delete_sam_account;
2316 m->rename_sam_account = pdb_ads_rename_sam_account;
2317 m->update_login_attempts = pdb_ads_update_login_attempts;
2318 m->getgrsid = pdb_ads_getgrsid;
2319 m->getgrgid = pdb_ads_getgrgid;
2320 m->getgrnam = pdb_ads_getgrnam;
2321 m->create_dom_group = pdb_ads_create_dom_group;
2322 m->delete_dom_group = pdb_ads_delete_dom_group;
2323 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
2324 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
2325 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
2326 m->enum_group_mapping = pdb_ads_enum_group_mapping;
2327 m->enum_group_members = pdb_ads_enum_group_members;
2328 m->enum_group_memberships = pdb_ads_enum_group_memberships;
2329 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
2330 m->add_groupmem = pdb_ads_add_groupmem;
2331 m->del_groupmem = pdb_ads_del_groupmem;
2332 m->create_alias = pdb_ads_create_alias;
2333 m->delete_alias = pdb_ads_delete_alias;
2334 m->get_aliasinfo = pdb_default_get_aliasinfo;
2335 m->set_aliasinfo = pdb_ads_set_aliasinfo;
2336 m->add_aliasmem = pdb_ads_add_aliasmem;
2337 m->del_aliasmem = pdb_ads_del_aliasmem;
2338 m->enum_aliasmem = pdb_ads_enum_aliasmem;
2339 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
2340 m->lookup_rids = pdb_ads_lookup_rids;
2341 m->lookup_names = pdb_ads_lookup_names;
2342 m->get_account_policy = pdb_ads_get_account_policy;
2343 m->set_account_policy = pdb_ads_set_account_policy;
2344 m->get_seq_num = pdb_ads_get_seq_num;
2345 m->search_users = pdb_ads_search_users;
2346 m->search_groups = pdb_ads_search_groups;
2347 m->search_aliases = pdb_ads_search_aliases;
2348 m->uid_to_sid = pdb_ads_uid_to_sid;
2349 m->gid_to_sid = pdb_ads_gid_to_sid;
2350 m->sid_to_id = pdb_ads_sid_to_id;
2351 m->capabilities = pdb_ads_capabilities;
2352 m->new_rid = pdb_ads_new_rid;
2353 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2354 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2355 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2356 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2359 static void free_private_data(void **vp)
2361 struct pdb_ads_state *state = talloc_get_type_abort(
2362 *vp, struct pdb_ads_state);
2364 TALLOC_FREE(state->ld);
2365 return;
2369 this is used to catch debug messages from events
2371 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2372 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
2374 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2375 const char *fmt, va_list ap)
2377 int samba_level = -1;
2378 char *s = NULL;
2379 switch (level) {
2380 case TLDAP_DEBUG_FATAL:
2381 samba_level = 0;
2382 break;
2383 case TLDAP_DEBUG_ERROR:
2384 samba_level = 1;
2385 break;
2386 case TLDAP_DEBUG_WARNING:
2387 samba_level = 2;
2388 break;
2389 case TLDAP_DEBUG_TRACE:
2390 samba_level = 11;
2391 break;
2394 if (vasprintf(&s, fmt, ap) == -1) {
2395 return;
2397 DEBUG(samba_level, ("tldap: %s", s));
2398 free(s);
2401 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2403 NTSTATUS status;
2404 int fd;
2406 if (tldap_connection_ok(state->ld)) {
2407 return state->ld;
2409 TALLOC_FREE(state->ld);
2411 status = open_socket_out(
2412 (struct sockaddr_storage *)(void *)&state->socket_address,
2413 0, 0, &fd);
2414 if (!NT_STATUS_IS_OK(status)) {
2415 DEBUG(10, ("Could not connect to %s: %s\n",
2416 state->socket_address.sun_path, nt_errstr(status)));
2417 return NULL;
2420 set_blocking(fd, false);
2422 state->ld = tldap_context_create(state, fd);
2423 if (state->ld == NULL) {
2424 close(fd);
2425 return NULL;
2427 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2429 return state->ld;
2432 int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2433 int scope, const char *attrs[], int num_attrs,
2434 int attrsonly,
2435 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2436 const char *fmt, ...)
2438 struct tldap_context *ld;
2439 va_list ap;
2440 int ret;
2442 ld = pdb_ads_ld(state);
2443 if (ld == NULL) {
2444 return TLDAP_SERVER_DOWN;
2447 va_start(ap, fmt);
2448 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2449 mem_ctx, res, fmt, ap);
2450 va_end(ap);
2452 if (ret != TLDAP_SERVER_DOWN) {
2453 return ret;
2456 /* retry once */
2457 ld = pdb_ads_ld(state);
2458 if (ld == NULL) {
2459 return TLDAP_SERVER_DOWN;
2462 va_start(ap, fmt);
2463 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2464 mem_ctx, res, fmt, ap);
2465 va_end(ap);
2466 return ret;
2469 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2470 const char *location)
2472 const char *domain_attrs[2] = { "objectSid", "objectGUID" };
2473 const char *ncname_attrs[1] = { "netbiosname" };
2474 struct tldap_context *ld;
2475 struct tldap_message *rootdse, **domain, **ncname;
2476 TALLOC_CTX *frame = talloc_stackframe();
2477 NTSTATUS status;
2478 int num_domains;
2479 int rc;
2481 ZERO_STRUCT(state->socket_address);
2482 state->socket_address.sun_family = AF_UNIX;
2483 strlcpy(state->socket_address.sun_path, location,
2484 sizeof(state->socket_address.sun_path));
2486 ld = pdb_ads_ld(state);
2487 if (ld == NULL) {
2488 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2489 goto done;
2492 rc = tldap_fetch_rootdse(ld);
2493 if (rc != TLDAP_SUCCESS) {
2494 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2495 tldap_errstr(talloc_tos(), state->ld, rc)));
2496 status = NT_STATUS_LDAP(rc);
2497 goto done;
2499 rootdse = tldap_rootdse(state->ld);
2501 state->domaindn = tldap_talloc_single_attribute(
2502 rootdse, "defaultNamingContext", state);
2503 if (state->domaindn == NULL) {
2504 DEBUG(10, ("Could not get defaultNamingContext\n"));
2505 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2506 goto done;
2508 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2510 state->configdn = tldap_talloc_single_attribute(
2511 rootdse, "configurationNamingContext", state);
2512 if (state->configdn == NULL) {
2513 DEBUG(10, ("Could not get configurationNamingContext\n"));
2514 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2515 goto done;
2517 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2520 * Figure out our domain's SID
2522 rc = pdb_ads_search_fmt(
2523 state, state->domaindn, TLDAP_SCOPE_BASE,
2524 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2525 talloc_tos(), &domain, "(objectclass=*)");
2526 if (rc != TLDAP_SUCCESS) {
2527 DEBUG(10, ("Could not retrieve domain: %s\n",
2528 tldap_errstr(talloc_tos(), state->ld, rc)));
2529 status = NT_STATUS_LDAP(rc);
2530 goto done;
2533 num_domains = talloc_array_length(domain);
2534 if (num_domains != 1) {
2535 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2536 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2537 goto done;
2539 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2540 DEBUG(10, ("Could not retrieve domain SID\n"));
2541 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2542 goto done;
2544 if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) {
2545 DEBUG(10, ("Could not retrieve domain GUID\n"));
2546 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2547 goto done;
2549 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2552 * Figure out our domain's short name
2554 rc = pdb_ads_search_fmt(
2555 state, state->configdn, TLDAP_SCOPE_SUB,
2556 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2557 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2558 if (rc != TLDAP_SUCCESS) {
2559 DEBUG(10, ("Could not retrieve ncname: %s\n",
2560 tldap_errstr(talloc_tos(), state->ld, rc)));
2561 status = NT_STATUS_LDAP(rc);
2562 goto done;
2564 if (talloc_array_length(ncname) != 1) {
2565 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2566 goto done;
2569 state->netbiosname = tldap_talloc_single_attribute(
2570 ncname[0], "netbiosname", state);
2571 if (state->netbiosname == NULL) {
2572 DEBUG(10, ("Could not get netbiosname\n"));
2573 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2574 goto done;
2576 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2578 if (!strequal(lp_workgroup(), state->netbiosname)) {
2579 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2580 state->netbiosname, lp_workgroup()));
2581 status = NT_STATUS_NO_SUCH_DOMAIN;
2582 goto done;
2585 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2587 status = NT_STATUS_OK;
2588 done:
2589 TALLOC_FREE(frame);
2590 return status;
2593 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2594 const char *location)
2596 struct pdb_methods *m;
2597 struct pdb_ads_state *state;
2598 char *tmp = NULL;
2599 NTSTATUS status;
2601 m = talloc(NULL, struct pdb_methods);
2602 if (m == NULL) {
2603 return NT_STATUS_NO_MEMORY;
2605 state = talloc_zero(m, struct pdb_ads_state);
2606 if (state == NULL) {
2607 goto nomem;
2609 m->private_data = state;
2610 m->free_private_data = free_private_data;
2611 pdb_ads_init_methods(m);
2613 if (location == NULL) {
2614 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2615 lp_private_dir());
2616 location = tmp;
2618 if (location == NULL) {
2619 goto nomem;
2622 status = pdb_ads_connect(state, location);
2623 if (!NT_STATUS_IS_OK(status)) {
2624 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2625 goto fail;
2628 *pdb_method = m;
2629 return NT_STATUS_OK;
2630 nomem:
2631 status = NT_STATUS_NO_MEMORY;
2632 fail:
2633 TALLOC_FREE(m);
2634 return status;
2637 NTSTATUS pdb_ads_init(void);
2638 NTSTATUS pdb_ads_init(void)
2640 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
2641 pdb_init_ads);