source: trunk/server/source3/passdb/pdb_ads.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 69.4 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 pdb_ldap with ads schema
4 Copyright (C) Volker Lendecke 2009
5
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.
10
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.
15
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/>.
18*/
19
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"
30
31struct 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;
39};
40
41struct pdb_ads_samu_private {
42 char *dn;
43 struct tldap_message *ldapmsg;
44};
45
46static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
47 struct dom_sid *sid);
48static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
49 struct dom_sid *psid);
50static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
51 const struct dom_sid *sid,
52 TALLOC_CTX *mem_ctx, char **pdn);
53static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state);
54static 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, ...);
59static 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);
63
64static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
65 time_t *ptime)
66{
67 uint64_t tmp;
68
69 if (!tldap_pull_uint64(msg, attr, &tmp)) {
70 return false;
71 }
72 *ptime = nt_time_to_unix(tmp);
73 return true;
74}
75
76static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
77{
78 uint32_t rid;
79 sid_peek_rid(sid, &rid);
80 return rid;
81}
82
83static char *pdb_ads_domaindn2dns(TALLOC_CTX *mem_ctx, char *dn)
84{
85 char *result, *p;
86
87 result = talloc_string_sub2(mem_ctx, dn, "DC=", "", false, false,
88 true);
89 if (result == NULL) {
90 return NULL;
91 }
92
93 while ((p = strchr_m(result, ',')) != NULL) {
94 *p = '.';
95 }
96
97 return result;
98}
99
100static struct pdb_domain_info *pdb_ads_get_domain_info(
101 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
102{
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;
108
109 info = talloc(mem_ctx, struct pdb_domain_info);
110 if (info == NULL) {
111 return NULL;
112 }
113 info->name = talloc_strdup(info, state->netbiosname);
114 if (info->name == NULL) {
115 goto fail;
116 }
117 info->dns_domain = pdb_ads_domaindn2dns(info, state->domaindn);
118 if (info->dns_domain == NULL) {
119 goto fail;
120 }
121
122 rootdse = tldap_rootdse(state->ld);
123 tmp = tldap_talloc_single_attribute(rootdse, "rootDomainNamingContext",
124 talloc_tos());
125 if (tmp == NULL) {
126 goto fail;
127 }
128 info->dns_forest = pdb_ads_domaindn2dns(info, tmp);
129 TALLOC_FREE(tmp);
130 if (info->dns_forest == NULL) {
131 goto fail;
132 }
133 info->sid = state->domainsid;
134 info->guid = state->domainguid;
135 return info;
136
137fail:
138 TALLOC_FREE(info);
139 return NULL;
140}
141
142static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
143 struct pdb_methods *m, struct samu *sam)
144{
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;
150
151 result = (struct pdb_ads_samu_private *)
152 pdb_get_backend_private_data(sam, m);
153
154 if (result != NULL) {
155 return talloc_get_type_abort(
156 result, struct pdb_ads_samu_private);
157 }
158
159 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), pdb_get_user_sid(sam));
160 if (sidstr == NULL) {
161 return NULL;
162 }
163
164 filter = talloc_asprintf(
165 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
166 TALLOC_FREE(sidstr);
167 if (filter == NULL) {
168 return NULL;
169 }
170
171 status = pdb_ads_getsamupriv(state, filter, sam, &result);
172 TALLOC_FREE(filter);
173 if (!NT_STATUS_IS_OK(status)) {
174 return NULL;
175 }
176
177 return result;
178}
179
180static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m,
181 struct samu *sam,
182 struct pdb_ads_samu_private *priv)
183{
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;
195
196 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
197 if (str == NULL) {
198 DEBUG(10, ("no samAccountName\n"));
199 goto fail;
200 }
201 pdb_set_username(sam, str, PDB_SET);
202
203 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
204 pdb_set_logon_time(sam, tmp_time, PDB_SET);
205 }
206 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
207 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
208 }
209 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
210 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
211 }
212 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
213 pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
214 }
215
216 str = tldap_talloc_single_attribute(entry, "displayName",
217 talloc_tos());
218 if (str != NULL) {
219 pdb_set_fullname(sam, str, PDB_SET);
220 }
221
222 str = tldap_talloc_single_attribute(entry, "homeDirectory",
223 talloc_tos());
224 if (str != NULL) {
225 pdb_set_homedir(sam, str, PDB_SET);
226 }
227
228 str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
229 if (str != NULL) {
230 pdb_set_dir_drive(sam, str, PDB_SET);
231 }
232
233 str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
234 if (str != NULL) {
235 pdb_set_logon_script(sam, str, PDB_SET);
236 }
237
238 str = tldap_talloc_single_attribute(entry, "profilePath",
239 talloc_tos());
240 if (str != NULL) {
241 pdb_set_profile_path(sam, str, PDB_SET);
242 }
243
244 str = tldap_talloc_single_attribute(entry, "profilePath",
245 talloc_tos());
246 if (str != NULL) {
247 pdb_set_profile_path(sam, str, PDB_SET);
248 }
249
250 str = tldap_talloc_single_attribute(entry, "comment",
251 talloc_tos());
252 if (str != NULL) {
253 pdb_set_comment(sam, str, PDB_SET);
254 }
255
256 str = tldap_talloc_single_attribute(entry, "description",
257 talloc_tos());
258 if (str != NULL) {
259 pdb_set_acct_desc(sam, str, PDB_SET);
260 }
261
262 str = tldap_talloc_single_attribute(entry, "userWorkstations",
263 talloc_tos());
264 if (str != NULL) {
265 pdb_set_workstations(sam, str, PDB_SET);
266 }
267
268 str = tldap_talloc_single_attribute(entry, "userParameters",
269 talloc_tos());
270 if (str != NULL) {
271 pdb_set_munged_dial(sam, str, PDB_SET);
272 }
273
274 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
275 DEBUG(10, ("Could not pull SID\n"));
276 goto fail;
277 }
278 pdb_set_user_sid(sam, &sid, PDB_SET);
279
280 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
281 DEBUG(10, ("Could not pull userAccountControl\n"));
282 goto fail;
283 }
284 pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
285
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;
291 }
292 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
293 }
294
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;
300 }
301 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
302 }
303
304 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
305 sid_compose(&sid, &state->domainsid, n);
306 pdb_set_group_sid(sam, &sid, PDB_SET);
307
308 }
309
310 if (tldap_pull_uint32(entry, "countryCode", &i)) {
311 pdb_set_country_code(sam, i, PDB_SET);
312 }
313
314 if (tldap_pull_uint32(entry, "codePage", &i)) {
315 pdb_set_code_page(sam, i, PDB_SET);
316 }
317
318 if (tldap_get_single_valueblob(entry, "logonHours", &blob)) {
319
320 if (blob.length > MAX_HOURS_LEN) {
321 status = NT_STATUS_INVALID_PARAMETER;
322 goto fail;
323 }
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);
327
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);
334 }
335
336 status = NT_STATUS_OK;
337fail:
338 TALLOC_FREE(frame);
339 return status;
340}
341
342static 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)
346{
347 uint64_t nt_time;
348
349 unix_to_nt_time(&nt_time, t);
350
351 return tldap_make_mod_fmt(
352 existing, mem_ctx, pmods, pnum_mods, attrib,
353 "%llu", nt_time);
354}
355
356static 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)
361{
362 bool ret = true;
363 DATA_BLOB blob;
364 const char *pw;
365
366 /* TODO: All fields :-) */
367
368 ret &= tldap_make_mod_fmt(
369 existing, mem_ctx, pmods, pnum_mods, "displayName",
370 "%s", pdb_get_fullname(sam));
371
372 pw = pdb_get_plaintext_passwd(sam);
373
374 /*
375 * If we have the plain text pw, this is probably about to be
376 * set. Is this true always?
377 */
378 if (pw != NULL) {
379 char *pw_quote;
380 uint8_t *pw_utf16;
381 size_t pw_utf16_len;
382
383 pw_quote = talloc_asprintf(talloc_tos(), "\"%s\"", pw);
384 if (pw_quote == NULL) {
385 ret = false;
386 goto fail;
387 }
388
389 ret &= convert_string_talloc(talloc_tos(),
390 CH_UNIX, CH_UTF16LE,
391 pw_quote, strlen(pw_quote),
392 &pw_utf16, &pw_utf16_len, false);
393 if (!ret) {
394 goto fail;
395 }
396 blob = data_blob_const(pw_utf16, pw_utf16_len);
397
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);
403 }
404
405 ret &= tldap_make_mod_fmt(
406 existing, mem_ctx, pmods, pnum_mods, "userAccountControl",
407 "%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
408
409 ret &= tldap_make_mod_fmt(
410 existing, mem_ctx, pmods, pnum_mods, "homeDirectory",
411 "%s", pdb_get_homedir(sam));
412
413 ret &= tldap_make_mod_fmt(
414 existing, mem_ctx, pmods, pnum_mods, "homeDrive",
415 "%s", pdb_get_dir_drive(sam));
416
417 ret &= tldap_make_mod_fmt(
418 existing, mem_ctx, pmods, pnum_mods, "scriptPath",
419 "%s", pdb_get_logon_script(sam));
420
421 ret &= tldap_make_mod_fmt(
422 existing, mem_ctx, pmods, pnum_mods, "profilePath",
423 "%s", pdb_get_profile_path(sam));
424
425 ret &= tldap_make_mod_fmt(
426 existing, mem_ctx, pmods, pnum_mods, "comment",
427 "%s", pdb_get_comment(sam));
428
429 ret &= tldap_make_mod_fmt(
430 existing, mem_ctx, pmods, pnum_mods, "description",
431 "%s", pdb_get_acct_desc(sam));
432
433 ret &= tldap_make_mod_fmt(
434 existing, mem_ctx, pmods, pnum_mods, "userWorkstations",
435 "%s", pdb_get_workstations(sam));
436
437 ret &= tldap_make_mod_fmt(
438 existing, mem_ctx, pmods, pnum_mods, "userParameters",
439 "%s", pdb_get_munged_dial(sam));
440
441 ret &= tldap_make_mod_fmt(
442 existing, mem_ctx, pmods, pnum_mods, "countryCode",
443 "%i", (int)pdb_get_country_code(sam));
444
445 ret &= tldap_make_mod_fmt(
446 existing, mem_ctx, pmods, pnum_mods, "codePage",
447 "%i", (int)pdb_get_code_page(sam));
448
449 ret &= pdb_ads_make_time_mod(
450 existing, mem_ctx, pmods, pnum_mods, "accountExpires",
451 (int)pdb_get_kickoff_time(sam));
452
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)));
456
457fail:
458 return ret;
459}
460
461static 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)
465{
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;
477
478 result = talloc(mem_ctx, struct pdb_ads_samu_private);
479 if (result == NULL) {
480 return NT_STATUS_NO_MEMORY;
481 }
482
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);
491 }
492
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;
498 }
499
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;
505 }
506
507 *presult = result;
508 return NT_STATUS_OK;
509}
510
511static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
512 struct pdb_ads_state *state,
513 struct samu *sam_acct,
514 const char *filter)
515{
516 struct pdb_ads_samu_private *priv;
517 NTSTATUS status;
518
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;
524 }
525
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;
532 }
533
534 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
535 return NT_STATUS_OK;
536}
537
538static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
539 struct samu *sam_acct,
540 const char *username)
541{
542 struct pdb_ads_state *state = talloc_get_type_abort(
543 m->private_data, struct pdb_ads_state);
544 char *filter;
545
546 filter = talloc_asprintf(
547 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
548 username);
549 NT_STATUS_HAVE_NO_MEMORY(filter);
550
551 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
552}
553
554static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
555 struct samu *sam_acct,
556 const struct dom_sid *sid)
557{
558 struct pdb_ads_state *state = talloc_get_type_abort(
559 m->private_data, struct pdb_ads_state);
560 char *sidstr, *filter;
561
562 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
563 NT_STATUS_HAVE_NO_MEMORY(sidstr);
564
565 filter = talloc_asprintf(
566 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
567 TALLOC_FREE(sidstr);
568 NT_STATUS_HAVE_NO_MEMORY(filter);
569
570 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
571}
572
573static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
574 TALLOC_CTX *tmp_ctx,
575 const char *name, uint32 acct_flags,
576 uint32 *rid)
577{
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;
589
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;
594 }
595
596 ld = pdb_ads_ld(state);
597 if (ld == NULL) {
598 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
599 }
600
601 /* TODO: Create machines etc */
602
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;
611 }
612
613
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);
620 }
621
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);
632 }
633
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);
639 }
640
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;
646 }
647
648 sid_peek_rid(&sid, rid);
649 TALLOC_FREE(dn);
650 return NT_STATUS_OK;
651}
652
653static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
654 TALLOC_CTX *tmp_ctx,
655 struct samu *sam)
656{
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;
663
664 ld = pdb_ads_ld(state);
665 if (ld == NULL) {
666 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
667 }
668
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;
673 }
674
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);
681 }
682 return NT_STATUS_OK;
683}
684
685static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
686 struct samu *sampass)
687{
688 return NT_STATUS_NOT_IMPLEMENTED;
689}
690
691static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
692 struct samu *sam)
693{
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;
700
701 ld = pdb_ads_ld(state);
702 if (ld == NULL) {
703 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
704 }
705
706 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
707 &mods, &num_mods, sam)) {
708 return NT_STATUS_NO_MEMORY;
709 }
710
711 if (num_mods == 0) {
712 /* Nothing to do, just return success */
713 return NT_STATUS_OK;
714 }
715
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);
723 }
724
725 return NT_STATUS_OK;
726}
727
728static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
729 struct samu *username)
730{
731 return NT_STATUS_NOT_IMPLEMENTED;
732}
733
734static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
735 struct samu *oldname,
736 const char *newname)
737{
738 return NT_STATUS_NOT_IMPLEMENTED;
739}
740
741static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
742 struct samu *sam_acct,
743 bool success)
744{
745 return NT_STATUS_NOT_IMPLEMENTED;
746}
747
748static 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)
752{
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;
761
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);
769 }
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;
774 }
775
776 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
777 return NT_STATUS_INTERNAL_DB_CORRUPTION;
778 }
779 map->gid = pdb_ads_sid2gid(&map->sid);
780
781 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
782 return NT_STATUS_INTERNAL_DB_CORRUPTION;
783 }
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;
794 }
795
796 str = tldap_talloc_single_attribute(group[0], "samAccountName",
797 talloc_tos());
798 if (str == NULL) {
799 return NT_STATUS_INTERNAL_DB_CORRUPTION;
800 }
801 fstrcpy(map->nt_name, str);
802 TALLOC_FREE(str);
803
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';
811 }
812
813 if (pmsg != NULL) {
814 *pmsg = talloc_move(mem_ctx, &group[0]);
815 }
816 TALLOC_FREE(group);
817 return NT_STATUS_OK;
818}
819
820static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
821 struct dom_sid sid)
822{
823 char *filter;
824 NTSTATUS status;
825
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;
831 }
832
833 status = pdb_ads_getgrfilter(m, map, filter, NULL, NULL);
834 TALLOC_FREE(filter);
835 return status;
836}
837
838static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
839 gid_t gid)
840{
841 struct dom_sid sid;
842 pdb_ads_gid_to_sid(m, gid, &sid);
843 return pdb_ads_getgrsid(m, map, sid);
844}
845
846static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
847 const char *name)
848{
849 char *filter;
850 NTSTATUS status;
851
852 filter = talloc_asprintf(talloc_tos(),
853 "(&(samaccountname=%s)(objectclass=group))",
854 name);
855 if (filter == NULL) {
856 return NT_STATUS_NO_MEMORY;
857 }
858
859 status = pdb_ads_getgrfilter(m, map, filter, NULL, NULL);
860 TALLOC_FREE(filter);
861 return status;
862}
863
864static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
865 TALLOC_CTX *mem_ctx, const char *name,
866 uint32 *rid)
867{
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;
880
881 ld = pdb_ads_ld(state);
882 if (ld == NULL) {
883 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
884 }
885
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;
891 }
892
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);
901
902 if (!ok) {
903 TALLOC_FREE(frame);
904 return NT_STATUS_NO_MEMORY;
905 }
906
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);
913 }
914
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);
924 }
925
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);
931 }
932
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;
938 }
939
940 sid_peek_rid(&sid, rid);
941 TALLOC_FREE(frame);
942 return NT_STATUS_OK;
943}
944
945static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
946 TALLOC_CTX *mem_ctx, uint32 rid)
947{
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;
956
957 sid_compose(&sid, &state->domainsid, rid);
958
959 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
960 NT_STATUS_HAVE_NO_MEMORY(sidstr);
961
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);
971 }
972
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;
980 }
981
982 if (!tldap_entry_dn(msg[0], &dn)) {
983 TALLOC_FREE(msg);
984 return NT_STATUS_INTERNAL_DB_CORRUPTION;
985 }
986
987 ld = pdb_ads_ld(state);
988 if (ld == NULL) {
989 TALLOC_FREE(msg);
990 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
991 }
992
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);
999 }
1000
1001 return NT_STATUS_OK;
1002}
1003
1004static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
1005 GROUP_MAP *map)
1006{
1007 return NT_STATUS_NOT_IMPLEMENTED;
1008}
1009
1010static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
1011 GROUP_MAP *map)
1012{
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;
1024
1025 ld = pdb_ads_ld(state);
1026 if (ld == NULL) {
1027 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1028 }
1029
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;
1035 }
1036 status = pdb_ads_getgrfilter(m, &existing_map, filter,
1037 talloc_tos(), &existing);
1038 TALLOC_FREE(filter);
1039
1040 if (!tldap_entry_dn(existing, &dn)) {
1041 return NT_STATUS_LDAP(TLDAP_DECODING_ERROR);
1042 }
1043
1044 ret = true;
1045
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);
1052
1053 if (!ret) {
1054 return NT_STATUS_NO_MEMORY;
1055 }
1056
1057 if (num_mods == 0) {
1058 TALLOC_FREE(existing);
1059 return NT_STATUS_OK;
1060 }
1061
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);
1068 }
1069 TALLOC_FREE(existing);
1070 return NT_STATUS_OK;
1071}
1072
1073static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
1074 struct dom_sid sid)
1075{
1076 return NT_STATUS_NOT_IMPLEMENTED;
1077}
1078
1079static 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)
1085{
1086 return NT_STATUS_NOT_IMPLEMENTED;
1087}
1088
1089static 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)
1094{
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;
1103
1104 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), group);
1105 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1106
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);
1115 }
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;
1125 }
1126
1127 if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
1128 *pmembers = NULL;
1129 *pnum_members = 0;
1130 return NT_STATUS_OK;
1131 }
1132
1133 members = talloc_array(mem_ctx, uint32_t, num_members);
1134 if (members == NULL) {
1135 return NT_STATUS_NO_MEMORY;
1136 }
1137
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;
1144 }
1145 }
1146
1147 *pmembers = members;
1148 *pnum_members = num_members;
1149 return NT_STATUS_OK;
1150}
1151
1152static 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)
1158{
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;
1168
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);
1180 }
1181 count = talloc_array_length(groups);
1182 } else {
1183 /*
1184 * This happens for artificial samu users
1185 */
1186 DEBUG(10, ("Could not get pdb_ads_samu_private\n"));
1187 count = 0;
1188 }
1189
1190 group_sids = talloc_array(mem_ctx, struct dom_sid, count+1);
1191 if (group_sids == NULL) {
1192 return NT_STATUS_NO_MEMORY;
1193 }
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;
1198 }
1199
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;
1205 }
1206 num_groups = 1;
1207
1208 for (i=0; i<count; i++) {
1209 if (!tldap_pull_binsid(groups[i], "objectSid",
1210 &group_sids[num_groups])) {
1211 continue;
1212 }
1213 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
1214
1215 num_groups += 1;
1216 if (num_groups == count) {
1217 break;
1218 }
1219 }
1220
1221 *pp_sids = group_sids;
1222 *pp_gids = gids;
1223 *p_num_groups = num_groups;
1224 return NT_STATUS_OK;
1225}
1226
1227static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
1228 TALLOC_CTX *mem_ctx,
1229 struct samu *user)
1230{
1231 return NT_STATUS_NOT_IMPLEMENTED;
1232}
1233
1234static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
1235 TALLOC_CTX *mem_ctx,
1236 uint32 grouprid, uint32 memberrid,
1237 int mod_op)
1238{
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;
1249
1250 ld = pdb_ads_ld(state);
1251 if (ld == NULL) {
1252 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1253 }
1254
1255 sid_compose(&groupsid, &state->domainsid, grouprid);
1256 sid_compose(&membersid, &state->domainsid, memberrid);
1257
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;
1262 }
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;
1267 }
1268
1269 mods = NULL;
1270 num_mods = 0;
1271
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;
1276 }
1277
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;
1286 }
1287 if ((mod_op == TLDAP_MOD_DELETE) &&
1288 (rc == TLDAP_UNWILLING_TO_PERFORM)) {
1289 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1290 }
1291 return NT_STATUS_LDAP(rc);
1292 }
1293
1294 return NT_STATUS_OK;
1295}
1296
1297static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
1298 TALLOC_CTX *mem_ctx,
1299 uint32 group_rid, uint32 member_rid)
1300{
1301 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1302 TLDAP_MOD_ADD);
1303}
1304
1305static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
1306 TALLOC_CTX *mem_ctx,
1307 uint32 group_rid, uint32 member_rid)
1308{
1309 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1310 TLDAP_MOD_DELETE);
1311}
1312
1313static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
1314 const char *name, uint32 *rid)
1315{
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;
1328
1329 ld = pdb_ads_ld(state);
1330 if (ld == NULL) {
1331 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1332 }
1333
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;
1339 }
1340
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);
1349
1350 if (!ok) {
1351 TALLOC_FREE(frame);
1352 return NT_STATUS_NO_MEMORY;
1353 }
1354
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);
1361 }
1362
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);
1372 }
1373
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);
1379 }
1380
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;
1386 }
1387
1388 sid_peek_rid(&sid, rid);
1389 TALLOC_FREE(frame);
1390 return NT_STATUS_OK;
1391}
1392
1393static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1394 const struct dom_sid *sid)
1395{
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;
1402
1403 ld = pdb_ads_ld(state);
1404 if (ld == NULL) {
1405 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1406 }
1407
1408 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1409 if (sidstr == NULL) {
1410 return NT_STATUS_NO_MEMORY;
1411 }
1412
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);
1424 }
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;
1429 }
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;
1434 }
1435
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);
1441 }
1442
1443 return NT_STATUS_OK;
1444}
1445
1446static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1447 const struct dom_sid *sid,
1448 struct acct_info *info)
1449{
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;
1461
1462 ld = pdb_ads_ld(state);
1463 if (ld == NULL) {
1464 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1465 }
1466
1467 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1468 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1469
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);
1481 }
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;
1489 }
1490
1491 if (!tldap_entry_dn(msg[0], &dn)) {
1492 TALLOC_FREE(msg);
1493 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1494 }
1495
1496 mods = NULL;
1497 num_mods = 0;
1498 ok = true;
1499
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;
1509 }
1510 if (num_mods == 0) {
1511 /* no change */
1512 TALLOC_FREE(msg);
1513 return NT_STATUS_OK;
1514 }
1515
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);
1522 }
1523 return NT_STATUS_OK;
1524}
1525
1526static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1527 const struct dom_sid *sid,
1528 TALLOC_CTX *mem_ctx, char **pdn)
1529{
1530 struct tldap_message **msg;
1531 char *sidstr, *dn;
1532 int rc;
1533
1534 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1535 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1536
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);
1545 }
1546
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;
1554 }
1555
1556 if (!tldap_entry_dn(msg[0], &dn)) {
1557 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1558 }
1559
1560 dn = talloc_strdup(mem_ctx, dn);
1561 if (dn == NULL) {
1562 return NT_STATUS_NO_MEMORY;
1563 }
1564 TALLOC_FREE(msg);
1565
1566 *pdn = dn;
1567 return NT_STATUS_OK;
1568}
1569
1570static 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)
1574{
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;
1584
1585 ld = pdb_ads_ld(state);
1586 if (ld == NULL) {
1587 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1588 }
1589
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;
1596 }
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;
1603 }
1604
1605 mods = NULL;
1606 num_mods = 0;
1607
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;
1612 }
1613
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;
1621 }
1622 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1623 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1624 }
1625 return NT_STATUS_LDAP(rc);
1626 }
1627
1628 return NT_STATUS_OK;
1629}
1630
1631static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1632 const struct dom_sid *alias,
1633 const struct dom_sid *member)
1634{
1635 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1636}
1637
1638static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1639 const struct dom_sid *alias,
1640 const struct dom_sid *member)
1641{
1642 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1643}
1644
1645static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
1646 struct dom_sid *psid)
1647{
1648 const char *attrs[1] = { "objectSid" };
1649 struct tldap_message **msg;
1650 char *dn;
1651 size_t len;
1652 int rc;
1653 bool ret;
1654
1655 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1656 dnblob->data, dnblob->length, &dn, &len,
1657 false)) {
1658 return false;
1659 }
1660 rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
1661 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1662 &msg, "(objectclass=*)");
1663 TALLOC_FREE(dn);
1664 if (talloc_array_length(msg) != 1) {
1665 DEBUG(10, ("Got %d objects, expected one\n",
1666 (int)talloc_array_length(msg)));
1667 TALLOC_FREE(msg);
1668 return false;
1669 }
1670
1671 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1672 TALLOC_FREE(msg);
1673 return ret;
1674}
1675
1676static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1677 const struct dom_sid *alias,
1678 TALLOC_CTX *mem_ctx,
1679 struct dom_sid **pmembers,
1680 size_t *pnum_members)
1681{
1682 struct pdb_ads_state *state = talloc_get_type_abort(
1683 m->private_data, struct pdb_ads_state);
1684 const char *attrs[1] = { "member" };
1685 char *sidstr;
1686 struct tldap_message **msg;
1687 int i, rc, num_members;
1688 DATA_BLOB *blobs;
1689 struct dom_sid *members;
1690
1691 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), alias);
1692 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1693
1694 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1695 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1696 &msg, "(objectsid=%s)", sidstr);
1697 TALLOC_FREE(sidstr);
1698 if (rc != TLDAP_SUCCESS) {
1699 DEBUG(10, ("ldap_search failed %s\n",
1700 tldap_errstr(talloc_tos(), state->ld, rc)));
1701 return NT_STATUS_LDAP(rc);
1702 }
1703 switch talloc_array_length(msg) {
1704 case 0:
1705 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1706 break;
1707 case 1:
1708 break;
1709 default:
1710 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1711 break;
1712 }
1713
1714 if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
1715 *pmembers = NULL;
1716 *pnum_members = 0;
1717 return NT_STATUS_OK;
1718 }
1719
1720 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1721 if (members == NULL) {
1722 return NT_STATUS_NO_MEMORY;
1723 }
1724
1725 for (i=0; i<num_members; i++) {
1726 if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
1727 TALLOC_FREE(members);
1728 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1729 }
1730 }
1731
1732 *pmembers = members;
1733 *pnum_members = num_members;
1734 return NT_STATUS_OK;
1735}
1736
1737static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1738 TALLOC_CTX *mem_ctx,
1739 const struct dom_sid *domain_sid,
1740 const struct dom_sid *members,
1741 size_t num_members,
1742 uint32_t **palias_rids,
1743 size_t *pnum_alias_rids)
1744{
1745 struct pdb_ads_state *state = talloc_get_type_abort(
1746 m->private_data, struct pdb_ads_state);
1747 const char *attrs[1] = { "objectSid" };
1748 struct tldap_message **msg = NULL;
1749 uint32_t *alias_rids = NULL;
1750 size_t num_alias_rids = 0;
1751 int i, rc, count;
1752 bool got_members = false;
1753 char *filter;
1754 NTSTATUS status;
1755
1756 /*
1757 * TODO: Get the filter right so that we only get the aliases from
1758 * either the SAM or BUILTIN
1759 */
1760
1761 filter = talloc_asprintf(talloc_tos(),
1762 "(&(|(grouptype=%d)(grouptype=%d))"
1763 "(objectclass=group)(|",
1764 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1765 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1766 if (filter == NULL) {
1767 return NT_STATUS_NO_MEMORY;
1768 }
1769
1770 for (i=0; i<num_members; i++) {
1771 char *dn;
1772
1773 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1774 if (!NT_STATUS_IS_OK(status)) {
1775 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1776 sid_string_dbg(&members[i]),
1777 nt_errstr(status)));
1778 continue;
1779 }
1780 filter = talloc_asprintf_append_buffer(
1781 filter, "(member=%s)", dn);
1782 TALLOC_FREE(dn);
1783 if (filter == NULL) {
1784 return NT_STATUS_NO_MEMORY;
1785 }
1786 got_members = true;
1787 }
1788
1789 if (!got_members) {
1790 goto done;
1791 }
1792
1793 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1794 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1795 &msg, "%s))", filter);
1796 TALLOC_FREE(filter);
1797 if (rc != TLDAP_SUCCESS) {
1798 DEBUG(10, ("tldap_search failed %s\n",
1799 tldap_errstr(talloc_tos(), state->ld, rc)));
1800 return NT_STATUS_LDAP(rc);
1801 }
1802
1803 count = talloc_array_length(msg);
1804 if (count == 0) {
1805 goto done;
1806 }
1807
1808 alias_rids = talloc_array(mem_ctx, uint32_t, count);
1809 if (alias_rids == NULL) {
1810 TALLOC_FREE(msg);
1811 return NT_STATUS_NO_MEMORY;
1812 }
1813
1814 for (i=0; i<count; i++) {
1815 struct dom_sid sid;
1816
1817 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1818 DEBUG(10, ("Could not pull SID for member %d\n", i));
1819 continue;
1820 }
1821 if (sid_peek_check_rid(domain_sid, &sid,
1822 &alias_rids[num_alias_rids])) {
1823 num_alias_rids += 1;
1824 }
1825 }
1826done:
1827 TALLOC_FREE(msg);
1828 *palias_rids = alias_rids;
1829 *pnum_alias_rids = 0;
1830 return NT_STATUS_OK;
1831}
1832
1833static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1834 const struct dom_sid *domain_sid,
1835 int num_rids,
1836 uint32 *rids,
1837 const char **names,
1838 enum lsa_SidType *lsa_attrs)
1839{
1840 struct pdb_ads_state *state = talloc_get_type_abort(
1841 m->private_data, struct pdb_ads_state);
1842 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1843 int i, num_mapped;
1844
1845 if (num_rids == 0) {
1846 return NT_STATUS_NONE_MAPPED;
1847 }
1848
1849 num_mapped = 0;
1850
1851 for (i=0; i<num_rids; i++) {
1852 struct dom_sid sid;
1853 struct tldap_message **msg;
1854 char *sidstr;
1855 uint32_t attr;
1856 int rc;
1857
1858 lsa_attrs[i] = SID_NAME_UNKNOWN;
1859
1860 sid_compose(&sid, domain_sid, rids[i]);
1861
1862 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
1863 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1864
1865 rc = pdb_ads_search_fmt(state, state->domaindn,
1866 TLDAP_SCOPE_SUB, attrs,
1867 ARRAY_SIZE(attrs), 0, talloc_tos(),
1868 &msg, "(objectsid=%s)", sidstr);
1869 TALLOC_FREE(sidstr);
1870 if (rc != TLDAP_SUCCESS) {
1871 DEBUG(10, ("ldap_search failed %s\n",
1872 tldap_errstr(talloc_tos(), state->ld, rc)));
1873 continue;
1874 }
1875
1876 switch talloc_array_length(msg) {
1877 case 0:
1878 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1879 continue;
1880 case 1:
1881 break;
1882 default:
1883 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1884 }
1885
1886 names[i] = tldap_talloc_single_attribute(
1887 msg[0], "samAccountName", talloc_tos());
1888 if (names[i] == NULL) {
1889 DEBUG(10, ("no samAccountName\n"));
1890 continue;
1891 }
1892 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1893 DEBUG(10, ("no samAccountType"));
1894 continue;
1895 }
1896 lsa_attrs[i] = ds_atype_map(attr);
1897 num_mapped += 1;
1898 }
1899
1900 if (num_mapped == 0) {
1901 return NT_STATUS_NONE_MAPPED;
1902 }
1903 if (num_mapped < num_rids) {
1904 return STATUS_SOME_UNMAPPED;
1905 }
1906 return NT_STATUS_OK;
1907}
1908
1909static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1910 const struct dom_sid *domain_sid,
1911 int num_names,
1912 const char **pp_names,
1913 uint32 *rids,
1914 enum lsa_SidType *attrs)
1915{
1916 return NT_STATUS_NOT_IMPLEMENTED;
1917}
1918
1919static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1920 enum pdb_policy_type type,
1921 uint32_t *value)
1922{
1923 return account_policy_get(type, value)
1924 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1925}
1926
1927static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1928 enum pdb_policy_type type,
1929 uint32_t value)
1930{
1931 return account_policy_set(type, value)
1932 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1933}
1934
1935static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1936 time_t *seq_num)
1937{
1938 return NT_STATUS_NOT_IMPLEMENTED;
1939}
1940
1941struct pdb_ads_search_state {
1942 uint32_t acct_flags;
1943 struct samr_displayentry *entries;
1944 uint32_t num_entries;
1945 ssize_t array_size;
1946 uint32_t current;
1947};
1948
1949static bool pdb_ads_next_entry(struct pdb_search *search,
1950 struct samr_displayentry *entry)
1951{
1952 struct pdb_ads_search_state *state = talloc_get_type_abort(
1953 search->private_data, struct pdb_ads_search_state);
1954
1955 if (state->current == state->num_entries) {
1956 return false;
1957 }
1958
1959 entry->idx = state->entries[state->current].idx;
1960 entry->rid = state->entries[state->current].rid;
1961 entry->acct_flags = state->entries[state->current].acct_flags;
1962
1963 entry->account_name = talloc_strdup(
1964 search, state->entries[state->current].account_name);
1965 entry->fullname = talloc_strdup(
1966 search, state->entries[state->current].fullname);
1967 entry->description = talloc_strdup(
1968 search, state->entries[state->current].description);
1969
1970 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1971 || (entry->description == NULL)) {
1972 DEBUG(0, ("talloc_strdup failed\n"));
1973 return false;
1974 }
1975
1976 state->current += 1;
1977 return true;
1978}
1979
1980static void pdb_ads_search_end(struct pdb_search *search)
1981{
1982 struct pdb_ads_search_state *state = talloc_get_type_abort(
1983 search->private_data, struct pdb_ads_search_state);
1984 TALLOC_FREE(state);
1985}
1986
1987static bool pdb_ads_search_filter(struct pdb_methods *m,
1988 struct pdb_search *search,
1989 const char *filter,
1990 uint32_t acct_flags,
1991 struct pdb_ads_search_state **pstate)
1992{
1993 struct pdb_ads_state *state = talloc_get_type_abort(
1994 m->private_data, struct pdb_ads_state);
1995 struct pdb_ads_search_state *sstate;
1996 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1997 "userAccountControl", "description" };
1998 struct tldap_message **users;
1999 int i, rc, num_users;
2000
2001 sstate = talloc_zero(search, struct pdb_ads_search_state);
2002 if (sstate == NULL) {
2003 return false;
2004 }
2005 sstate->acct_flags = acct_flags;
2006
2007 rc = pdb_ads_search_fmt(
2008 state, state->domaindn, TLDAP_SCOPE_SUB,
2009 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
2010 "%s", filter);
2011 if (rc != TLDAP_SUCCESS) {
2012 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
2013 tldap_errstr(talloc_tos(), state->ld, rc)));
2014 return false;
2015 }
2016
2017 num_users = talloc_array_length(users);
2018
2019 sstate->entries = talloc_array(sstate, struct samr_displayentry,
2020 num_users);
2021 if (sstate->entries == NULL) {
2022 DEBUG(10, ("talloc failed\n"));
2023 return false;
2024 }
2025
2026 sstate->num_entries = 0;
2027
2028 for (i=0; i<num_users; i++) {
2029 struct samr_displayentry *e;
2030 struct dom_sid sid;
2031 uint32_t ctrl;
2032
2033 e = &sstate->entries[sstate->num_entries];
2034
2035 e->idx = sstate->num_entries;
2036 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
2037 DEBUG(10, ("Could not pull sid\n"));
2038 continue;
2039 }
2040 sid_peek_rid(&sid, &e->rid);
2041
2042 if (tldap_pull_uint32(users[i], "userAccountControl", &ctrl)) {
2043
2044 e->acct_flags = ds_uf2acb(ctrl);
2045
2046 DEBUG(10, ("pdb_ads_search_filter: Found %x, "
2047 "filter %x\n", (int)e->acct_flags,
2048 (int)sstate->acct_flags));
2049
2050
2051 if ((sstate->acct_flags != 0) &&
2052 ((sstate->acct_flags & e->acct_flags) == 0)) {
2053 continue;
2054 }
2055
2056 if (e->acct_flags & (ACB_WSTRUST|ACB_SVRTRUST)) {
2057 e->acct_flags |= ACB_NORMAL;
2058 }
2059 } else {
2060 e->acct_flags = ACB_NORMAL;
2061 }
2062
2063 if (e->rid == DOMAIN_RID_GUEST) {
2064 /*
2065 * Guest is specially crafted in s3. Make
2066 * QueryDisplayInfo match QueryUserInfo
2067 */
2068 e->account_name = lp_guestaccount();
2069 e->fullname = lp_guestaccount();
2070 e->description = "";
2071 e->acct_flags = ACB_NORMAL;
2072 } else {
2073 e->account_name = tldap_talloc_single_attribute(
2074 users[i], "samAccountName", sstate->entries);
2075 e->fullname = tldap_talloc_single_attribute(
2076 users[i], "displayName", sstate->entries);
2077 e->description = tldap_talloc_single_attribute(
2078 users[i], "description", sstate->entries);
2079 }
2080 if (e->account_name == NULL) {
2081 return false;
2082 }
2083 if (e->fullname == NULL) {
2084 e->fullname = "";
2085 }
2086 if (e->description == NULL) {
2087 e->description = "";
2088 }
2089
2090 sstate->num_entries += 1;
2091 if (sstate->num_entries >= num_users) {
2092 break;
2093 }
2094 }
2095
2096 search->private_data = sstate;
2097 search->next_entry = pdb_ads_next_entry;
2098 search->search_end = pdb_ads_search_end;
2099 *pstate = sstate;
2100 return true;
2101}
2102
2103static bool pdb_ads_search_users(struct pdb_methods *m,
2104 struct pdb_search *search,
2105 uint32 acct_flags)
2106{
2107 struct pdb_ads_search_state *sstate;
2108 char *filter;
2109 bool ret;
2110
2111 DEBUG(10, ("pdb_ads_search_users got flags %x\n", acct_flags));
2112
2113 if (acct_flags & ACB_NORMAL) {
2114 filter = talloc_asprintf(
2115 talloc_tos(),
2116 "(&(objectclass=user)(sAMAccountType=%d))",
2117 ATYPE_NORMAL_ACCOUNT);
2118 } else if (acct_flags & ACB_WSTRUST) {
2119 filter = talloc_asprintf(
2120 talloc_tos(),
2121 "(&(objectclass=user)(sAMAccountType=%d))",
2122 ATYPE_WORKSTATION_TRUST);
2123 } else {
2124 filter = talloc_strdup(talloc_tos(), "(objectclass=user)");
2125 }
2126 if (filter == NULL) {
2127 return false;
2128 }
2129
2130 ret = pdb_ads_search_filter(m, search, filter, acct_flags, &sstate);
2131 TALLOC_FREE(filter);
2132 if (!ret) {
2133 return false;
2134 }
2135 return true;
2136}
2137
2138static bool pdb_ads_search_groups(struct pdb_methods *m,
2139 struct pdb_search *search)
2140{
2141 struct pdb_ads_search_state *sstate;
2142 char *filter;
2143 bool ret;
2144
2145 filter = talloc_asprintf(talloc_tos(),
2146 "(&(grouptype=%d)(objectclass=group))",
2147 GTYPE_SECURITY_GLOBAL_GROUP);
2148 if (filter == NULL) {
2149 return false;
2150 }
2151 ret = pdb_ads_search_filter(m, search, filter, 0, &sstate);
2152 TALLOC_FREE(filter);
2153 if (!ret) {
2154 return false;
2155 }
2156 return true;
2157}
2158
2159static bool pdb_ads_search_aliases(struct pdb_methods *m,
2160 struct pdb_search *search,
2161 const struct dom_sid *sid)
2162{
2163 struct pdb_ads_search_state *sstate;
2164 char *filter;
2165 bool ret;
2166
2167 filter = talloc_asprintf(
2168 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
2169 sid_check_is_builtin(sid)
2170 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2171 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
2172
2173 if (filter == NULL) {
2174 return false;
2175 }
2176 ret = pdb_ads_search_filter(m, search, filter, 0, &sstate);
2177 TALLOC_FREE(filter);
2178 if (!ret) {
2179 return false;
2180 }
2181 return true;
2182}
2183
2184static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
2185 struct dom_sid *sid)
2186{
2187 struct pdb_ads_state *state = talloc_get_type_abort(
2188 m->private_data, struct pdb_ads_state);
2189 sid_compose(sid, &state->domainsid, uid);
2190 return true;
2191}
2192
2193static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
2194 struct dom_sid *sid)
2195{
2196 struct pdb_ads_state *state = talloc_get_type_abort(
2197 m->private_data, struct pdb_ads_state);
2198 sid_compose(sid, &state->domainsid, gid);
2199 return true;
2200}
2201
2202static bool pdb_ads_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2203 union unid_t *id, enum lsa_SidType *type)
2204{
2205 struct pdb_ads_state *state = talloc_get_type_abort(
2206 m->private_data, struct pdb_ads_state);
2207 const char *attrs[4] = { "objectClass", "samAccountType",
2208 "uidNumber", "gidNumber" };
2209 struct tldap_message **msg;
2210 char *sidstr, *base;
2211 uint32_t atype;
2212 int rc;
2213 bool ret = false;
2214
2215 sidstr = sid_binstring_hex(sid);
2216 if (sidstr == NULL) {
2217 return false;
2218 }
2219 base = talloc_asprintf(talloc_tos(), "<SID=%s>", sidstr);
2220 SAFE_FREE(sidstr);
2221
2222 rc = pdb_ads_search_fmt(
2223 state, base, TLDAP_SCOPE_BASE,
2224 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
2225 "(objectclass=*)");
2226 TALLOC_FREE(base);
2227
2228 if (rc != TLDAP_SUCCESS) {
2229 DEBUG(10, ("pdb_ads_search_fmt failed: %s\n",
2230 tldap_errstr(talloc_tos(), state->ld, rc)));
2231 return false;
2232 }
2233 if (talloc_array_length(msg) != 1) {
2234 DEBUG(10, ("Got %d objects, expected 1\n",
2235 (int)talloc_array_length(msg)));
2236 goto fail;
2237 }
2238 if (!tldap_pull_uint32(msg[0], "samAccountType", &atype)) {
2239 DEBUG(10, ("samAccountType not found\n"));
2240 goto fail;
2241 }
2242 if (atype == ATYPE_ACCOUNT) {
2243 uint32_t uid;
2244 *type = SID_NAME_USER;
2245 if (!tldap_pull_uint32(msg[0], "uidNumber", &uid)) {
2246 DEBUG(10, ("Did not find uidNumber\n"));
2247 goto fail;
2248 }
2249 id->uid = uid;
2250 } else {
2251 uint32_t gid;
2252 *type = SID_NAME_DOM_GRP;
2253 if (!tldap_pull_uint32(msg[0], "gidNumber", &gid)) {
2254 DEBUG(10, ("Did not find gidNumber\n"));
2255 goto fail;
2256 }
2257 id->gid = gid;
2258 }
2259 ret = true;
2260fail:
2261 TALLOC_FREE(msg);
2262 return ret;
2263}
2264
2265static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
2266{
2267 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2268}
2269
2270static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
2271{
2272 return false;
2273}
2274
2275static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
2276 const char *domain, char** pwd,
2277 struct dom_sid *sid,
2278 time_t *pass_last_set_time)
2279{
2280 return false;
2281}
2282
2283static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
2284 const char* domain, const char* pwd,
2285 const struct dom_sid *sid)
2286{
2287 return false;
2288}
2289
2290static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
2291 const char *domain)
2292{
2293 return false;
2294}
2295
2296static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
2297 TALLOC_CTX *mem_ctx,
2298 uint32 *num_domains,
2299 struct trustdom_info ***domains)
2300{
2301 *num_domains = 0;
2302 *domains = NULL;
2303 return NT_STATUS_OK;
2304}
2305
2306static void pdb_ads_init_methods(struct pdb_methods *m)
2307{
2308 m->name = "ads";
2309 m->get_domain_info = pdb_ads_get_domain_info;
2310 m->getsampwnam = pdb_ads_getsampwnam;
2311 m->getsampwsid = pdb_ads_getsampwsid;
2312 m->create_user = pdb_ads_create_user;
2313 m->delete_user = pdb_ads_delete_user;
2314 m->add_sam_account = pdb_ads_add_sam_account;
2315 m->update_sam_account = pdb_ads_update_sam_account;
2316 m->delete_sam_account = pdb_ads_delete_sam_account;
2317 m->rename_sam_account = pdb_ads_rename_sam_account;
2318 m->update_login_attempts = pdb_ads_update_login_attempts;
2319 m->getgrsid = pdb_ads_getgrsid;
2320 m->getgrgid = pdb_ads_getgrgid;
2321 m->getgrnam = pdb_ads_getgrnam;
2322 m->create_dom_group = pdb_ads_create_dom_group;
2323 m->delete_dom_group = pdb_ads_delete_dom_group;
2324 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
2325 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
2326 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
2327 m->enum_group_mapping = pdb_ads_enum_group_mapping;
2328 m->enum_group_members = pdb_ads_enum_group_members;
2329 m->enum_group_memberships = pdb_ads_enum_group_memberships;
2330 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
2331 m->add_groupmem = pdb_ads_add_groupmem;
2332 m->del_groupmem = pdb_ads_del_groupmem;
2333 m->create_alias = pdb_ads_create_alias;
2334 m->delete_alias = pdb_ads_delete_alias;
2335 m->get_aliasinfo = pdb_default_get_aliasinfo;
2336 m->set_aliasinfo = pdb_ads_set_aliasinfo;
2337 m->add_aliasmem = pdb_ads_add_aliasmem;
2338 m->del_aliasmem = pdb_ads_del_aliasmem;
2339 m->enum_aliasmem = pdb_ads_enum_aliasmem;
2340 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
2341 m->lookup_rids = pdb_ads_lookup_rids;
2342 m->lookup_names = pdb_ads_lookup_names;
2343 m->get_account_policy = pdb_ads_get_account_policy;
2344 m->set_account_policy = pdb_ads_set_account_policy;
2345 m->get_seq_num = pdb_ads_get_seq_num;
2346 m->search_users = pdb_ads_search_users;
2347 m->search_groups = pdb_ads_search_groups;
2348 m->search_aliases = pdb_ads_search_aliases;
2349 m->uid_to_sid = pdb_ads_uid_to_sid;
2350 m->gid_to_sid = pdb_ads_gid_to_sid;
2351 m->sid_to_id = pdb_ads_sid_to_id;
2352 m->capabilities = pdb_ads_capabilities;
2353 m->new_rid = pdb_ads_new_rid;
2354 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2355 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2356 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2357 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2358}
2359
2360static void free_private_data(void **vp)
2361{
2362 struct pdb_ads_state *state = talloc_get_type_abort(
2363 *vp, struct pdb_ads_state);
2364
2365 TALLOC_FREE(state->ld);
2366 return;
2367}
2368
2369/*
2370 this is used to catch debug messages from events
2371*/
2372static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2373 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
2374
2375static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2376 const char *fmt, va_list ap)
2377{
2378 int samba_level = -1;
2379 char *s = NULL;
2380 switch (level) {
2381 case TLDAP_DEBUG_FATAL:
2382 samba_level = 0;
2383 break;
2384 case TLDAP_DEBUG_ERROR:
2385 samba_level = 1;
2386 break;
2387 case TLDAP_DEBUG_WARNING:
2388 samba_level = 2;
2389 break;
2390 case TLDAP_DEBUG_TRACE:
2391 samba_level = 11;
2392 break;
2393
2394 };
2395 if (vasprintf(&s, fmt, ap) == -1) {
2396 return;
2397 }
2398 DEBUG(samba_level, ("tldap: %s", s));
2399 free(s);
2400}
2401
2402static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2403{
2404 NTSTATUS status;
2405 int fd;
2406
2407 if (tldap_connection_ok(state->ld)) {
2408 return state->ld;
2409 }
2410 TALLOC_FREE(state->ld);
2411
2412 status = open_socket_out(
2413 (struct sockaddr_storage *)(void *)&state->socket_address,
2414 0, 0, &fd);
2415 if (!NT_STATUS_IS_OK(status)) {
2416 DEBUG(10, ("Could not connect to %s: %s\n",
2417 state->socket_address.sun_path, nt_errstr(status)));
2418 return NULL;
2419 }
2420
2421 set_blocking(fd, false);
2422
2423 state->ld = tldap_context_create(state, fd);
2424 if (state->ld == NULL) {
2425 close(fd);
2426 return NULL;
2427 }
2428 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2429
2430 return state->ld;
2431}
2432
2433int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2434 int scope, const char *attrs[], int num_attrs,
2435 int attrsonly,
2436 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2437 const char *fmt, ...)
2438{
2439 struct tldap_context *ld;
2440 va_list ap;
2441 int ret;
2442
2443 ld = pdb_ads_ld(state);
2444 if (ld == NULL) {
2445 return TLDAP_SERVER_DOWN;
2446 }
2447
2448 va_start(ap, fmt);
2449 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2450 mem_ctx, res, fmt, ap);
2451 va_end(ap);
2452
2453 if (ret != TLDAP_SERVER_DOWN) {
2454 return ret;
2455 }
2456
2457 /* retry once */
2458 ld = pdb_ads_ld(state);
2459 if (ld == NULL) {
2460 return TLDAP_SERVER_DOWN;
2461 }
2462
2463 va_start(ap, fmt);
2464 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2465 mem_ctx, res, fmt, ap);
2466 va_end(ap);
2467 return ret;
2468}
2469
2470static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2471 const char *location)
2472{
2473 const char *domain_attrs[2] = { "objectSid", "objectGUID" };
2474 const char *ncname_attrs[1] = { "netbiosname" };
2475 struct tldap_context *ld;
2476 struct tldap_message *rootdse, **domain, **ncname;
2477 TALLOC_CTX *frame = talloc_stackframe();
2478 NTSTATUS status;
2479 int num_domains;
2480 int rc;
2481
2482 ZERO_STRUCT(state->socket_address);
2483 state->socket_address.sun_family = AF_UNIX;
2484 strlcpy(state->socket_address.sun_path, location,
2485 sizeof(state->socket_address.sun_path));
2486
2487 ld = pdb_ads_ld(state);
2488 if (ld == NULL) {
2489 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2490 goto done;
2491 }
2492
2493 rc = tldap_fetch_rootdse(ld);
2494 if (rc != TLDAP_SUCCESS) {
2495 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2496 tldap_errstr(talloc_tos(), state->ld, rc)));
2497 status = NT_STATUS_LDAP(rc);
2498 goto done;
2499 }
2500 rootdse = tldap_rootdse(state->ld);
2501
2502 state->domaindn = tldap_talloc_single_attribute(
2503 rootdse, "defaultNamingContext", state);
2504 if (state->domaindn == NULL) {
2505 DEBUG(10, ("Could not get defaultNamingContext\n"));
2506 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2507 goto done;
2508 }
2509 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2510
2511 state->configdn = tldap_talloc_single_attribute(
2512 rootdse, "configurationNamingContext", state);
2513 if (state->configdn == NULL) {
2514 DEBUG(10, ("Could not get configurationNamingContext\n"));
2515 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2516 goto done;
2517 }
2518 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2519
2520 /*
2521 * Figure out our domain's SID
2522 */
2523 rc = pdb_ads_search_fmt(
2524 state, state->domaindn, TLDAP_SCOPE_BASE,
2525 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2526 talloc_tos(), &domain, "(objectclass=*)");
2527 if (rc != TLDAP_SUCCESS) {
2528 DEBUG(10, ("Could not retrieve domain: %s\n",
2529 tldap_errstr(talloc_tos(), state->ld, rc)));
2530 status = NT_STATUS_LDAP(rc);
2531 goto done;
2532 }
2533
2534 num_domains = talloc_array_length(domain);
2535 if (num_domains != 1) {
2536 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2537 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2538 goto done;
2539 }
2540 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2541 DEBUG(10, ("Could not retrieve domain SID\n"));
2542 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2543 goto done;
2544 }
2545 if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) {
2546 DEBUG(10, ("Could not retrieve domain GUID\n"));
2547 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2548 goto done;
2549 }
2550 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2551
2552 /*
2553 * Figure out our domain's short name
2554 */
2555 rc = pdb_ads_search_fmt(
2556 state, state->configdn, TLDAP_SCOPE_SUB,
2557 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2558 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2559 if (rc != TLDAP_SUCCESS) {
2560 DEBUG(10, ("Could not retrieve ncname: %s\n",
2561 tldap_errstr(talloc_tos(), state->ld, rc)));
2562 status = NT_STATUS_LDAP(rc);
2563 goto done;
2564 }
2565 if (talloc_array_length(ncname) != 1) {
2566 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2567 goto done;
2568 }
2569
2570 state->netbiosname = tldap_talloc_single_attribute(
2571 ncname[0], "netbiosname", state);
2572 if (state->netbiosname == NULL) {
2573 DEBUG(10, ("Could not get netbiosname\n"));
2574 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2575 goto done;
2576 }
2577 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2578
2579 if (!strequal(lp_workgroup(), state->netbiosname)) {
2580 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2581 state->netbiosname, lp_workgroup()));
2582 status = NT_STATUS_NO_SUCH_DOMAIN;
2583 goto done;
2584 }
2585
2586 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2587
2588 status = NT_STATUS_OK;
2589done:
2590 TALLOC_FREE(frame);
2591 return status;
2592}
2593
2594static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2595 const char *location)
2596{
2597 struct pdb_methods *m;
2598 struct pdb_ads_state *state;
2599 char *tmp = NULL;
2600 NTSTATUS status;
2601
2602 m = talloc(NULL, struct pdb_methods);
2603 if (m == NULL) {
2604 return NT_STATUS_NO_MEMORY;
2605 }
2606 state = talloc_zero(m, struct pdb_ads_state);
2607 if (state == NULL) {
2608 goto nomem;
2609 }
2610 m->private_data = state;
2611 m->free_private_data = free_private_data;
2612 pdb_ads_init_methods(m);
2613
2614 if (location == NULL) {
2615 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2616 lp_private_dir());
2617 location = tmp;
2618 }
2619 if (location == NULL) {
2620 goto nomem;
2621 }
2622
2623 status = pdb_ads_connect(state, location);
2624 if (!NT_STATUS_IS_OK(status)) {
2625 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2626 goto fail;
2627 }
2628
2629 *pdb_method = m;
2630 return NT_STATUS_OK;
2631nomem:
2632 status = NT_STATUS_NO_MEMORY;
2633fail:
2634 TALLOC_FREE(m);
2635 return status;
2636}
2637
2638NTSTATUS pdb_ads_init(void);
2639NTSTATUS pdb_ads_init(void)
2640{
2641 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
2642 pdb_init_ads);
2643}
Note: See TracBrowser for help on using the repository browser.