s3-utils/net_rpc_printer.c: print more info on write error
[Samba/gebeck_regimport.git] / source3 / passdb / pdb_ads.c
blob3746da3a4fe802a34fc06e103012cb31a5a52da6
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 "passdb.h"
22 #include "tldap.h"
23 #include "tldap_util.h"
24 #include "../libds/common/flags.h"
25 #include "secrets.h"
26 #include "../librpc/gen_ndr/samr.h"
27 #include "../libcli/ldap/ldap_ndr.h"
28 #include "../libcli/security/security.h"
29 #include "../libds/common/flag_mapping.h"
31 struct pdb_ads_state {
32 struct sockaddr_un socket_address;
33 struct tldap_context *ld;
34 struct dom_sid domainsid;
35 struct GUID domainguid;
36 char *domaindn;
37 char *configdn;
38 char *netbiosname;
41 struct pdb_ads_samu_private {
42 char *dn;
43 struct tldap_message *ldapmsg;
46 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
47 struct dom_sid *sid);
48 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
49 struct dom_sid *psid);
50 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
51 const struct dom_sid *sid,
52 TALLOC_CTX *mem_ctx, char **pdn);
53 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state);
54 static int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
55 int scope, const char *attrs[], int num_attrs,
56 int attrsonly,
57 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
58 const char *fmt, ...);
59 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
60 const char *filter,
61 TALLOC_CTX *mem_ctx,
62 struct pdb_ads_samu_private **presult);
64 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
65 time_t *ptime)
67 uint64_t tmp;
69 if (!tldap_pull_uint64(msg, attr, &tmp)) {
70 return false;
72 *ptime = nt_time_to_unix(tmp);
73 return true;
76 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
78 uint32_t rid;
79 sid_peek_rid(sid, &rid);
80 return rid;
83 static char *pdb_ads_domaindn2dns(TALLOC_CTX *mem_ctx, char *dn)
85 char *result, *p;
87 result = talloc_string_sub2(mem_ctx, dn, "DC=", "", false, false,
88 true);
89 if (result == NULL) {
90 return NULL;
93 while ((p = strchr_m(result, ',')) != NULL) {
94 *p = '.';
97 return result;
100 static struct pdb_domain_info *pdb_ads_get_domain_info(
101 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
103 struct pdb_ads_state *state = talloc_get_type_abort(
104 m->private_data, struct pdb_ads_state);
105 struct pdb_domain_info *info;
106 struct tldap_message *rootdse;
107 char *tmp;
109 info = talloc(mem_ctx, struct pdb_domain_info);
110 if (info == NULL) {
111 return NULL;
113 info->name = talloc_strdup(info, state->netbiosname);
114 if (info->name == NULL) {
115 goto fail;
117 info->dns_domain = pdb_ads_domaindn2dns(info, state->domaindn);
118 if (info->dns_domain == NULL) {
119 goto fail;
122 rootdse = tldap_rootdse(state->ld);
123 tmp = tldap_talloc_single_attribute(rootdse, "rootDomainNamingContext",
124 talloc_tos());
125 if (tmp == NULL) {
126 goto fail;
128 info->dns_forest = pdb_ads_domaindn2dns(info, tmp);
129 TALLOC_FREE(tmp);
130 if (info->dns_forest == NULL) {
131 goto fail;
133 info->sid = state->domainsid;
134 info->guid = state->domainguid;
135 return info;
137 fail:
138 TALLOC_FREE(info);
139 return NULL;
142 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
143 struct pdb_methods *m, struct samu *sam)
145 struct pdb_ads_state *state = talloc_get_type_abort(
146 m->private_data, struct pdb_ads_state);
147 struct pdb_ads_samu_private *result;
148 char *sidstr, *filter;
149 NTSTATUS status;
151 result = (struct pdb_ads_samu_private *)
152 pdb_get_backend_private_data(sam, m);
154 if (result != NULL) {
155 return talloc_get_type_abort(
156 result, struct pdb_ads_samu_private);
159 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), pdb_get_user_sid(sam));
160 if (sidstr == NULL) {
161 return NULL;
164 filter = talloc_asprintf(
165 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
166 TALLOC_FREE(sidstr);
167 if (filter == NULL) {
168 return NULL;
171 status = pdb_ads_getsamupriv(state, filter, sam, &result);
172 TALLOC_FREE(filter);
173 if (!NT_STATUS_IS_OK(status)) {
174 return NULL;
177 return result;
180 static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m,
181 struct samu *sam,
182 struct pdb_ads_samu_private *priv)
184 struct pdb_ads_state *state = talloc_get_type_abort(
185 m->private_data, struct pdb_ads_state);
186 TALLOC_CTX *frame = talloc_stackframe();
187 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
188 struct tldap_message *entry = priv->ldapmsg;
189 char *str;
190 time_t tmp_time;
191 struct dom_sid sid;
192 uint64_t n;
193 uint32_t i;
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 str = tldap_talloc_single_attribute(entry, "comment",
251 talloc_tos());
252 if (str != NULL) {
253 pdb_set_comment(sam, str, PDB_SET);
256 str = tldap_talloc_single_attribute(entry, "description",
257 talloc_tos());
258 if (str != NULL) {
259 pdb_set_acct_desc(sam, str, PDB_SET);
262 str = tldap_talloc_single_attribute(entry, "userWorkstations",
263 talloc_tos());
264 if (str != NULL) {
265 pdb_set_workstations(sam, str, PDB_SET);
268 str = tldap_talloc_single_attribute(entry, "userParameters",
269 talloc_tos());
270 if (str != NULL) {
271 pdb_set_munged_dial(sam, str, PDB_SET);
274 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
275 DEBUG(10, ("Could not pull SID\n"));
276 goto fail;
278 pdb_set_user_sid(sam, &sid, PDB_SET);
280 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
281 DEBUG(10, ("Could not pull userAccountControl\n"));
282 goto fail;
284 pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
286 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
287 if (blob.length != NT_HASH_LEN) {
288 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
289 (int)blob.length, NT_HASH_LEN));
290 goto fail;
292 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
295 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
296 if (blob.length != LM_HASH_LEN) {
297 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
298 (int)blob.length, LM_HASH_LEN));
299 goto fail;
301 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
304 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
305 sid_compose(&sid, &state->domainsid, n);
306 pdb_set_group_sid(sam, &sid, PDB_SET);
310 if (tldap_pull_uint32(entry, "countryCode", &i)) {
311 pdb_set_country_code(sam, i, PDB_SET);
314 if (tldap_pull_uint32(entry, "codePage", &i)) {
315 pdb_set_code_page(sam, i, PDB_SET);
318 if (tldap_get_single_valueblob(entry, "logonHours", &blob)) {
320 if (blob.length > MAX_HOURS_LEN) {
321 status = NT_STATUS_INVALID_PARAMETER;
322 goto fail;
324 pdb_set_logon_divs(sam, blob.length * 8, PDB_SET);
325 pdb_set_hours_len(sam, blob.length, PDB_SET);
326 pdb_set_hours(sam, blob.data, blob.length, PDB_SET);
328 } else {
329 uint8_t hours[21];
330 pdb_set_logon_divs(sam, sizeof(hours)/8, PDB_SET);
331 pdb_set_hours_len(sam, sizeof(hours), PDB_SET);
332 memset(hours, 0xff, sizeof(hours));
333 pdb_set_hours(sam, hours, sizeof(hours), PDB_SET);
336 status = NT_STATUS_OK;
337 fail:
338 TALLOC_FREE(frame);
339 return status;
342 static bool pdb_ads_make_time_mod(struct tldap_message *existing,
343 TALLOC_CTX *mem_ctx,
344 struct tldap_mod **pmods, int *pnum_mods,
345 const char *attrib, time_t t)
347 uint64_t nt_time;
349 unix_to_nt_time(&nt_time, t);
351 return tldap_make_mod_fmt(
352 existing, mem_ctx, pmods, pnum_mods, attrib,
353 "%llu", nt_time);
356 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
357 struct tldap_message *existing,
358 TALLOC_CTX *mem_ctx,
359 struct tldap_mod **pmods, int *pnum_mods,
360 struct samu *sam)
362 bool ret = true;
363 DATA_BLOB blob;
364 const char *pw;
366 /* TODO: All fields :-) */
368 ret &= tldap_make_mod_fmt(
369 existing, mem_ctx, pmods, pnum_mods, "displayName",
370 "%s", pdb_get_fullname(sam));
372 pw = pdb_get_plaintext_passwd(sam);
375 * If we have the plain text pw, this is probably about to be
376 * set. Is this true always?
378 if (pw != NULL) {
379 char *pw_quote;
380 uint8_t *pw_utf16;
381 size_t pw_utf16_len;
383 pw_quote = talloc_asprintf(talloc_tos(), "\"%s\"", pw);
384 if (pw_quote == NULL) {
385 ret = false;
386 goto fail;
389 ret &= convert_string_talloc(talloc_tos(),
390 CH_UNIX, CH_UTF16LE,
391 pw_quote, strlen(pw_quote),
392 &pw_utf16, &pw_utf16_len);
393 if (!ret) {
394 goto fail;
396 blob = data_blob_const(pw_utf16, pw_utf16_len);
398 ret &= tldap_add_mod_blobs(mem_ctx, pmods, pnum_mods,
399 TLDAP_MOD_REPLACE,
400 "unicodePwd", &blob, 1);
401 TALLOC_FREE(pw_utf16);
402 TALLOC_FREE(pw_quote);
405 ret &= tldap_make_mod_fmt(
406 existing, mem_ctx, pmods, pnum_mods, "userAccountControl",
407 "%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
409 ret &= tldap_make_mod_fmt(
410 existing, mem_ctx, pmods, pnum_mods, "homeDirectory",
411 "%s", pdb_get_homedir(sam));
413 ret &= tldap_make_mod_fmt(
414 existing, mem_ctx, pmods, pnum_mods, "homeDrive",
415 "%s", pdb_get_dir_drive(sam));
417 ret &= tldap_make_mod_fmt(
418 existing, mem_ctx, pmods, pnum_mods, "scriptPath",
419 "%s", pdb_get_logon_script(sam));
421 ret &= tldap_make_mod_fmt(
422 existing, mem_ctx, pmods, pnum_mods, "profilePath",
423 "%s", pdb_get_profile_path(sam));
425 ret &= tldap_make_mod_fmt(
426 existing, mem_ctx, pmods, pnum_mods, "comment",
427 "%s", pdb_get_comment(sam));
429 ret &= tldap_make_mod_fmt(
430 existing, mem_ctx, pmods, pnum_mods, "description",
431 "%s", pdb_get_acct_desc(sam));
433 ret &= tldap_make_mod_fmt(
434 existing, mem_ctx, pmods, pnum_mods, "userWorkstations",
435 "%s", pdb_get_workstations(sam));
437 ret &= tldap_make_mod_fmt(
438 existing, mem_ctx, pmods, pnum_mods, "userParameters",
439 "%s", pdb_get_munged_dial(sam));
441 ret &= tldap_make_mod_fmt(
442 existing, mem_ctx, pmods, pnum_mods, "countryCode",
443 "%i", (int)pdb_get_country_code(sam));
445 ret &= tldap_make_mod_fmt(
446 existing, mem_ctx, pmods, pnum_mods, "codePage",
447 "%i", (int)pdb_get_code_page(sam));
449 ret &= pdb_ads_make_time_mod(
450 existing, mem_ctx, pmods, pnum_mods, "accountExpires",
451 (int)pdb_get_kickoff_time(sam));
453 ret &= tldap_make_mod_blob(
454 existing, mem_ctx, pmods, pnum_mods, "logonHours",
455 data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam)));
457 fail:
458 return ret;
461 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
462 const char *filter,
463 TALLOC_CTX *mem_ctx,
464 struct pdb_ads_samu_private **presult)
466 const char * attrs[] = {
467 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
468 "sAMAccountName", "displayName", "homeDirectory",
469 "homeDrive", "scriptPath", "profilePath", "description",
470 "userWorkstations", "comment", "userParameters", "objectSid",
471 "primaryGroupID", "userAccountControl", "logonHours",
472 "badPwdCount", "logonCount", "countryCode", "codePage",
473 "unicodePwd", "dBCSPwd" };
474 struct tldap_message **users;
475 int rc, count;
476 struct pdb_ads_samu_private *result;
478 result = talloc(mem_ctx, struct pdb_ads_samu_private);
479 if (result == NULL) {
480 return NT_STATUS_NO_MEMORY;
483 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
484 attrs, ARRAY_SIZE(attrs), 0, result,
485 &users, "%s", filter);
486 if (rc != TLDAP_SUCCESS) {
487 DEBUG(10, ("ldap_search failed %s\n",
488 tldap_errstr(talloc_tos(), state->ld, rc)));
489 TALLOC_FREE(result);
490 return NT_STATUS_LDAP(rc);
493 count = talloc_array_length(users);
494 if (count != 1) {
495 DEBUG(10, ("Expected 1 user, got %d\n", count));
496 TALLOC_FREE(result);
497 return NT_STATUS_NO_SUCH_USER;
500 result->ldapmsg = users[0];
501 if (!tldap_entry_dn(result->ldapmsg, &result->dn)) {
502 DEBUG(10, ("Could not extract dn\n"));
503 TALLOC_FREE(result);
504 return NT_STATUS_INTERNAL_DB_CORRUPTION;
507 *presult = result;
508 return NT_STATUS_OK;
511 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
512 struct pdb_ads_state *state,
513 struct samu *sam_acct,
514 const char *filter)
516 struct pdb_ads_samu_private *priv;
517 NTSTATUS status;
519 status = pdb_ads_getsamupriv(state, filter, sam_acct, &priv);
520 if (!NT_STATUS_IS_OK(status)) {
521 DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n",
522 nt_errstr(status)));
523 return status;
526 status = pdb_ads_init_sam_from_priv(m, sam_acct, priv);
527 if (!NT_STATUS_IS_OK(status)) {
528 DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n",
529 nt_errstr(status)));
530 TALLOC_FREE(priv);
531 return status;
534 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
535 return NT_STATUS_OK;
538 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
539 struct samu *sam_acct,
540 const char *username)
542 struct pdb_ads_state *state = talloc_get_type_abort(
543 m->private_data, struct pdb_ads_state);
544 char *filter;
546 filter = talloc_asprintf(
547 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
548 username);
549 NT_STATUS_HAVE_NO_MEMORY(filter);
551 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
554 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
555 struct samu *sam_acct,
556 const struct dom_sid *sid)
558 struct pdb_ads_state *state = talloc_get_type_abort(
559 m->private_data, struct pdb_ads_state);
560 char *sidstr, *filter;
562 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
563 NT_STATUS_HAVE_NO_MEMORY(sidstr);
565 filter = talloc_asprintf(
566 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
567 TALLOC_FREE(sidstr);
568 NT_STATUS_HAVE_NO_MEMORY(filter);
570 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
573 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
574 TALLOC_CTX *tmp_ctx,
575 const char *name, uint32 acct_flags,
576 uint32 *rid)
578 struct pdb_ads_state *state = talloc_get_type_abort(
579 m->private_data, struct pdb_ads_state);
580 struct tldap_context *ld;
581 const char *attrs[1] = { "objectSid" };
582 struct tldap_mod *mods = NULL;
583 int num_mods = 0;
584 struct tldap_message **user;
585 struct dom_sid sid;
586 char *dn;
587 int rc;
588 bool ok;
590 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
591 state->domaindn);
592 if (dn == NULL) {
593 return NT_STATUS_NO_MEMORY;
596 ld = pdb_ads_ld(state);
597 if (ld == NULL) {
598 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
601 /* TODO: Create machines etc */
603 ok = true;
604 ok &= tldap_make_mod_fmt(
605 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "user");
606 ok &= tldap_make_mod_fmt(
607 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
608 name);
609 if (!ok) {
610 return NT_STATUS_NO_MEMORY;
614 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
615 if (rc != TLDAP_SUCCESS) {
616 DEBUG(10, ("ldap_add failed %s\n",
617 tldap_errstr(talloc_tos(), ld, rc)));
618 TALLOC_FREE(dn);
619 return NT_STATUS_LDAP(rc);
622 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
623 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
624 &user,
625 "(&(objectclass=user)(samaccountname=%s))",
626 name);
627 if (rc != TLDAP_SUCCESS) {
628 DEBUG(10, ("Could not find just created user %s: %s\n",
629 name, tldap_errstr(talloc_tos(), state->ld, rc)));
630 TALLOC_FREE(dn);
631 return NT_STATUS_LDAP(rc);
634 if (talloc_array_length(user) != 1) {
635 DEBUG(10, ("Got %d users, expected one\n",
636 (int)talloc_array_length(user)));
637 TALLOC_FREE(dn);
638 return NT_STATUS_LDAP(rc);
641 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
642 DEBUG(10, ("Could not fetch objectSid from user %s\n",
643 name));
644 TALLOC_FREE(dn);
645 return NT_STATUS_INTERNAL_DB_CORRUPTION;
648 sid_peek_rid(&sid, rid);
649 TALLOC_FREE(dn);
650 return NT_STATUS_OK;
653 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
654 TALLOC_CTX *tmp_ctx,
655 struct samu *sam)
657 struct pdb_ads_state *state = talloc_get_type_abort(
658 m->private_data, struct pdb_ads_state);
659 NTSTATUS status;
660 struct tldap_context *ld;
661 char *dn;
662 int rc;
664 ld = pdb_ads_ld(state);
665 if (ld == NULL) {
666 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
669 status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
670 &dn);
671 if (!NT_STATUS_IS_OK(status)) {
672 return status;
675 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
676 TALLOC_FREE(dn);
677 if (rc != TLDAP_SUCCESS) {
678 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
679 tldap_errstr(talloc_tos(), ld, rc)));
680 return NT_STATUS_LDAP(rc);
682 return NT_STATUS_OK;
685 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
686 struct samu *sampass)
688 return NT_STATUS_NOT_IMPLEMENTED;
691 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
692 struct samu *sam)
694 struct pdb_ads_state *state = talloc_get_type_abort(
695 m->private_data, struct pdb_ads_state);
696 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
697 struct tldap_context *ld;
698 struct tldap_mod *mods = NULL;
699 int rc, num_mods = 0;
701 ld = pdb_ads_ld(state);
702 if (ld == NULL) {
703 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
706 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
707 &mods, &num_mods, sam)) {
708 return NT_STATUS_NO_MEMORY;
711 if (num_mods == 0) {
712 /* Nothing to do, just return success */
713 return NT_STATUS_OK;
716 rc = tldap_modify(ld, priv->dn, mods, num_mods, NULL, 0,
717 NULL, 0);
718 TALLOC_FREE(mods);
719 if (rc != TLDAP_SUCCESS) {
720 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
721 tldap_errstr(talloc_tos(), ld, rc)));
722 return NT_STATUS_LDAP(rc);
725 return NT_STATUS_OK;
728 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
729 struct samu *username)
731 return NT_STATUS_NOT_IMPLEMENTED;
734 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
735 struct samu *oldname,
736 const char *newname)
738 return NT_STATUS_NOT_IMPLEMENTED;
741 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
742 struct samu *sam_acct,
743 bool success)
745 return NT_STATUS_NOT_IMPLEMENTED;
748 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
749 const char *filter,
750 TALLOC_CTX *mem_ctx,
751 struct tldap_message **pmsg)
753 struct pdb_ads_state *state = talloc_get_type_abort(
754 m->private_data, struct pdb_ads_state);
755 const char *attrs[4] = { "objectSid", "description", "samAccountName",
756 "groupType" };
757 char *str;
758 struct tldap_message **group;
759 uint32_t grouptype;
760 int rc;
762 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
763 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
764 &group, "%s", filter);
765 if (rc != TLDAP_SUCCESS) {
766 DEBUG(10, ("ldap_search failed %s\n",
767 tldap_errstr(talloc_tos(), state->ld, rc)));
768 return NT_STATUS_LDAP(rc);
770 if (talloc_array_length(group) != 1) {
771 DEBUG(10, ("Expected 1 group, got %d\n",
772 (int)talloc_array_length(group)));
773 return NT_STATUS_INTERNAL_DB_CORRUPTION;
776 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
777 return NT_STATUS_INTERNAL_DB_CORRUPTION;
779 map->gid = pdb_ads_sid2gid(&map->sid);
781 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
782 return NT_STATUS_INTERNAL_DB_CORRUPTION;
784 switch (grouptype) {
785 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
786 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
787 map->sid_name_use = SID_NAME_ALIAS;
788 break;
789 case GTYPE_SECURITY_GLOBAL_GROUP:
790 map->sid_name_use = SID_NAME_DOM_GRP;
791 break;
792 default:
793 return NT_STATUS_INTERNAL_DB_CORRUPTION;
796 str = tldap_talloc_single_attribute(group[0], "samAccountName",
797 talloc_tos());
798 if (str == NULL) {
799 return NT_STATUS_INTERNAL_DB_CORRUPTION;
801 fstrcpy(map->nt_name, str);
802 TALLOC_FREE(str);
804 str = tldap_talloc_single_attribute(group[0], "description",
805 talloc_tos());
806 if (str != NULL) {
807 fstrcpy(map->comment, str);
808 TALLOC_FREE(str);
809 } else {
810 map->comment[0] = '\0';
813 if (pmsg != NULL) {
814 *pmsg = talloc_move(mem_ctx, &group[0]);
816 TALLOC_FREE(group);
817 return NT_STATUS_OK;
820 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
821 struct dom_sid sid)
823 char *filter;
824 NTSTATUS status;
826 filter = talloc_asprintf(talloc_tos(),
827 "(&(objectsid=%s)(objectclass=group))",
828 sid_string_talloc(talloc_tos(), &sid));
829 if (filter == NULL) {
830 return NT_STATUS_NO_MEMORY;
833 status = pdb_ads_getgrfilter(m, map, filter, NULL, NULL);
834 TALLOC_FREE(filter);
835 return status;
838 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
839 gid_t gid)
841 struct dom_sid sid;
842 pdb_ads_gid_to_sid(m, gid, &sid);
843 return pdb_ads_getgrsid(m, map, sid);
846 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
847 const char *name)
849 char *filter;
850 NTSTATUS status;
852 filter = talloc_asprintf(talloc_tos(),
853 "(&(samaccountname=%s)(objectclass=group))",
854 name);
855 if (filter == NULL) {
856 return NT_STATUS_NO_MEMORY;
859 status = pdb_ads_getgrfilter(m, map, filter, NULL, NULL);
860 TALLOC_FREE(filter);
861 return status;
864 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
865 TALLOC_CTX *mem_ctx, const char *name,
866 uint32 *rid)
868 TALLOC_CTX *frame = talloc_stackframe();
869 struct pdb_ads_state *state = talloc_get_type_abort(
870 m->private_data, struct pdb_ads_state);
871 struct tldap_context *ld;
872 const char *attrs[1] = { "objectSid" };
873 int num_mods = 0;
874 struct tldap_mod *mods = NULL;
875 struct tldap_message **alias;
876 struct dom_sid sid;
877 char *dn;
878 int rc;
879 bool ok = true;
881 ld = pdb_ads_ld(state);
882 if (ld == NULL) {
883 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
886 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
887 state->domaindn);
888 if (dn == NULL) {
889 TALLOC_FREE(frame);
890 return NT_STATUS_NO_MEMORY;
893 ok &= tldap_make_mod_fmt(
894 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
895 name);
896 ok &= tldap_make_mod_fmt(
897 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group");
898 ok &= tldap_make_mod_fmt(
899 NULL, talloc_tos(), &mods, &num_mods, "groupType",
900 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
902 if (!ok) {
903 TALLOC_FREE(frame);
904 return NT_STATUS_NO_MEMORY;
907 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
908 if (rc != TLDAP_SUCCESS) {
909 DEBUG(10, ("ldap_add failed %s\n",
910 tldap_errstr(talloc_tos(), state->ld, rc)));
911 TALLOC_FREE(frame);
912 return NT_STATUS_LDAP(rc);
915 rc = pdb_ads_search_fmt(
916 state, state->domaindn, TLDAP_SCOPE_SUB,
917 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
918 "(&(objectclass=group)(samaccountname=%s))", name);
919 if (rc != TLDAP_SUCCESS) {
920 DEBUG(10, ("Could not find just created alias %s: %s\n",
921 name, tldap_errstr(talloc_tos(), state->ld, rc)));
922 TALLOC_FREE(frame);
923 return NT_STATUS_LDAP(rc);
926 if (talloc_array_length(alias) != 1) {
927 DEBUG(10, ("Got %d alias, expected one\n",
928 (int)talloc_array_length(alias)));
929 TALLOC_FREE(frame);
930 return NT_STATUS_LDAP(rc);
933 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
934 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
935 name));
936 TALLOC_FREE(frame);
937 return NT_STATUS_INTERNAL_DB_CORRUPTION;
940 sid_peek_rid(&sid, rid);
941 TALLOC_FREE(frame);
942 return NT_STATUS_OK;
945 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
946 TALLOC_CTX *mem_ctx, uint32 rid)
948 struct pdb_ads_state *state = talloc_get_type_abort(
949 m->private_data, struct pdb_ads_state);
950 struct tldap_context *ld;
951 struct dom_sid sid;
952 char *sidstr;
953 struct tldap_message **msg;
954 char *dn;
955 int rc;
957 sid_compose(&sid, &state->domainsid, rid);
959 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
960 NT_STATUS_HAVE_NO_MEMORY(sidstr);
962 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
963 NULL, 0, 0, talloc_tos(), &msg,
964 ("(&(objectSid=%s)(objectClass=group))"),
965 sidstr);
966 TALLOC_FREE(sidstr);
967 if (rc != TLDAP_SUCCESS) {
968 DEBUG(10, ("ldap_search failed %s\n",
969 tldap_errstr(talloc_tos(), state->ld, rc)));
970 return NT_STATUS_LDAP(rc);
973 switch talloc_array_length(msg) {
974 case 0:
975 return NT_STATUS_NO_SUCH_GROUP;
976 case 1:
977 break;
978 default:
979 return NT_STATUS_INTERNAL_DB_CORRUPTION;
982 if (!tldap_entry_dn(msg[0], &dn)) {
983 TALLOC_FREE(msg);
984 return NT_STATUS_INTERNAL_DB_CORRUPTION;
987 ld = pdb_ads_ld(state);
988 if (ld == NULL) {
989 TALLOC_FREE(msg);
990 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
993 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
994 TALLOC_FREE(msg);
995 if (rc != TLDAP_SUCCESS) {
996 DEBUG(10, ("ldap_delete failed: %s\n",
997 tldap_errstr(talloc_tos(), state->ld, rc)));
998 return NT_STATUS_LDAP(rc);
1001 return NT_STATUS_OK;
1004 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
1005 GROUP_MAP *map)
1007 return NT_STATUS_NOT_IMPLEMENTED;
1010 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
1011 GROUP_MAP *map)
1013 struct pdb_ads_state *state = talloc_get_type_abort(
1014 m->private_data, struct pdb_ads_state);
1015 struct tldap_context *ld;
1016 struct tldap_mod *mods = NULL;
1017 char *filter;
1018 struct tldap_message *existing;
1019 char *dn;
1020 GROUP_MAP existing_map;
1021 int rc, num_mods = 0;
1022 bool ret;
1023 NTSTATUS status;
1025 ld = pdb_ads_ld(state);
1026 if (ld == NULL) {
1027 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1030 filter = talloc_asprintf(talloc_tos(),
1031 "(&(objectsid=%s)(objectclass=group))",
1032 sid_string_talloc(talloc_tos(), &map->sid));
1033 if (filter == NULL) {
1034 return NT_STATUS_NO_MEMORY;
1036 status = pdb_ads_getgrfilter(m, &existing_map, filter,
1037 talloc_tos(), &existing);
1038 TALLOC_FREE(filter);
1040 if (!tldap_entry_dn(existing, &dn)) {
1041 return NT_STATUS_LDAP(TLDAP_DECODING_ERROR);
1044 ret = true;
1046 ret &= tldap_make_mod_fmt(
1047 existing, talloc_tos(), &mods, &num_mods, "description",
1048 "%s", map->comment);
1049 ret &= tldap_make_mod_fmt(
1050 existing, talloc_tos(), &mods, &num_mods, "samaccountname",
1051 "%s", map->nt_name);
1053 if (!ret) {
1054 return NT_STATUS_NO_MEMORY;
1057 if (num_mods == 0) {
1058 TALLOC_FREE(existing);
1059 return NT_STATUS_OK;
1062 rc = tldap_modify(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1063 if (rc != TLDAP_SUCCESS) {
1064 DEBUG(10, ("ldap_modify for %s failed: %s\n", dn,
1065 tldap_errstr(talloc_tos(), ld, rc)));
1066 TALLOC_FREE(existing);
1067 return NT_STATUS_LDAP(rc);
1069 TALLOC_FREE(existing);
1070 return NT_STATUS_OK;
1073 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
1074 struct dom_sid sid)
1076 return NT_STATUS_NOT_IMPLEMENTED;
1079 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
1080 const struct dom_sid *sid,
1081 enum lsa_SidType sid_name_use,
1082 GROUP_MAP **pp_rmap,
1083 size_t *p_num_entries,
1084 bool unix_only)
1086 return NT_STATUS_NOT_IMPLEMENTED;
1089 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
1090 TALLOC_CTX *mem_ctx,
1091 const struct dom_sid *group,
1092 uint32 **pmembers,
1093 size_t *pnum_members)
1095 struct pdb_ads_state *state = talloc_get_type_abort(
1096 m->private_data, struct pdb_ads_state);
1097 const char *attrs[1] = { "member" };
1098 char *sidstr;
1099 struct tldap_message **msg;
1100 int i, rc, num_members;
1101 DATA_BLOB *blobs;
1102 uint32_t *members;
1104 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), group);
1105 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1107 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1108 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1109 &msg, "(objectsid=%s)", sidstr);
1110 TALLOC_FREE(sidstr);
1111 if (rc != TLDAP_SUCCESS) {
1112 DEBUG(10, ("ldap_search failed %s\n",
1113 tldap_errstr(talloc_tos(), state->ld, rc)));
1114 return NT_STATUS_LDAP(rc);
1116 switch talloc_array_length(msg) {
1117 case 0:
1118 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1119 break;
1120 case 1:
1121 break;
1122 default:
1123 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1124 break;
1127 if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
1128 *pmembers = NULL;
1129 *pnum_members = 0;
1130 return NT_STATUS_OK;
1133 members = talloc_array(mem_ctx, uint32_t, num_members);
1134 if (members == NULL) {
1135 return NT_STATUS_NO_MEMORY;
1138 for (i=0; i<num_members; i++) {
1139 struct dom_sid sid;
1140 if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
1141 || !sid_peek_rid(&sid, &members[i])) {
1142 TALLOC_FREE(members);
1143 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1147 *pmembers = members;
1148 *pnum_members = num_members;
1149 return NT_STATUS_OK;
1152 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
1153 TALLOC_CTX *mem_ctx,
1154 struct samu *user,
1155 struct dom_sid **pp_sids,
1156 gid_t **pp_gids,
1157 uint32_t *p_num_groups)
1159 struct pdb_ads_state *state = talloc_get_type_abort(
1160 m->private_data, struct pdb_ads_state);
1161 struct pdb_ads_samu_private *priv;
1162 const char *attrs[1] = { "objectSid" };
1163 struct tldap_message **groups;
1164 int i, rc, count;
1165 size_t num_groups;
1166 struct dom_sid *group_sids;
1167 gid_t *gids;
1169 priv = pdb_ads_get_samu_private(m, user);
1170 if (priv != NULL) {
1171 rc = pdb_ads_search_fmt(
1172 state, state->domaindn, TLDAP_SCOPE_SUB,
1173 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
1174 "(&(member=%s)(grouptype=%d)(objectclass=group))",
1175 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
1176 if (rc != TLDAP_SUCCESS) {
1177 DEBUG(10, ("ldap_search failed %s\n",
1178 tldap_errstr(talloc_tos(), state->ld, rc)));
1179 return NT_STATUS_LDAP(rc);
1181 count = talloc_array_length(groups);
1182 } else {
1184 * This happens for artificial samu users
1186 DEBUG(10, ("Could not get pdb_ads_samu_private\n"));
1187 count = 0;
1190 group_sids = talloc_array(mem_ctx, struct dom_sid, count+1);
1191 if (group_sids == NULL) {
1192 return NT_STATUS_NO_MEMORY;
1194 gids = talloc_array(mem_ctx, gid_t, count+1);
1195 if (gids == NULL) {
1196 TALLOC_FREE(group_sids);
1197 return NT_STATUS_NO_MEMORY;
1200 sid_copy(&group_sids[0], pdb_get_group_sid(user));
1201 if (!sid_to_gid(&group_sids[0], &gids[0])) {
1202 TALLOC_FREE(gids);
1203 TALLOC_FREE(group_sids);
1204 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1206 num_groups = 1;
1208 for (i=0; i<count; i++) {
1209 if (!tldap_pull_binsid(groups[i], "objectSid",
1210 &group_sids[num_groups])) {
1211 continue;
1213 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
1215 num_groups += 1;
1216 if (num_groups == count) {
1217 break;
1221 *pp_sids = group_sids;
1222 *pp_gids = gids;
1223 *p_num_groups = num_groups;
1224 return NT_STATUS_OK;
1227 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
1228 TALLOC_CTX *mem_ctx,
1229 struct samu *user)
1231 return NT_STATUS_NOT_IMPLEMENTED;
1234 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
1235 TALLOC_CTX *mem_ctx,
1236 uint32 grouprid, uint32 memberrid,
1237 int mod_op)
1239 struct pdb_ads_state *state = talloc_get_type_abort(
1240 m->private_data, struct pdb_ads_state);
1241 TALLOC_CTX *frame = talloc_stackframe();
1242 struct tldap_context *ld;
1243 struct dom_sid groupsid, membersid;
1244 char *groupdn, *memberdn;
1245 struct tldap_mod *mods;
1246 int num_mods;
1247 int rc;
1248 NTSTATUS status;
1250 ld = pdb_ads_ld(state);
1251 if (ld == NULL) {
1252 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1255 sid_compose(&groupsid, &state->domainsid, grouprid);
1256 sid_compose(&membersid, &state->domainsid, memberrid);
1258 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
1259 if (!NT_STATUS_IS_OK(status)) {
1260 TALLOC_FREE(frame);
1261 return NT_STATUS_NO_SUCH_GROUP;
1263 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
1264 if (!NT_STATUS_IS_OK(status)) {
1265 TALLOC_FREE(frame);
1266 return NT_STATUS_NO_SUCH_USER;
1269 mods = NULL;
1270 num_mods = 0;
1272 if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op,
1273 "member", memberdn)) {
1274 TALLOC_FREE(frame);
1275 return NT_STATUS_NO_MEMORY;
1278 rc = tldap_modify(ld, groupdn, mods, num_mods, NULL, 0, NULL, 0);
1279 TALLOC_FREE(frame);
1280 if (rc != TLDAP_SUCCESS) {
1281 DEBUG(10, ("ldap_modify failed: %s\n",
1282 tldap_errstr(talloc_tos(), state->ld, rc)));
1283 if ((mod_op == TLDAP_MOD_ADD) &&
1284 (rc == TLDAP_ALREADY_EXISTS)) {
1285 return NT_STATUS_MEMBER_IN_GROUP;
1287 if ((mod_op == TLDAP_MOD_DELETE) &&
1288 (rc == TLDAP_UNWILLING_TO_PERFORM)) {
1289 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1291 return NT_STATUS_LDAP(rc);
1294 return NT_STATUS_OK;
1297 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
1298 TALLOC_CTX *mem_ctx,
1299 uint32 group_rid, uint32 member_rid)
1301 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1302 TLDAP_MOD_ADD);
1305 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
1306 TALLOC_CTX *mem_ctx,
1307 uint32 group_rid, uint32 member_rid)
1309 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1310 TLDAP_MOD_DELETE);
1313 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
1314 const char *name, uint32 *rid)
1316 TALLOC_CTX *frame = talloc_stackframe();
1317 struct pdb_ads_state *state = talloc_get_type_abort(
1318 m->private_data, struct pdb_ads_state);
1319 struct tldap_context *ld;
1320 const char *attrs[1] = { "objectSid" };
1321 int num_mods = 0;
1322 struct tldap_mod *mods = NULL;
1323 struct tldap_message **alias;
1324 struct dom_sid sid;
1325 char *dn;
1326 int rc;
1327 bool ok = true;
1329 ld = pdb_ads_ld(state);
1330 if (ld == NULL) {
1331 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1334 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1335 state->domaindn);
1336 if (dn == NULL) {
1337 TALLOC_FREE(frame);
1338 return NT_STATUS_NO_MEMORY;
1341 ok &= tldap_make_mod_fmt(
1342 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
1343 name);
1344 ok &= tldap_make_mod_fmt(
1345 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group");
1346 ok &= tldap_make_mod_fmt(
1347 NULL, talloc_tos(), &mods, &num_mods, "groupType",
1348 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1350 if (!ok) {
1351 TALLOC_FREE(frame);
1352 return NT_STATUS_NO_MEMORY;
1355 rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1356 if (rc != TLDAP_SUCCESS) {
1357 DEBUG(10, ("ldap_add failed %s\n",
1358 tldap_errstr(talloc_tos(), state->ld, rc)));
1359 TALLOC_FREE(frame);
1360 return NT_STATUS_LDAP(rc);
1363 rc = pdb_ads_search_fmt(
1364 state, state->domaindn, TLDAP_SCOPE_SUB,
1365 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1366 "(&(objectclass=group)(samaccountname=%s))", name);
1367 if (rc != TLDAP_SUCCESS) {
1368 DEBUG(10, ("Could not find just created alias %s: %s\n",
1369 name, tldap_errstr(talloc_tos(), state->ld, rc)));
1370 TALLOC_FREE(frame);
1371 return NT_STATUS_LDAP(rc);
1374 if (talloc_array_length(alias) != 1) {
1375 DEBUG(10, ("Got %d alias, expected one\n",
1376 (int)talloc_array_length(alias)));
1377 TALLOC_FREE(frame);
1378 return NT_STATUS_LDAP(rc);
1381 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1382 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1383 name));
1384 TALLOC_FREE(frame);
1385 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1388 sid_peek_rid(&sid, rid);
1389 TALLOC_FREE(frame);
1390 return NT_STATUS_OK;
1393 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1394 const struct dom_sid *sid)
1396 struct pdb_ads_state *state = talloc_get_type_abort(
1397 m->private_data, struct pdb_ads_state);
1398 struct tldap_context *ld;
1399 struct tldap_message **alias;
1400 char *sidstr, *dn = NULL;
1401 int rc;
1403 ld = pdb_ads_ld(state);
1404 if (ld == NULL) {
1405 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1408 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1409 if (sidstr == NULL) {
1410 return NT_STATUS_NO_MEMORY;
1413 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1414 NULL, 0, 0, talloc_tos(), &alias,
1415 "(&(objectSid=%s)(objectclass=group)"
1416 "(|(grouptype=%d)(grouptype=%d)))",
1417 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1418 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1419 TALLOC_FREE(sidstr);
1420 if (rc != TLDAP_SUCCESS) {
1421 DEBUG(10, ("ldap_search failed: %s\n",
1422 tldap_errstr(talloc_tos(), state->ld, rc)));
1423 return NT_STATUS_LDAP(rc);
1425 if (talloc_array_length(alias) != 1) {
1426 DEBUG(10, ("Expected 1 alias, got %d\n",
1427 (int)talloc_array_length(alias)));
1428 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1430 if (!tldap_entry_dn(alias[0], &dn)) {
1431 DEBUG(10, ("Could not get DN for alias %s\n",
1432 sid_string_dbg(sid)));
1433 return NT_STATUS_INTERNAL_ERROR;
1436 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
1437 if (rc != TLDAP_SUCCESS) {
1438 DEBUG(10, ("ldap_delete failed: %s\n",
1439 tldap_errstr(talloc_tos(), state->ld, rc)));
1440 return NT_STATUS_LDAP(rc);
1443 return NT_STATUS_OK;
1446 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1447 const struct dom_sid *sid,
1448 struct acct_info *info)
1450 struct pdb_ads_state *state = talloc_get_type_abort(
1451 m->private_data, struct pdb_ads_state);
1452 struct tldap_context *ld;
1453 const char *attrs[3] = { "objectSid", "description",
1454 "samAccountName" };
1455 struct tldap_message **msg;
1456 char *sidstr, *dn;
1457 int rc;
1458 struct tldap_mod *mods;
1459 int num_mods;
1460 bool ok;
1462 ld = pdb_ads_ld(state);
1463 if (ld == NULL) {
1464 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1467 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1468 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1470 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1471 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1472 &msg, "(&(objectSid=%s)(objectclass=group)"
1473 "(|(grouptype=%d)(grouptype=%d)))",
1474 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1475 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1476 TALLOC_FREE(sidstr);
1477 if (rc != TLDAP_SUCCESS) {
1478 DEBUG(10, ("ldap_search failed %s\n",
1479 tldap_errstr(talloc_tos(), state->ld, rc)));
1480 return NT_STATUS_LDAP(rc);
1482 switch talloc_array_length(msg) {
1483 case 0:
1484 return NT_STATUS_NO_SUCH_ALIAS;
1485 case 1:
1486 break;
1487 default:
1488 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1491 if (!tldap_entry_dn(msg[0], &dn)) {
1492 TALLOC_FREE(msg);
1493 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1496 mods = NULL;
1497 num_mods = 0;
1498 ok = true;
1500 ok &= tldap_make_mod_fmt(
1501 msg[0], msg, &mods, &num_mods, "description",
1502 "%s", info->acct_desc);
1503 ok &= tldap_make_mod_fmt(
1504 msg[0], msg, &mods, &num_mods, "samAccountName",
1505 "%s", info->acct_name);
1506 if (!ok) {
1507 TALLOC_FREE(msg);
1508 return NT_STATUS_NO_MEMORY;
1510 if (num_mods == 0) {
1511 /* no change */
1512 TALLOC_FREE(msg);
1513 return NT_STATUS_OK;
1516 rc = tldap_modify(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1517 TALLOC_FREE(msg);
1518 if (rc != TLDAP_SUCCESS) {
1519 DEBUG(10, ("ldap_modify failed: %s\n",
1520 tldap_errstr(talloc_tos(), state->ld, rc)));
1521 return NT_STATUS_LDAP(rc);
1523 return NT_STATUS_OK;
1526 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1527 const struct dom_sid *sid,
1528 TALLOC_CTX *mem_ctx, char **pdn)
1530 struct tldap_message **msg;
1531 char *sidstr, *dn;
1532 int rc;
1534 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1535 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1537 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1538 NULL, 0, 0, talloc_tos(), &msg,
1539 "(objectsid=%s)", sidstr);
1540 TALLOC_FREE(sidstr);
1541 if (rc != TLDAP_SUCCESS) {
1542 DEBUG(10, ("ldap_search failed %s\n",
1543 tldap_errstr(talloc_tos(), state->ld, rc)));
1544 return NT_STATUS_LDAP(rc);
1547 switch talloc_array_length(msg) {
1548 case 0:
1549 return NT_STATUS_NOT_FOUND;
1550 case 1:
1551 break;
1552 default:
1553 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1556 if (!tldap_entry_dn(msg[0], &dn)) {
1557 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1560 dn = talloc_strdup(mem_ctx, dn);
1561 if (dn == NULL) {
1562 return NT_STATUS_NO_MEMORY;
1564 TALLOC_FREE(msg);
1566 *pdn = dn;
1567 return NT_STATUS_OK;
1570 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1571 const struct dom_sid *alias,
1572 const struct dom_sid *member,
1573 int mod_op)
1575 struct pdb_ads_state *state = talloc_get_type_abort(
1576 m->private_data, struct pdb_ads_state);
1577 struct tldap_context *ld;
1578 TALLOC_CTX *frame = talloc_stackframe();
1579 struct tldap_mod *mods;
1580 int num_mods;
1581 int rc;
1582 char *aliasdn, *memberdn;
1583 NTSTATUS status;
1585 ld = pdb_ads_ld(state);
1586 if (ld == NULL) {
1587 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1590 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1591 if (!NT_STATUS_IS_OK(status)) {
1592 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1593 sid_string_dbg(alias), nt_errstr(status)));
1594 TALLOC_FREE(frame);
1595 return NT_STATUS_NO_SUCH_ALIAS;
1597 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1598 if (!NT_STATUS_IS_OK(status)) {
1599 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1600 sid_string_dbg(member), nt_errstr(status)));
1601 TALLOC_FREE(frame);
1602 return status;
1605 mods = NULL;
1606 num_mods = 0;
1608 if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op,
1609 "member", memberdn)) {
1610 TALLOC_FREE(frame);
1611 return NT_STATUS_NO_MEMORY;
1614 rc = tldap_modify(ld, aliasdn, mods, num_mods, NULL, 0, NULL, 0);
1615 TALLOC_FREE(frame);
1616 if (rc != TLDAP_SUCCESS) {
1617 DEBUG(10, ("ldap_modify failed: %s\n",
1618 tldap_errstr(talloc_tos(), state->ld, rc)));
1619 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1620 return NT_STATUS_MEMBER_IN_ALIAS;
1622 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1623 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1625 return NT_STATUS_LDAP(rc);
1628 return NT_STATUS_OK;
1631 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1632 const struct dom_sid *alias,
1633 const struct dom_sid *member)
1635 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1638 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1639 const struct dom_sid *alias,
1640 const struct dom_sid *member)
1642 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1645 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
1646 struct dom_sid *psid)
1648 const char *attrs[1] = { "objectSid" };
1649 struct tldap_message **msg;
1650 char *dn;
1651 size_t len;
1652 int rc;
1653 bool ret;
1655 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1656 dnblob->data, dnblob->length, &dn, &len)) {
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);