source: branches/samba-3.5.x/source3/passdb/pdb_ads.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

File size: 59.7 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
22struct pdb_ads_state {
23 struct sockaddr_un socket_address;
24 struct tldap_context *ld;
25 struct dom_sid domainsid;
26 struct GUID domainguid;
27 char *domaindn;
28 char *configdn;
29 char *netbiosname;
30};
31
32struct pdb_ads_samu_private {
33 char *dn;
34 struct tldap_message *ldapmsg;
35};
36
37static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
38 struct samu *sam_acct,
39 const DOM_SID *sid);
40static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
41 DOM_SID *sid);
42static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
43 struct dom_sid *psid);
44static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
45 const struct dom_sid *sid,
46 TALLOC_CTX *mem_ctx, char **pdn);
47static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state);
48static int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
49 int scope, const char *attrs[], int num_attrs,
50 int attrsonly,
51 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
52 const char *fmt, ...);
53static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
54 const char *filter,
55 TALLOC_CTX *mem_ctx,
56 struct pdb_ads_samu_private **presult);
57
58static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
59 time_t *ptime)
60{
61 uint64_t tmp;
62
63 if (!tldap_pull_uint64(msg, attr, &tmp)) {
64 return false;
65 }
66 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
67 return true;
68}
69
70static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
71{
72 uint32_t rid;
73 sid_peek_rid(sid, &rid);
74 return rid;
75}
76
77static char *pdb_ads_domaindn2dns(TALLOC_CTX *mem_ctx, char *dn)
78{
79 char *result, *p;
80
81 result = talloc_string_sub2(mem_ctx, dn, "DC=", "", false, false,
82 true);
83 if (result == NULL) {
84 return NULL;
85 }
86
87 while ((p = strchr_m(result, ',')) != NULL) {
88 *p = '.';
89 }
90
91 return result;
92}
93
94static struct pdb_domain_info *pdb_ads_get_domain_info(
95 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
96{
97 struct pdb_ads_state *state = talloc_get_type_abort(
98 m->private_data, struct pdb_ads_state);
99 struct pdb_domain_info *info;
100 struct tldap_message *rootdse;
101 char *tmp;
102
103 info = talloc(mem_ctx, struct pdb_domain_info);
104 if (info == NULL) {
105 return NULL;
106 }
107 info->name = talloc_strdup(info, state->netbiosname);
108 if (info->name == NULL) {
109 goto fail;
110 }
111 info->dns_domain = pdb_ads_domaindn2dns(info, state->domaindn);
112 if (info->dns_domain == NULL) {
113 goto fail;
114 }
115
116 rootdse = tldap_rootdse(state->ld);
117 tmp = tldap_talloc_single_attribute(rootdse, "rootDomainNamingContext",
118 talloc_tos());
119 if (tmp == NULL) {
120 goto fail;
121 }
122 info->dns_forest = pdb_ads_domaindn2dns(info, tmp);
123 TALLOC_FREE(tmp);
124 if (info->dns_forest == NULL) {
125 goto fail;
126 }
127 info->sid = state->domainsid;
128 info->guid = state->domainguid;
129 return info;
130
131fail:
132 TALLOC_FREE(info);
133 return NULL;
134}
135
136static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
137 struct pdb_methods *m, struct samu *sam)
138{
139 struct pdb_ads_state *state = talloc_get_type_abort(
140 m->private_data, struct pdb_ads_state);
141 struct pdb_ads_samu_private *result;
142 char *sidstr, *filter;
143 NTSTATUS status;
144
145 result = (struct pdb_ads_samu_private *)
146 pdb_get_backend_private_data(sam, m);
147
148 if (result != NULL) {
149 return talloc_get_type_abort(
150 result, struct pdb_ads_samu_private);
151 }
152
153 sidstr = sid_binstring(talloc_tos(), pdb_get_user_sid(sam));
154 if (sidstr == NULL) {
155 return NULL;
156 }
157
158 filter = talloc_asprintf(
159 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
160 TALLOC_FREE(sidstr);
161 if (filter == NULL) {
162 return NULL;
163 }
164
165 status = pdb_ads_getsamupriv(state, filter, sam, &result);
166 TALLOC_FREE(filter);
167 if (!NT_STATUS_IS_OK(status)) {
168 return NULL;
169 }
170
171 return result;
172}
173
174static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m,
175 struct samu *sam,
176 struct pdb_ads_samu_private *priv)
177{
178 struct pdb_ads_state *state = talloc_get_type_abort(
179 m->private_data, struct pdb_ads_state);
180 TALLOC_CTX *frame = talloc_stackframe();
181 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
182 struct tldap_message *entry = priv->ldapmsg;
183 char *str;
184 time_t tmp_time;
185 struct dom_sid sid;
186 uint64_t n;
187 DATA_BLOB blob;
188
189 str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
190 if (str == NULL) {
191 DEBUG(10, ("no samAccountName\n"));
192 goto fail;
193 }
194 pdb_set_username(sam, str, PDB_SET);
195
196 if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
197 pdb_set_logon_time(sam, tmp_time, PDB_SET);
198 }
199 if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
200 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
201 }
202 if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
203 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
204 }
205 if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
206 pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
207 }
208
209 str = tldap_talloc_single_attribute(entry, "displayName",
210 talloc_tos());
211 if (str != NULL) {
212 pdb_set_fullname(sam, str, PDB_SET);
213 }
214
215 str = tldap_talloc_single_attribute(entry, "homeDirectory",
216 talloc_tos());
217 if (str != NULL) {
218 pdb_set_homedir(sam, str, PDB_SET);
219 }
220
221 str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
222 if (str != NULL) {
223 pdb_set_dir_drive(sam, str, PDB_SET);
224 }
225
226 str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
227 if (str != NULL) {
228 pdb_set_logon_script(sam, str, PDB_SET);
229 }
230
231 str = tldap_talloc_single_attribute(entry, "profilePath",
232 talloc_tos());
233 if (str != NULL) {
234 pdb_set_profile_path(sam, str, PDB_SET);
235 }
236
237 str = tldap_talloc_single_attribute(entry, "profilePath",
238 talloc_tos());
239 if (str != NULL) {
240 pdb_set_profile_path(sam, str, PDB_SET);
241 }
242
243 if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
244 DEBUG(10, ("Could not pull SID\n"));
245 goto fail;
246 }
247 pdb_set_user_sid(sam, &sid, PDB_SET);
248
249 if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
250 DEBUG(10, ("Could not pull userAccountControl\n"));
251 goto fail;
252 }
253 pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
254
255 if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
256 if (blob.length != NT_HASH_LEN) {
257 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
258 (int)blob.length, NT_HASH_LEN));
259 goto fail;
260 }
261 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
262 }
263
264 if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
265 if (blob.length != LM_HASH_LEN) {
266 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
267 (int)blob.length, LM_HASH_LEN));
268 goto fail;
269 }
270 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
271 }
272
273 if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
274 sid_compose(&sid, &state->domainsid, n);
275 pdb_set_group_sid(sam, &sid, PDB_SET);
276
277 }
278 status = NT_STATUS_OK;
279fail:
280 TALLOC_FREE(frame);
281 return status;
282}
283
284static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
285 struct tldap_message *existing,
286 TALLOC_CTX *mem_ctx,
287 int *pnum_mods, struct tldap_mod **pmods,
288 struct samu *sam)
289{
290 bool ret = true;
291 DATA_BLOB blob;
292
293 /* TODO: All fields :-) */
294
295 ret &= tldap_make_mod_fmt(
296 existing, mem_ctx, pnum_mods, pmods, "displayName",
297 "%s", pdb_get_fullname(sam));
298
299 blob = data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN);
300 if (blob.data != NULL) {
301 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
302 "unicodePwd", 1, &blob);
303 }
304
305 blob = data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN);
306 if (blob.data != NULL) {
307 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
308 "dBCSPwd", 1, &blob);
309 }
310
311 ret &= tldap_make_mod_fmt(
312 existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
313 "%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
314
315 ret &= tldap_make_mod_fmt(
316 existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
317 "%s", pdb_get_homedir(sam));
318
319 ret &= tldap_make_mod_fmt(
320 existing, mem_ctx, pnum_mods, pmods, "homeDrive",
321 "%s", pdb_get_dir_drive(sam));
322
323 ret &= tldap_make_mod_fmt(
324 existing, mem_ctx, pnum_mods, pmods, "scriptPath",
325 "%s", pdb_get_logon_script(sam));
326
327 ret &= tldap_make_mod_fmt(
328 existing, mem_ctx, pnum_mods, pmods, "profilePath",
329 "%s", pdb_get_profile_path(sam));
330
331 return ret;
332}
333
334static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
335 const char *filter,
336 TALLOC_CTX *mem_ctx,
337 struct pdb_ads_samu_private **presult)
338{
339 const char * attrs[] = {
340 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
341 "sAMAccountName", "displayName", "homeDirectory",
342 "homeDrive", "scriptPath", "profilePath", "description",
343 "userWorkstations", "comment", "userParameters", "objectSid",
344 "primaryGroupID", "userAccountControl", "logonHours",
345 "badPwdCount", "logonCount", "countryCode", "codePage",
346 "unicodePwd", "dBCSPwd" };
347 struct tldap_message **users;
348 int rc, count;
349 struct pdb_ads_samu_private *result;
350
351 result = talloc(mem_ctx, struct pdb_ads_samu_private);
352 if (result == NULL) {
353 return NT_STATUS_NO_MEMORY;
354 }
355
356 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
357 attrs, ARRAY_SIZE(attrs), 0, result,
358 &users, "%s", filter);
359 if (rc != TLDAP_SUCCESS) {
360 DEBUG(10, ("ldap_search failed %s\n",
361 tldap_errstr(talloc_tos(), state->ld, rc)));
362 TALLOC_FREE(result);
363 return NT_STATUS_LDAP(rc);
364 }
365
366 count = talloc_array_length(users);
367 if (count != 1) {
368 DEBUG(10, ("Expected 1 user, got %d\n", count));
369 TALLOC_FREE(result);
370 return NT_STATUS_INTERNAL_DB_CORRUPTION;
371 }
372
373 result->ldapmsg = users[0];
374 if (!tldap_entry_dn(result->ldapmsg, &result->dn)) {
375 DEBUG(10, ("Could not extract dn\n"));
376 TALLOC_FREE(result);
377 return NT_STATUS_INTERNAL_DB_CORRUPTION;
378 }
379
380 *presult = result;
381 return NT_STATUS_OK;
382}
383
384static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
385 struct pdb_ads_state *state,
386 struct samu *sam_acct,
387 const char *filter)
388{
389 struct pdb_ads_samu_private *priv;
390 NTSTATUS status;
391
392 status = pdb_ads_getsamupriv(state, filter, sam_acct, &priv);
393 if (!NT_STATUS_IS_OK(status)) {
394 DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n",
395 nt_errstr(status)));
396 return status;
397 }
398
399 status = pdb_ads_init_sam_from_priv(m, sam_acct, priv);
400 if (!NT_STATUS_IS_OK(status)) {
401 DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n",
402 nt_errstr(status)));
403 TALLOC_FREE(priv);
404 return status;
405 }
406
407 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
408 return NT_STATUS_OK;
409}
410
411static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
412 struct samu *sam_acct,
413 const char *username)
414{
415 struct pdb_ads_state *state = talloc_get_type_abort(
416 m->private_data, struct pdb_ads_state);
417 char *filter;
418
419 filter = talloc_asprintf(
420 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
421 username);
422 NT_STATUS_HAVE_NO_MEMORY(filter);
423
424 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
425}
426
427static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
428 struct samu *sam_acct,
429 const DOM_SID *sid)
430{
431 struct pdb_ads_state *state = talloc_get_type_abort(
432 m->private_data, struct pdb_ads_state);
433 char *sidstr, *filter;
434
435 sidstr = sid_binstring(talloc_tos(), sid);
436 NT_STATUS_HAVE_NO_MEMORY(sidstr);
437
438 filter = talloc_asprintf(
439 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
440 TALLOC_FREE(sidstr);
441 NT_STATUS_HAVE_NO_MEMORY(filter);
442
443 return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
444}
445
446static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
447 TALLOC_CTX *tmp_ctx,
448 const char *name, uint32 acct_flags,
449 uint32 *rid)
450{
451 struct pdb_ads_state *state = talloc_get_type_abort(
452 m->private_data, struct pdb_ads_state);
453 struct tldap_context *ld;
454 const char *attrs[1] = { "objectSid" };
455 struct tldap_mod *mods = NULL;
456 int num_mods = 0;
457 struct tldap_message **user;
458 struct dom_sid sid;
459 char *dn;
460 int rc;
461 bool ok;
462
463 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
464 state->domaindn);
465 if (dn == NULL) {
466 return NT_STATUS_NO_MEMORY;
467 }
468
469 ld = pdb_ads_ld(state);
470 if (ld == NULL) {
471 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
472 }
473
474 /* TODO: Create machines etc */
475
476 ok = true;
477 ok &= tldap_make_mod_fmt(
478 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
479 ok &= tldap_make_mod_fmt(
480 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
481 name);
482 if (!ok) {
483 return NT_STATUS_NO_MEMORY;
484 }
485
486
487 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
488 if (rc != TLDAP_SUCCESS) {
489 DEBUG(10, ("ldap_add failed %s\n",
490 tldap_errstr(talloc_tos(), ld, rc)));
491 TALLOC_FREE(dn);
492 return NT_STATUS_LDAP(rc);
493 }
494
495 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
496 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
497 &user,
498 "(&(objectclass=user)(samaccountname=%s))",
499 name);
500 if (rc != TLDAP_SUCCESS) {
501 DEBUG(10, ("Could not find just created user %s: %s\n",
502 name, tldap_errstr(talloc_tos(), state->ld, rc)));
503 TALLOC_FREE(dn);
504 return NT_STATUS_LDAP(rc);
505 }
506
507 if (talloc_array_length(user) != 1) {
508 DEBUG(10, ("Got %d users, expected one\n",
509 (int)talloc_array_length(user)));
510 TALLOC_FREE(dn);
511 return NT_STATUS_LDAP(rc);
512 }
513
514 if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
515 DEBUG(10, ("Could not fetch objectSid from user %s\n",
516 name));
517 TALLOC_FREE(dn);
518 return NT_STATUS_INTERNAL_DB_CORRUPTION;
519 }
520
521 sid_peek_rid(&sid, rid);
522 TALLOC_FREE(dn);
523 return NT_STATUS_OK;
524}
525
526static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
527 TALLOC_CTX *tmp_ctx,
528 struct samu *sam)
529{
530 struct pdb_ads_state *state = talloc_get_type_abort(
531 m->private_data, struct pdb_ads_state);
532 NTSTATUS status;
533 struct tldap_context *ld;
534 char *dn;
535 int rc;
536
537 ld = pdb_ads_ld(state);
538 if (ld == NULL) {
539 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
540 }
541
542 status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
543 &dn);
544 if (!NT_STATUS_IS_OK(status)) {
545 return status;
546 }
547
548 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
549 TALLOC_FREE(dn);
550 if (rc != TLDAP_SUCCESS) {
551 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
552 tldap_errstr(talloc_tos(), ld, rc)));
553 return NT_STATUS_LDAP(rc);
554 }
555 return NT_STATUS_OK;
556}
557
558static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
559 struct samu *sampass)
560{
561 return NT_STATUS_NOT_IMPLEMENTED;
562}
563
564static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
565 struct samu *sam)
566{
567 struct pdb_ads_state *state = talloc_get_type_abort(
568 m->private_data, struct pdb_ads_state);
569 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
570 struct tldap_context *ld;
571 struct tldap_mod *mods = NULL;
572 int rc, num_mods = 0;
573
574 ld = pdb_ads_ld(state);
575 if (ld == NULL) {
576 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
577 }
578
579 if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
580 &num_mods, &mods, sam)) {
581 return NT_STATUS_NO_MEMORY;
582 }
583
584 if (num_mods == 0) {
585 /* Nothing to do, just return success */
586 return NT_STATUS_OK;
587 }
588
589 rc = tldap_modify(ld, priv->dn, num_mods, mods, NULL, 0,
590 NULL, 0);
591 TALLOC_FREE(mods);
592 if (rc != TLDAP_SUCCESS) {
593 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
594 tldap_errstr(talloc_tos(), ld, rc)));
595 return NT_STATUS_LDAP(rc);
596 }
597
598 return NT_STATUS_OK;
599}
600
601static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
602 struct samu *username)
603{
604 return NT_STATUS_NOT_IMPLEMENTED;
605}
606
607static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
608 struct samu *oldname,
609 const char *newname)
610{
611 return NT_STATUS_NOT_IMPLEMENTED;
612}
613
614static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
615 struct samu *sam_acct,
616 bool success)
617{
618 return NT_STATUS_NOT_IMPLEMENTED;
619}
620
621static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
622 const char *filter)
623{
624 struct pdb_ads_state *state = talloc_get_type_abort(
625 m->private_data, struct pdb_ads_state);
626 const char *attrs[4] = { "objectSid", "description", "samAccountName",
627 "groupType" };
628 char *str;
629 struct tldap_message **group;
630 uint32_t grouptype;
631 int rc;
632
633 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
634 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
635 &group, "%s", filter);
636 if (rc != TLDAP_SUCCESS) {
637 DEBUG(10, ("ldap_search failed %s\n",
638 tldap_errstr(talloc_tos(), state->ld, rc)));
639 return NT_STATUS_LDAP(rc);
640 }
641 if (talloc_array_length(group) != 1) {
642 DEBUG(10, ("Expected 1 user, got %d\n",
643 (int)talloc_array_length(group)));
644 return NT_STATUS_INTERNAL_DB_CORRUPTION;
645 }
646
647 if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
648 return NT_STATUS_INTERNAL_DB_CORRUPTION;
649 }
650 map->gid = pdb_ads_sid2gid(&map->sid);
651
652 if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
653 return NT_STATUS_INTERNAL_DB_CORRUPTION;
654 }
655 switch (grouptype) {
656 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
657 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
658 map->sid_name_use = SID_NAME_ALIAS;
659 break;
660 case GTYPE_SECURITY_GLOBAL_GROUP:
661 map->sid_name_use = SID_NAME_DOM_GRP;
662 break;
663 default:
664 return NT_STATUS_INTERNAL_DB_CORRUPTION;
665 }
666
667 str = tldap_talloc_single_attribute(group[0], "samAccountName",
668 talloc_tos());
669 if (str == NULL) {
670 return NT_STATUS_INTERNAL_DB_CORRUPTION;
671 }
672 fstrcpy(map->nt_name, str);
673 TALLOC_FREE(str);
674
675 str = tldap_talloc_single_attribute(group[0], "description",
676 talloc_tos());
677 if (str != NULL) {
678 fstrcpy(map->comment, str);
679 TALLOC_FREE(str);
680 } else {
681 map->comment[0] = '\0';
682 }
683
684 TALLOC_FREE(group);
685 return NT_STATUS_OK;
686}
687
688static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
689 DOM_SID sid)
690{
691 char *filter;
692 NTSTATUS status;
693
694 filter = talloc_asprintf(talloc_tos(),
695 "(&(objectsid=%s)(objectclass=group))",
696 sid_string_talloc(talloc_tos(), &sid));
697 if (filter == NULL) {
698 return NT_STATUS_NO_MEMORY;
699 }
700
701 status = pdb_ads_getgrfilter(m, map, filter);
702 TALLOC_FREE(filter);
703 return status;
704}
705
706static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
707 gid_t gid)
708{
709 struct dom_sid sid;
710 pdb_ads_gid_to_sid(m, gid, &sid);
711 return pdb_ads_getgrsid(m, map, sid);
712}
713
714static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
715 const char *name)
716{
717 char *filter;
718 NTSTATUS status;
719
720 filter = talloc_asprintf(talloc_tos(),
721 "(&(samaccountname=%s)(objectclass=group))",
722 name);
723 if (filter == NULL) {
724 return NT_STATUS_NO_MEMORY;
725 }
726
727 status = pdb_ads_getgrfilter(m, map, filter);
728 TALLOC_FREE(filter);
729 return status;
730}
731
732static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
733 TALLOC_CTX *mem_ctx, const char *name,
734 uint32 *rid)
735{
736 TALLOC_CTX *frame = talloc_stackframe();
737 struct pdb_ads_state *state = talloc_get_type_abort(
738 m->private_data, struct pdb_ads_state);
739 struct tldap_context *ld;
740 const char *attrs[1] = { "objectSid" };
741 int num_mods = 0;
742 struct tldap_mod *mods = NULL;
743 struct tldap_message **alias;
744 struct dom_sid sid;
745 char *dn;
746 int rc;
747 bool ok = true;
748
749 ld = pdb_ads_ld(state);
750 if (ld == NULL) {
751 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
752 }
753
754 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
755 state->domaindn);
756 if (dn == NULL) {
757 TALLOC_FREE(frame);
758 return NT_STATUS_NO_MEMORY;
759 }
760
761 ok &= tldap_make_mod_fmt(
762 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
763 name);
764 ok &= tldap_make_mod_fmt(
765 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
766 ok &= tldap_make_mod_fmt(
767 NULL, talloc_tos(), &num_mods, &mods, "groupType",
768 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
769
770 if (!ok) {
771 TALLOC_FREE(frame);
772 return NT_STATUS_NO_MEMORY;
773 }
774
775 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
776 if (rc != TLDAP_SUCCESS) {
777 DEBUG(10, ("ldap_add failed %s\n",
778 tldap_errstr(talloc_tos(), state->ld, rc)));
779 TALLOC_FREE(frame);
780 return NT_STATUS_LDAP(rc);
781 }
782
783 rc = pdb_ads_search_fmt(
784 state, state->domaindn, TLDAP_SCOPE_SUB,
785 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
786 "(&(objectclass=group)(samaccountname=%s))", name);
787 if (rc != TLDAP_SUCCESS) {
788 DEBUG(10, ("Could not find just created alias %s: %s\n",
789 name, tldap_errstr(talloc_tos(), state->ld, rc)));
790 TALLOC_FREE(frame);
791 return NT_STATUS_LDAP(rc);
792 }
793
794 if (talloc_array_length(alias) != 1) {
795 DEBUG(10, ("Got %d alias, expected one\n",
796 (int)talloc_array_length(alias)));
797 TALLOC_FREE(frame);
798 return NT_STATUS_LDAP(rc);
799 }
800
801 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
802 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
803 name));
804 TALLOC_FREE(frame);
805 return NT_STATUS_INTERNAL_DB_CORRUPTION;
806 }
807
808 sid_peek_rid(&sid, rid);
809 TALLOC_FREE(frame);
810 return NT_STATUS_OK;
811}
812
813static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
814 TALLOC_CTX *mem_ctx, uint32 rid)
815{
816 struct pdb_ads_state *state = talloc_get_type_abort(
817 m->private_data, struct pdb_ads_state);
818 struct tldap_context *ld;
819 struct dom_sid sid;
820 char *sidstr;
821 struct tldap_message **msg;
822 char *dn;
823 int rc;
824
825 sid_compose(&sid, &state->domainsid, rid);
826
827 sidstr = sid_binstring(talloc_tos(), &sid);
828 NT_STATUS_HAVE_NO_MEMORY(sidstr);
829
830 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
831 NULL, 0, 0, talloc_tos(), &msg,
832 ("(&(objectSid=%s)(objectClass=group))"),
833 sidstr);
834 TALLOC_FREE(sidstr);
835 if (rc != TLDAP_SUCCESS) {
836 DEBUG(10, ("ldap_search failed %s\n",
837 tldap_errstr(talloc_tos(), state->ld, rc)));
838 return NT_STATUS_LDAP(rc);
839 }
840
841 switch talloc_array_length(msg) {
842 case 0:
843 return NT_STATUS_NO_SUCH_GROUP;
844 case 1:
845 break;
846 default:
847 return NT_STATUS_INTERNAL_DB_CORRUPTION;
848 }
849
850 if (!tldap_entry_dn(msg[0], &dn)) {
851 TALLOC_FREE(msg);
852 return NT_STATUS_INTERNAL_DB_CORRUPTION;
853 }
854
855 ld = pdb_ads_ld(state);
856 if (ld == NULL) {
857 TALLOC_FREE(msg);
858 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
859 }
860
861 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
862 TALLOC_FREE(msg);
863 if (rc != TLDAP_SUCCESS) {
864 DEBUG(10, ("ldap_delete failed: %s\n",
865 tldap_errstr(talloc_tos(), state->ld, rc)));
866 return NT_STATUS_LDAP(rc);
867 }
868
869 return NT_STATUS_OK;
870}
871
872static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
873 GROUP_MAP *map)
874{
875 return NT_STATUS_NOT_IMPLEMENTED;
876}
877
878static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
879 GROUP_MAP *map)
880{
881 return NT_STATUS_NOT_IMPLEMENTED;
882}
883
884static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
885 DOM_SID sid)
886{
887 return NT_STATUS_NOT_IMPLEMENTED;
888}
889
890static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
891 const DOM_SID *sid,
892 enum lsa_SidType sid_name_use,
893 GROUP_MAP **pp_rmap,
894 size_t *p_num_entries,
895 bool unix_only)
896{
897 return NT_STATUS_NOT_IMPLEMENTED;
898}
899
900static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
901 TALLOC_CTX *mem_ctx,
902 const DOM_SID *group,
903 uint32 **pmembers,
904 size_t *pnum_members)
905{
906 struct pdb_ads_state *state = talloc_get_type_abort(
907 m->private_data, struct pdb_ads_state);
908 const char *attrs[1] = { "member" };
909 char *sidstr;
910 struct tldap_message **msg;
911 int i, rc, num_members;
912 DATA_BLOB *blobs;
913 uint32_t *members;
914
915 sidstr = sid_binstring(talloc_tos(), group);
916 NT_STATUS_HAVE_NO_MEMORY(sidstr);
917
918 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
919 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
920 &msg, "(objectsid=%s)", sidstr);
921 TALLOC_FREE(sidstr);
922 if (rc != TLDAP_SUCCESS) {
923 DEBUG(10, ("ldap_search failed %s\n",
924 tldap_errstr(talloc_tos(), state->ld, rc)));
925 return NT_STATUS_LDAP(rc);
926 }
927 switch talloc_array_length(msg) {
928 case 0:
929 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
930 break;
931 case 1:
932 break;
933 default:
934 return NT_STATUS_INTERNAL_DB_CORRUPTION;
935 break;
936 }
937
938 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
939 return NT_STATUS_INTERNAL_DB_CORRUPTION;
940 }
941
942 members = talloc_array(mem_ctx, uint32_t, num_members);
943 if (members == NULL) {
944 return NT_STATUS_NO_MEMORY;
945 }
946
947 for (i=0; i<num_members; i++) {
948 struct dom_sid sid;
949 if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
950 || !sid_peek_rid(&sid, &members[i])) {
951 TALLOC_FREE(members);
952 return NT_STATUS_INTERNAL_DB_CORRUPTION;
953 }
954 }
955
956 *pmembers = members;
957 *pnum_members = num_members;
958 return NT_STATUS_OK;
959}
960
961static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
962 TALLOC_CTX *mem_ctx,
963 struct samu *user,
964 DOM_SID **pp_sids,
965 gid_t **pp_gids,
966 size_t *p_num_groups)
967{
968 struct pdb_ads_state *state = talloc_get_type_abort(
969 m->private_data, struct pdb_ads_state);
970 struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
971 m, user);
972 const char *attrs[1] = { "objectSid" };
973 struct tldap_message **groups;
974 int i, rc, count;
975 size_t num_groups;
976 struct dom_sid *group_sids;
977 gid_t *gids;
978
979 rc = pdb_ads_search_fmt(
980 state, state->domaindn, TLDAP_SCOPE_SUB,
981 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
982 "(&(member=%s)(grouptype=%d)(objectclass=group))",
983 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
984 if (rc != TLDAP_SUCCESS) {
985 DEBUG(10, ("ldap_search failed %s\n",
986 tldap_errstr(talloc_tos(), state->ld, rc)));
987 return NT_STATUS_LDAP(rc);
988 }
989
990 count = talloc_array_length(groups);
991
992 group_sids = talloc_array(mem_ctx, struct dom_sid, count);
993 if (group_sids == NULL) {
994 return NT_STATUS_NO_MEMORY;
995 }
996 gids = talloc_array(mem_ctx, gid_t, count);
997 if (gids == NULL) {
998 TALLOC_FREE(group_sids);
999 return NT_STATUS_NO_MEMORY;
1000 }
1001 num_groups = 0;
1002
1003 for (i=0; i<count; i++) {
1004 if (!tldap_pull_binsid(groups[i], "objectSid",
1005 &group_sids[num_groups])) {
1006 continue;
1007 }
1008 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
1009
1010 num_groups += 1;
1011 if (num_groups == count) {
1012 break;
1013 }
1014 }
1015
1016 *pp_sids = group_sids;
1017 *pp_gids = gids;
1018 *p_num_groups = num_groups;
1019 return NT_STATUS_OK;
1020}
1021
1022static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
1023 TALLOC_CTX *mem_ctx,
1024 struct samu *user)
1025{
1026 return NT_STATUS_NOT_IMPLEMENTED;
1027}
1028
1029static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
1030 TALLOC_CTX *mem_ctx,
1031 uint32 grouprid, uint32 memberrid,
1032 int mod_op)
1033{
1034 struct pdb_ads_state *state = talloc_get_type_abort(
1035 m->private_data, struct pdb_ads_state);
1036 TALLOC_CTX *frame = talloc_stackframe();
1037 struct tldap_context *ld;
1038 struct dom_sid groupsid, membersid;
1039 char *groupdn, *memberdn;
1040 struct tldap_mod *mods;
1041 int rc;
1042 NTSTATUS status;
1043
1044 ld = pdb_ads_ld(state);
1045 if (ld == NULL) {
1046 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1047 }
1048
1049 sid_compose(&groupsid, &state->domainsid, grouprid);
1050 sid_compose(&membersid, &state->domainsid, memberrid);
1051
1052 status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
1053 if (!NT_STATUS_IS_OK(status)) {
1054 TALLOC_FREE(frame);
1055 return NT_STATUS_NO_SUCH_GROUP;
1056 }
1057 status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
1058 if (!NT_STATUS_IS_OK(status)) {
1059 TALLOC_FREE(frame);
1060 return NT_STATUS_NO_SUCH_USER;
1061 }
1062
1063 mods = NULL;
1064
1065 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1066 "member", memberdn)) {
1067 TALLOC_FREE(frame);
1068 return NT_STATUS_NO_MEMORY;
1069 }
1070
1071 rc = tldap_modify(ld, groupdn, 1, mods, NULL, 0, NULL, 0);
1072 TALLOC_FREE(frame);
1073 if (rc != TLDAP_SUCCESS) {
1074 DEBUG(10, ("ldap_modify failed: %s\n",
1075 tldap_errstr(talloc_tos(), state->ld, rc)));
1076 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1077 return NT_STATUS_MEMBER_IN_GROUP;
1078 }
1079 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1080 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1081 }
1082 return NT_STATUS_LDAP(rc);
1083 }
1084
1085 return NT_STATUS_OK;
1086}
1087
1088static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
1089 TALLOC_CTX *mem_ctx,
1090 uint32 group_rid, uint32 member_rid)
1091{
1092 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1093 TLDAP_MOD_ADD);
1094}
1095
1096static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
1097 TALLOC_CTX *mem_ctx,
1098 uint32 group_rid, uint32 member_rid)
1099{
1100 return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1101 TLDAP_MOD_DELETE);
1102}
1103
1104static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
1105 const char *name, uint32 *rid)
1106{
1107 TALLOC_CTX *frame = talloc_stackframe();
1108 struct pdb_ads_state *state = talloc_get_type_abort(
1109 m->private_data, struct pdb_ads_state);
1110 struct tldap_context *ld;
1111 const char *attrs[1] = { "objectSid" };
1112 int num_mods = 0;
1113 struct tldap_mod *mods = NULL;
1114 struct tldap_message **alias;
1115 struct dom_sid sid;
1116 char *dn;
1117 int rc;
1118 bool ok = true;
1119
1120 ld = pdb_ads_ld(state);
1121 if (ld == NULL) {
1122 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1123 }
1124
1125 dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1126 state->domaindn);
1127 if (dn == NULL) {
1128 TALLOC_FREE(frame);
1129 return NT_STATUS_NO_MEMORY;
1130 }
1131
1132 ok &= tldap_make_mod_fmt(
1133 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
1134 name);
1135 ok &= tldap_make_mod_fmt(
1136 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
1137 ok &= tldap_make_mod_fmt(
1138 NULL, talloc_tos(), &num_mods, &mods, "groupType",
1139 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1140
1141 if (!ok) {
1142 TALLOC_FREE(frame);
1143 return NT_STATUS_NO_MEMORY;
1144 }
1145
1146 rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1147 if (rc != TLDAP_SUCCESS) {
1148 DEBUG(10, ("ldap_add failed %s\n",
1149 tldap_errstr(talloc_tos(), state->ld, rc)));
1150 TALLOC_FREE(frame);
1151 return NT_STATUS_LDAP(rc);
1152 }
1153
1154 rc = pdb_ads_search_fmt(
1155 state, state->domaindn, TLDAP_SCOPE_SUB,
1156 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1157 "(&(objectclass=group)(samaccountname=%s))", name);
1158 if (rc != TLDAP_SUCCESS) {
1159 DEBUG(10, ("Could not find just created alias %s: %s\n",
1160 name, tldap_errstr(talloc_tos(), state->ld, rc)));
1161 TALLOC_FREE(frame);
1162 return NT_STATUS_LDAP(rc);
1163 }
1164
1165 if (talloc_array_length(alias) != 1) {
1166 DEBUG(10, ("Got %d alias, expected one\n",
1167 (int)talloc_array_length(alias)));
1168 TALLOC_FREE(frame);
1169 return NT_STATUS_LDAP(rc);
1170 }
1171
1172 if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1173 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1174 name));
1175 TALLOC_FREE(frame);
1176 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1177 }
1178
1179 sid_peek_rid(&sid, rid);
1180 TALLOC_FREE(frame);
1181 return NT_STATUS_OK;
1182}
1183
1184static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1185 const DOM_SID *sid)
1186{
1187 struct pdb_ads_state *state = talloc_get_type_abort(
1188 m->private_data, struct pdb_ads_state);
1189 struct tldap_context *ld;
1190 struct tldap_message **alias;
1191 char *sidstr, *dn;
1192 int rc;
1193
1194 ld = pdb_ads_ld(state);
1195 if (ld == NULL) {
1196 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1197 }
1198
1199 sidstr = sid_binstring(talloc_tos(), sid);
1200 if (sidstr == NULL) {
1201 return NT_STATUS_NO_MEMORY;
1202 }
1203
1204 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1205 NULL, 0, 0, talloc_tos(), &alias,
1206 "(&(objectSid=%s)(objectclass=group)"
1207 "(|(grouptype=%d)(grouptype=%d)))",
1208 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1209 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1210 TALLOC_FREE(sidstr);
1211 if (rc != TLDAP_SUCCESS) {
1212 DEBUG(10, ("ldap_search failed: %s\n",
1213 tldap_errstr(talloc_tos(), state->ld, rc)));
1214 TALLOC_FREE(dn);
1215 return NT_STATUS_LDAP(rc);
1216 }
1217 if (talloc_array_length(alias) != 1) {
1218 DEBUG(10, ("Expected 1 alias, got %d\n",
1219 (int)talloc_array_length(alias)));
1220 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1221 }
1222 if (!tldap_entry_dn(alias[0], &dn)) {
1223 DEBUG(10, ("Could not get DN for alias %s\n",
1224 sid_string_dbg(sid)));
1225 return NT_STATUS_INTERNAL_ERROR;
1226 }
1227
1228 rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
1229 if (rc != TLDAP_SUCCESS) {
1230 DEBUG(10, ("ldap_delete failed: %s\n",
1231 tldap_errstr(talloc_tos(), state->ld, rc)));
1232 TALLOC_FREE(dn);
1233 return NT_STATUS_LDAP(rc);
1234 }
1235
1236 return NT_STATUS_OK;
1237}
1238
1239static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1240 const DOM_SID *sid,
1241 struct acct_info *info)
1242{
1243 struct pdb_ads_state *state = talloc_get_type_abort(
1244 m->private_data, struct pdb_ads_state);
1245 struct tldap_context *ld;
1246 const char *attrs[3] = { "objectSid", "description",
1247 "samAccountName" };
1248 struct tldap_message **msg;
1249 char *sidstr, *dn;
1250 int rc;
1251 struct tldap_mod *mods;
1252 int num_mods;
1253 bool ok;
1254
1255 ld = pdb_ads_ld(state);
1256 if (ld == NULL) {
1257 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1258 }
1259
1260 sidstr = sid_binstring(talloc_tos(), sid);
1261 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1262
1263 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1264 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1265 &msg, "(&(objectSid=%s)(objectclass=group)"
1266 "(|(grouptype=%d)(grouptype=%d)))",
1267 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1268 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1269 TALLOC_FREE(sidstr);
1270 if (rc != TLDAP_SUCCESS) {
1271 DEBUG(10, ("ldap_search failed %s\n",
1272 tldap_errstr(talloc_tos(), state->ld, rc)));
1273 return NT_STATUS_LDAP(rc);
1274 }
1275 switch talloc_array_length(msg) {
1276 case 0:
1277 return NT_STATUS_NO_SUCH_ALIAS;
1278 case 1:
1279 break;
1280 default:
1281 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1282 }
1283
1284 if (!tldap_entry_dn(msg[0], &dn)) {
1285 TALLOC_FREE(msg);
1286 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1287 }
1288
1289 mods = NULL;
1290 num_mods = 0;
1291 ok = true;
1292
1293 ok &= tldap_make_mod_fmt(
1294 msg[0], msg, &num_mods, &mods, "description",
1295 "%s", info->acct_desc);
1296 ok &= tldap_make_mod_fmt(
1297 msg[0], msg, &num_mods, &mods, "samAccountName",
1298 "%s", info->acct_name);
1299 if (!ok) {
1300 TALLOC_FREE(msg);
1301 return NT_STATUS_NO_MEMORY;
1302 }
1303 if (num_mods == 0) {
1304 /* no change */
1305 TALLOC_FREE(msg);
1306 return NT_STATUS_OK;
1307 }
1308
1309 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1310 TALLOC_FREE(msg);
1311 if (rc != TLDAP_SUCCESS) {
1312 DEBUG(10, ("ldap_modify failed: %s\n",
1313 tldap_errstr(talloc_tos(), state->ld, rc)));
1314 return NT_STATUS_LDAP(rc);
1315 }
1316 return NT_STATUS_OK;
1317}
1318
1319static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1320 const struct dom_sid *sid,
1321 TALLOC_CTX *mem_ctx, char **pdn)
1322{
1323 struct tldap_message **msg;
1324 char *sidstr, *dn;
1325 int rc;
1326
1327 sidstr = sid_binstring(talloc_tos(), sid);
1328 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1329
1330 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1331 NULL, 0, 0, talloc_tos(), &msg,
1332 "(objectsid=%s)", sidstr);
1333 TALLOC_FREE(sidstr);
1334 if (rc != TLDAP_SUCCESS) {
1335 DEBUG(10, ("ldap_search failed %s\n",
1336 tldap_errstr(talloc_tos(), state->ld, rc)));
1337 return NT_STATUS_LDAP(rc);
1338 }
1339
1340 switch talloc_array_length(msg) {
1341 case 0:
1342 return NT_STATUS_NOT_FOUND;
1343 case 1:
1344 break;
1345 default:
1346 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1347 }
1348
1349 if (!tldap_entry_dn(msg[0], &dn)) {
1350 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1351 }
1352
1353 dn = talloc_strdup(mem_ctx, dn);
1354 if (dn == NULL) {
1355 return NT_STATUS_NO_MEMORY;
1356 }
1357 TALLOC_FREE(msg);
1358
1359 *pdn = dn;
1360 return NT_STATUS_OK;
1361}
1362
1363static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1364 const DOM_SID *alias,
1365 const DOM_SID *member,
1366 int mod_op)
1367{
1368 struct pdb_ads_state *state = talloc_get_type_abort(
1369 m->private_data, struct pdb_ads_state);
1370 struct tldap_context *ld;
1371 TALLOC_CTX *frame = talloc_stackframe();
1372 struct tldap_mod *mods;
1373 int rc;
1374 char *aliasdn, *memberdn;
1375 NTSTATUS status;
1376
1377 ld = pdb_ads_ld(state);
1378 if (ld == NULL) {
1379 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1380 }
1381
1382 status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1383 if (!NT_STATUS_IS_OK(status)) {
1384 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1385 sid_string_dbg(alias), nt_errstr(status)));
1386 TALLOC_FREE(frame);
1387 return NT_STATUS_NO_SUCH_ALIAS;
1388 }
1389 status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1390 if (!NT_STATUS_IS_OK(status)) {
1391 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1392 sid_string_dbg(member), nt_errstr(status)));
1393 TALLOC_FREE(frame);
1394 return status;
1395 }
1396
1397 mods = NULL;
1398
1399 if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1400 "member", memberdn)) {
1401 TALLOC_FREE(frame);
1402 return NT_STATUS_NO_MEMORY;
1403 }
1404
1405 rc = tldap_modify(ld, aliasdn, 1, mods, NULL, 0, NULL, 0);
1406 TALLOC_FREE(frame);
1407 if (rc != TLDAP_SUCCESS) {
1408 DEBUG(10, ("ldap_modify failed: %s\n",
1409 tldap_errstr(talloc_tos(), state->ld, rc)));
1410 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1411 return NT_STATUS_MEMBER_IN_ALIAS;
1412 }
1413 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1414 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1415 }
1416 return NT_STATUS_LDAP(rc);
1417 }
1418
1419 return NT_STATUS_OK;
1420}
1421
1422static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1423 const DOM_SID *alias,
1424 const DOM_SID *member)
1425{
1426 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1427}
1428
1429static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1430 const DOM_SID *alias,
1431 const DOM_SID *member)
1432{
1433 return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1434}
1435
1436static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
1437 struct dom_sid *psid)
1438{
1439 const char *attrs[1] = { "objectSid" };
1440 struct tldap_message **msg;
1441 char *dn;
1442 size_t len;
1443 int rc;
1444 bool ret;
1445
1446 if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1447 dnblob->data, dnblob->length, &dn, &len,
1448 false)) {
1449 return false;
1450 }
1451 rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
1452 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1453 &msg, "(objectclass=*)");
1454 TALLOC_FREE(dn);
1455 if (talloc_array_length(msg) != 1) {
1456 DEBUG(10, ("Got %d objects, expected one\n",
1457 (int)talloc_array_length(msg)));
1458 TALLOC_FREE(msg);
1459 return false;
1460 }
1461
1462 ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1463 TALLOC_FREE(msg);
1464 return ret;
1465}
1466
1467static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1468 const DOM_SID *alias,
1469 TALLOC_CTX *mem_ctx,
1470 DOM_SID **pmembers,
1471 size_t *pnum_members)
1472{
1473 struct pdb_ads_state *state = talloc_get_type_abort(
1474 m->private_data, struct pdb_ads_state);
1475 const char *attrs[1] = { "member" };
1476 char *sidstr;
1477 struct tldap_message **msg;
1478 int i, rc, num_members;
1479 DATA_BLOB *blobs;
1480 struct dom_sid *members;
1481
1482 sidstr = sid_binstring(talloc_tos(), alias);
1483 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1484
1485 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1486 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1487 &msg, "(objectsid=%s)", sidstr);
1488 TALLOC_FREE(sidstr);
1489 if (rc != TLDAP_SUCCESS) {
1490 DEBUG(10, ("ldap_search failed %s\n",
1491 tldap_errstr(talloc_tos(), state->ld, rc)));
1492 return NT_STATUS_LDAP(rc);
1493 }
1494 switch talloc_array_length(msg) {
1495 case 0:
1496 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1497 break;
1498 case 1:
1499 break;
1500 default:
1501 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1502 break;
1503 }
1504
1505 if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1506 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1507 }
1508
1509 members = talloc_array(mem_ctx, struct dom_sid, num_members);
1510 if (members == NULL) {
1511 return NT_STATUS_NO_MEMORY;
1512 }
1513
1514 for (i=0; i<num_members; i++) {
1515 if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
1516 TALLOC_FREE(members);
1517 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1518 }
1519 }
1520
1521 *pmembers = members;
1522 *pnum_members = num_members;
1523 return NT_STATUS_OK;
1524}
1525
1526static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1527 TALLOC_CTX *mem_ctx,
1528 const DOM_SID *domain_sid,
1529 const DOM_SID *members,
1530 size_t num_members,
1531 uint32_t **palias_rids,
1532 size_t *pnum_alias_rids)
1533{
1534 struct pdb_ads_state *state = talloc_get_type_abort(
1535 m->private_data, struct pdb_ads_state);
1536 const char *attrs[1] = { "objectSid" };
1537 struct tldap_message **msg;
1538 uint32_t *alias_rids = NULL;
1539 size_t num_alias_rids = 0;
1540 int i, rc, count;
1541 bool got_members = false;
1542 char *filter;
1543 NTSTATUS status;
1544
1545 /*
1546 * TODO: Get the filter right so that we only get the aliases from
1547 * either the SAM or BUILTIN
1548 */
1549
1550 filter = talloc_asprintf(talloc_tos(),
1551 "(&(|(grouptype=%d)(grouptype=%d))"
1552 "(objectclass=group)(|",
1553 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1554 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1555 if (filter == NULL) {
1556 return NT_STATUS_NO_MEMORY;
1557 }
1558
1559 for (i=0; i<num_members; i++) {
1560 char *dn;
1561
1562 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1563 if (!NT_STATUS_IS_OK(status)) {
1564 DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1565 sid_string_dbg(&members[i]),
1566 nt_errstr(status)));
1567 continue;
1568 }
1569 filter = talloc_asprintf_append_buffer(
1570 filter, "(member=%s)", dn);
1571 TALLOC_FREE(dn);
1572 if (filter == NULL) {
1573 return NT_STATUS_NO_MEMORY;
1574 }
1575 got_members = true;
1576 }
1577
1578 if (!got_members) {
1579 goto done;
1580 }
1581
1582 rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1583 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1584 &msg, "%s))", filter);
1585 TALLOC_FREE(filter);
1586 if (rc != TLDAP_SUCCESS) {
1587 DEBUG(10, ("tldap_search failed %s\n",
1588 tldap_errstr(talloc_tos(), state->ld, rc)));
1589 return NT_STATUS_LDAP(rc);
1590 }
1591
1592 count = talloc_array_length(msg);
1593 if (count == 0) {
1594 goto done;
1595 }
1596
1597 alias_rids = talloc_array(mem_ctx, uint32_t, count);
1598 if (alias_rids == NULL) {
1599 TALLOC_FREE(msg);
1600 return NT_STATUS_NO_MEMORY;
1601 }
1602
1603 for (i=0; i<count; i++) {
1604 struct dom_sid sid;
1605
1606 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1607 DEBUG(10, ("Could not pull SID for member %d\n", i));
1608 continue;
1609 }
1610 if (sid_peek_check_rid(domain_sid, &sid,
1611 &alias_rids[num_alias_rids])) {
1612 num_alias_rids += 1;
1613 }
1614 }
1615done:
1616 TALLOC_FREE(msg);
1617 *palias_rids = alias_rids;
1618 *pnum_alias_rids = 0;
1619 return NT_STATUS_OK;
1620}
1621
1622static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1623 const DOM_SID *domain_sid,
1624 int num_rids,
1625 uint32 *rids,
1626 const char **names,
1627 enum lsa_SidType *lsa_attrs)
1628{
1629 struct pdb_ads_state *state = talloc_get_type_abort(
1630 m->private_data, struct pdb_ads_state);
1631 const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1632 int i, num_mapped;
1633
1634 if (num_rids == 0) {
1635 return NT_STATUS_NONE_MAPPED;
1636 }
1637
1638 num_mapped = 0;
1639
1640 for (i=0; i<num_rids; i++) {
1641 struct dom_sid sid;
1642 struct tldap_message **msg;
1643 char *sidstr;
1644 uint32_t attr;
1645 int rc;
1646
1647 lsa_attrs[i] = SID_NAME_UNKNOWN;
1648
1649 sid_compose(&sid, domain_sid, rids[i]);
1650
1651 sidstr = sid_binstring(talloc_tos(), &sid);
1652 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1653
1654 rc = pdb_ads_search_fmt(state, state->domaindn,
1655 TLDAP_SCOPE_SUB, attrs,
1656 ARRAY_SIZE(attrs), 0, talloc_tos(),
1657 &msg, "(objectsid=%s)", sidstr);
1658 TALLOC_FREE(sidstr);
1659 if (rc != TLDAP_SUCCESS) {
1660 DEBUG(10, ("ldap_search failed %s\n",
1661 tldap_errstr(talloc_tos(), state->ld, rc)));
1662 continue;
1663 }
1664
1665 switch talloc_array_length(msg) {
1666 case 0:
1667 DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1668 continue;
1669 case 1:
1670 break;
1671 default:
1672 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1673 }
1674
1675 names[i] = tldap_talloc_single_attribute(
1676 msg[0], "samAccountName", talloc_tos());
1677 if (names[i] == NULL) {
1678 DEBUG(10, ("no samAccountName\n"));
1679 continue;
1680 }
1681 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1682 DEBUG(10, ("no samAccountType"));
1683 continue;
1684 }
1685 lsa_attrs[i] = ds_atype_map(attr);
1686 num_mapped += 1;
1687 }
1688
1689 if (num_mapped == 0) {
1690 return NT_STATUS_NONE_MAPPED;
1691 }
1692 if (num_mapped < num_rids) {
1693 return STATUS_SOME_UNMAPPED;
1694 }
1695 return NT_STATUS_OK;
1696}
1697
1698static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1699 const DOM_SID *domain_sid,
1700 int num_names,
1701 const char **pp_names,
1702 uint32 *rids,
1703 enum lsa_SidType *attrs)
1704{
1705 return NT_STATUS_NOT_IMPLEMENTED;
1706}
1707
1708static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1709 enum pdb_policy_type type,
1710 uint32_t *value)
1711{
1712 return account_policy_get(type, value)
1713 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1714}
1715
1716static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1717 enum pdb_policy_type type,
1718 uint32_t value)
1719{
1720 return account_policy_set(type, value)
1721 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1722}
1723
1724static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1725 time_t *seq_num)
1726{
1727 return NT_STATUS_NOT_IMPLEMENTED;
1728}
1729
1730struct pdb_ads_search_state {
1731 uint32_t acct_flags;
1732 struct samr_displayentry *entries;
1733 uint32_t num_entries;
1734 ssize_t array_size;
1735 uint32_t current;
1736};
1737
1738static bool pdb_ads_next_entry(struct pdb_search *search,
1739 struct samr_displayentry *entry)
1740{
1741 struct pdb_ads_search_state *state = talloc_get_type_abort(
1742 search->private_data, struct pdb_ads_search_state);
1743
1744 if (state->current == state->num_entries) {
1745 return false;
1746 }
1747
1748 entry->idx = state->entries[state->current].idx;
1749 entry->rid = state->entries[state->current].rid;
1750 entry->acct_flags = state->entries[state->current].acct_flags;
1751
1752 entry->account_name = talloc_strdup(
1753 search, state->entries[state->current].account_name);
1754 entry->fullname = talloc_strdup(
1755 search, state->entries[state->current].fullname);
1756 entry->description = talloc_strdup(
1757 search, state->entries[state->current].description);
1758
1759 if ((entry->account_name == NULL) || (entry->fullname == NULL)
1760 || (entry->description == NULL)) {
1761 DEBUG(0, ("talloc_strdup failed\n"));
1762 return false;
1763 }
1764
1765 state->current += 1;
1766 return true;
1767}
1768
1769static void pdb_ads_search_end(struct pdb_search *search)
1770{
1771 struct pdb_ads_search_state *state = talloc_get_type_abort(
1772 search->private_data, struct pdb_ads_search_state);
1773 TALLOC_FREE(state);
1774}
1775
1776static bool pdb_ads_search_filter(struct pdb_methods *m,
1777 struct pdb_search *search,
1778 const char *filter,
1779 struct pdb_ads_search_state **pstate)
1780{
1781 struct pdb_ads_state *state = talloc_get_type_abort(
1782 m->private_data, struct pdb_ads_state);
1783 struct pdb_ads_search_state *sstate;
1784 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1785 "userAccountControl", "description" };
1786 struct tldap_message **users;
1787 int i, rc, num_users;
1788
1789 sstate = talloc_zero(search, struct pdb_ads_search_state);
1790 if (sstate == NULL) {
1791 return false;
1792 }
1793
1794 rc = pdb_ads_search_fmt(
1795 state, state->domaindn, TLDAP_SCOPE_SUB,
1796 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1797 "%s", filter);
1798 if (rc != TLDAP_SUCCESS) {
1799 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1800 tldap_errstr(talloc_tos(), state->ld, rc)));
1801 return false;
1802 }
1803
1804 num_users = talloc_array_length(users);
1805
1806 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1807 num_users);
1808 if (sstate->entries == NULL) {
1809 DEBUG(10, ("talloc failed\n"));
1810 return false;
1811 }
1812
1813 sstate->num_entries = 0;
1814
1815 for (i=0; i<num_users; i++) {
1816 struct samr_displayentry *e;
1817 struct dom_sid sid;
1818
1819 e = &sstate->entries[sstate->num_entries];
1820
1821 e->idx = sstate->num_entries;
1822 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1823 DEBUG(10, ("Could not pull sid\n"));
1824 continue;
1825 }
1826 sid_peek_rid(&sid, &e->rid);
1827 e->acct_flags = ACB_NORMAL;
1828 e->account_name = tldap_talloc_single_attribute(
1829 users[i], "samAccountName", sstate->entries);
1830 if (e->account_name == NULL) {
1831 return false;
1832 }
1833 e->fullname = tldap_talloc_single_attribute(
1834 users[i], "displayName", sstate->entries);
1835 if (e->fullname == NULL) {
1836 e->fullname = "";
1837 }
1838 e->description = tldap_talloc_single_attribute(
1839 users[i], "description", sstate->entries);
1840 if (e->description == NULL) {
1841 e->description = "";
1842 }
1843
1844 sstate->num_entries += 1;
1845 if (sstate->num_entries >= num_users) {
1846 break;
1847 }
1848 }
1849
1850 search->private_data = sstate;
1851 search->next_entry = pdb_ads_next_entry;
1852 search->search_end = pdb_ads_search_end;
1853 *pstate = sstate;
1854 return true;
1855}
1856
1857static bool pdb_ads_search_users(struct pdb_methods *m,
1858 struct pdb_search *search,
1859 uint32 acct_flags)
1860{
1861 struct pdb_ads_search_state *sstate;
1862 bool ret;
1863
1864 ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1865 if (!ret) {
1866 return false;
1867 }
1868 sstate->acct_flags = acct_flags;
1869 return true;
1870}
1871
1872static bool pdb_ads_search_groups(struct pdb_methods *m,
1873 struct pdb_search *search)
1874{
1875 struct pdb_ads_search_state *sstate;
1876 char *filter;
1877 bool ret;
1878
1879 filter = talloc_asprintf(talloc_tos(),
1880 "(&(grouptype=%d)(objectclass=group))",
1881 GTYPE_SECURITY_GLOBAL_GROUP);
1882 if (filter == NULL) {
1883 return false;
1884 }
1885 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1886 TALLOC_FREE(filter);
1887 if (!ret) {
1888 return false;
1889 }
1890 sstate->acct_flags = 0;
1891 return true;
1892}
1893
1894static bool pdb_ads_search_aliases(struct pdb_methods *m,
1895 struct pdb_search *search,
1896 const DOM_SID *sid)
1897{
1898 struct pdb_ads_search_state *sstate;
1899 char *filter;
1900 bool ret;
1901
1902 filter = talloc_asprintf(
1903 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1904 sid_check_is_builtin(sid)
1905 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1906 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1907
1908 if (filter == NULL) {
1909 return false;
1910 }
1911 ret = pdb_ads_search_filter(m, search, filter, &sstate);
1912 TALLOC_FREE(filter);
1913 if (!ret) {
1914 return false;
1915 }
1916 sstate->acct_flags = 0;
1917 return true;
1918}
1919
1920static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1921 DOM_SID *sid)
1922{
1923 struct pdb_ads_state *state = talloc_get_type_abort(
1924 m->private_data, struct pdb_ads_state);
1925 sid_compose(sid, &state->domainsid, uid);
1926 return true;
1927}
1928
1929static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1930 DOM_SID *sid)
1931{
1932 struct pdb_ads_state *state = talloc_get_type_abort(
1933 m->private_data, struct pdb_ads_state);
1934 sid_compose(sid, &state->domainsid, gid);
1935 return true;
1936}
1937
1938static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1939 union unid_t *id, enum lsa_SidType *type)
1940{
1941 struct pdb_ads_state *state = talloc_get_type_abort(
1942 m->private_data, struct pdb_ads_state);
1943 struct tldap_message **msg;
1944 char *sidstr;
1945 uint32_t rid;
1946 int rc;
1947
1948 /*
1949 * This is a big, big hack: Just hard-code the rid as uid/gid.
1950 */
1951
1952 sid_peek_rid(sid, &rid);
1953
1954 sidstr = sid_binstring(talloc_tos(), sid);
1955 if (sidstr == NULL) {
1956 return false;
1957 }
1958
1959 rc = pdb_ads_search_fmt(
1960 state, state->domaindn, TLDAP_SCOPE_SUB,
1961 NULL, 0, 0, talloc_tos(), &msg,
1962 "(&(objectsid=%s)(objectclass=user))", sidstr);
1963 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1964 id->uid = rid;
1965 *type = SID_NAME_USER;
1966 TALLOC_FREE(sidstr);
1967 return true;
1968 }
1969
1970 rc = pdb_ads_search_fmt(
1971 state, state->domaindn, TLDAP_SCOPE_SUB,
1972 NULL, 0, 0, talloc_tos(), &msg,
1973 "(&(objectsid=%s)(objectclass=group))", sidstr);
1974 if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1975 id->gid = rid;
1976 *type = SID_NAME_DOM_GRP;
1977 TALLOC_FREE(sidstr);
1978 return true;
1979 }
1980
1981 TALLOC_FREE(sidstr);
1982 return false;
1983}
1984
1985static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
1986{
1987 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
1988}
1989
1990static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1991{
1992 return false;
1993}
1994
1995static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1996 const char *domain, char** pwd,
1997 DOM_SID *sid,
1998 time_t *pass_last_set_time)
1999{
2000 return false;
2001}
2002
2003static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
2004 const char* domain, const char* pwd,
2005 const DOM_SID *sid)
2006{
2007 return false;
2008}
2009
2010static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
2011 const char *domain)
2012{
2013 return false;
2014}
2015
2016static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
2017 TALLOC_CTX *mem_ctx,
2018 uint32 *num_domains,
2019 struct trustdom_info ***domains)
2020{
2021 *num_domains = 0;
2022 *domains = NULL;
2023 return NT_STATUS_OK;
2024}
2025
2026static void pdb_ads_init_methods(struct pdb_methods *m)
2027{
2028 m->name = "ads";
2029 m->get_domain_info = pdb_ads_get_domain_info;
2030 m->getsampwnam = pdb_ads_getsampwnam;
2031 m->getsampwsid = pdb_ads_getsampwsid;
2032 m->create_user = pdb_ads_create_user;
2033 m->delete_user = pdb_ads_delete_user;
2034 m->add_sam_account = pdb_ads_add_sam_account;
2035 m->update_sam_account = pdb_ads_update_sam_account;
2036 m->delete_sam_account = pdb_ads_delete_sam_account;
2037 m->rename_sam_account = pdb_ads_rename_sam_account;
2038 m->update_login_attempts = pdb_ads_update_login_attempts;
2039 m->getgrsid = pdb_ads_getgrsid;
2040 m->getgrgid = pdb_ads_getgrgid;
2041 m->getgrnam = pdb_ads_getgrnam;
2042 m->create_dom_group = pdb_ads_create_dom_group;
2043 m->delete_dom_group = pdb_ads_delete_dom_group;
2044 m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
2045 m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
2046 m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
2047 m->enum_group_mapping = pdb_ads_enum_group_mapping;
2048 m->enum_group_members = pdb_ads_enum_group_members;
2049 m->enum_group_memberships = pdb_ads_enum_group_memberships;
2050 m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
2051 m->add_groupmem = pdb_ads_add_groupmem;
2052 m->del_groupmem = pdb_ads_del_groupmem;
2053 m->create_alias = pdb_ads_create_alias;
2054 m->delete_alias = pdb_ads_delete_alias;
2055 m->get_aliasinfo = pdb_default_get_aliasinfo;
2056 m->set_aliasinfo = pdb_ads_set_aliasinfo;
2057 m->add_aliasmem = pdb_ads_add_aliasmem;
2058 m->del_aliasmem = pdb_ads_del_aliasmem;
2059 m->enum_aliasmem = pdb_ads_enum_aliasmem;
2060 m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
2061 m->lookup_rids = pdb_ads_lookup_rids;
2062 m->lookup_names = pdb_ads_lookup_names;
2063 m->get_account_policy = pdb_ads_get_account_policy;
2064 m->set_account_policy = pdb_ads_set_account_policy;
2065 m->get_seq_num = pdb_ads_get_seq_num;
2066 m->search_users = pdb_ads_search_users;
2067 m->search_groups = pdb_ads_search_groups;
2068 m->search_aliases = pdb_ads_search_aliases;
2069 m->uid_to_sid = pdb_ads_uid_to_sid;
2070 m->gid_to_sid = pdb_ads_gid_to_sid;
2071 m->sid_to_id = pdb_ads_sid_to_id;
2072 m->capabilities = pdb_ads_capabilities;
2073 m->new_rid = pdb_ads_new_rid;
2074 m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2075 m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2076 m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2077 m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2078}
2079
2080static void free_private_data(void **vp)
2081{
2082 struct pdb_ads_state *state = talloc_get_type_abort(
2083 *vp, struct pdb_ads_state);
2084
2085 TALLOC_FREE(state->ld);
2086 return;
2087}
2088
2089/*
2090 this is used to catch debug messages from events
2091*/
2092static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2093 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
2094
2095static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2096 const char *fmt, va_list ap)
2097{
2098 int samba_level = -1;
2099 char *s = NULL;
2100 switch (level) {
2101 case TLDAP_DEBUG_FATAL:
2102 samba_level = 0;
2103 break;
2104 case TLDAP_DEBUG_ERROR:
2105 samba_level = 1;
2106 break;
2107 case TLDAP_DEBUG_WARNING:
2108 samba_level = 2;
2109 break;
2110 case TLDAP_DEBUG_TRACE:
2111 samba_level = 11;
2112 break;
2113
2114 };
2115 if (vasprintf(&s, fmt, ap) == -1) {
2116 return;
2117 }
2118 DEBUG(samba_level, ("tldap: %s", s));
2119 free(s);
2120}
2121
2122static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2123{
2124 NTSTATUS status;
2125 int fd;
2126
2127 if (tldap_connection_ok(state->ld)) {
2128 return state->ld;
2129 }
2130 TALLOC_FREE(state->ld);
2131
2132 status = open_socket_out(
2133 (struct sockaddr_storage *)(void *)&state->socket_address,
2134 0, 0, &fd);
2135 if (!NT_STATUS_IS_OK(status)) {
2136 DEBUG(10, ("Could not connect to %s: %s\n",
2137 state->socket_address.sun_path, nt_errstr(status)));
2138 return NULL;
2139 }
2140
2141 set_blocking(fd, false);
2142
2143 state->ld = tldap_context_create(state, fd);
2144 if (state->ld == NULL) {
2145 close(fd);
2146 return NULL;
2147 }
2148 tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2149
2150 return state->ld;
2151}
2152
2153int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2154 int scope, const char *attrs[], int num_attrs,
2155 int attrsonly,
2156 TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2157 const char *fmt, ...)
2158{
2159 struct tldap_context *ld;
2160 va_list ap;
2161 int ret;
2162
2163 ld = pdb_ads_ld(state);
2164 if (ld == NULL) {
2165 return TLDAP_SERVER_DOWN;
2166 }
2167
2168 va_start(ap, fmt);
2169 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2170 mem_ctx, res, fmt, ap);
2171 va_end(ap);
2172
2173 if (ret != TLDAP_SERVER_DOWN) {
2174 return ret;
2175 }
2176
2177 /* retry once */
2178 ld = pdb_ads_ld(state);
2179 if (ld == NULL) {
2180 return TLDAP_SERVER_DOWN;
2181 }
2182
2183 va_start(ap, fmt);
2184 ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2185 mem_ctx, res, fmt, ap);
2186 va_end(ap);
2187 return ret;
2188}
2189
2190static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2191 const char *location)
2192{
2193 const char *domain_attrs[2] = { "objectSid", "objectGUID" };
2194 const char *ncname_attrs[1] = { "netbiosname" };
2195 struct tldap_context *ld;
2196 struct tldap_message *rootdse, **domain, **ncname;
2197 TALLOC_CTX *frame = talloc_stackframe();
2198 NTSTATUS status;
2199 int num_domains;
2200 int rc;
2201
2202 ZERO_STRUCT(state->socket_address);
2203 state->socket_address.sun_family = AF_UNIX;
2204 strncpy(state->socket_address.sun_path, location,
2205 sizeof(state->socket_address.sun_path) - 1);
2206
2207 ld = pdb_ads_ld(state);
2208 if (ld == NULL) {
2209 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2210 goto done;
2211 }
2212
2213 rc = tldap_fetch_rootdse(ld);
2214 if (rc != TLDAP_SUCCESS) {
2215 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2216 tldap_errstr(talloc_tos(), state->ld, rc)));
2217 status = NT_STATUS_LDAP(rc);
2218 goto done;
2219 }
2220 rootdse = tldap_rootdse(state->ld);
2221
2222 state->domaindn = tldap_talloc_single_attribute(
2223 rootdse, "defaultNamingContext", state);
2224 if (state->domaindn == NULL) {
2225 DEBUG(10, ("Could not get defaultNamingContext\n"));
2226 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2227 goto done;
2228 }
2229 DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2230
2231 state->configdn = tldap_talloc_single_attribute(
2232 rootdse, "configurationNamingContext", state);
2233 if (state->domaindn == NULL) {
2234 DEBUG(10, ("Could not get configurationNamingContext\n"));
2235 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2236 goto done;
2237 }
2238 DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2239
2240 /*
2241 * Figure out our domain's SID
2242 */
2243 rc = pdb_ads_search_fmt(
2244 state, state->domaindn, TLDAP_SCOPE_BASE,
2245 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2246 talloc_tos(), &domain, "(objectclass=*)");
2247 if (rc != TLDAP_SUCCESS) {
2248 DEBUG(10, ("Could not retrieve domain: %s\n",
2249 tldap_errstr(talloc_tos(), state->ld, rc)));
2250 status = NT_STATUS_LDAP(rc);
2251 goto done;
2252 }
2253
2254 num_domains = talloc_array_length(domain);
2255 if (num_domains != 1) {
2256 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2257 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2258 goto done;
2259 }
2260 if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2261 DEBUG(10, ("Could not retrieve domain SID\n"));
2262 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2263 goto done;
2264 }
2265 if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) {
2266 DEBUG(10, ("Could not retrieve domain GUID\n"));
2267 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2268 goto done;
2269 }
2270 DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2271
2272 /*
2273 * Figure out our domain's short name
2274 */
2275 rc = pdb_ads_search_fmt(
2276 state, state->configdn, TLDAP_SCOPE_SUB,
2277 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2278 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2279 if (rc != TLDAP_SUCCESS) {
2280 DEBUG(10, ("Could not retrieve ncname: %s\n",
2281 tldap_errstr(talloc_tos(), state->ld, rc)));
2282 status = NT_STATUS_LDAP(rc);
2283 goto done;
2284 }
2285 if (talloc_array_length(ncname) != 1) {
2286 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2287 goto done;
2288 }
2289
2290 state->netbiosname = tldap_talloc_single_attribute(
2291 ncname[0], "netbiosname", state);
2292 if (state->netbiosname == NULL) {
2293 DEBUG(10, ("Could not get netbiosname\n"));
2294 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2295 goto done;
2296 }
2297 DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2298
2299 if (!strequal(lp_workgroup(), state->netbiosname)) {
2300 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2301 state->netbiosname, lp_workgroup()));
2302 status = NT_STATUS_NO_SUCH_DOMAIN;
2303 goto done;
2304 }
2305
2306 secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2307
2308 status = NT_STATUS_OK;
2309done:
2310 TALLOC_FREE(frame);
2311 return status;
2312}
2313
2314static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2315 const char *location)
2316{
2317 struct pdb_methods *m;
2318 struct pdb_ads_state *state;
2319 char *tmp = NULL;
2320 NTSTATUS status;
2321
2322 m = talloc(talloc_autofree_context(), struct pdb_methods);
2323 if (m == NULL) {
2324 return NT_STATUS_NO_MEMORY;
2325 }
2326 state = talloc_zero(m, struct pdb_ads_state);
2327 if (state == NULL) {
2328 goto nomem;
2329 }
2330 m->private_data = state;
2331 m->free_private_data = free_private_data;
2332 pdb_ads_init_methods(m);
2333
2334 if (location == NULL) {
2335 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2336 lp_private_dir());
2337 location = tmp;
2338 }
2339 if (location == NULL) {
2340 goto nomem;
2341 }
2342
2343 status = pdb_ads_connect(state, location);
2344 if (!NT_STATUS_IS_OK(status)) {
2345 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2346 goto fail;
2347 }
2348
2349 *pdb_method = m;
2350 return NT_STATUS_OK;
2351nomem:
2352 status = NT_STATUS_NO_MEMORY;
2353fail:
2354 TALLOC_FREE(m);
2355 return status;
2356}
2357
2358NTSTATUS pdb_ads_init(void);
2359NTSTATUS pdb_ads_init(void)
2360{
2361 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
2362 pdb_init_ads);
2363}
Note: See TracBrowser for help on using the repository browser.