Implement pdb_ads_[add|del]_groupmem
[samba.git] / source3 / passdb / pdb_ads.c
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
22 struct pdb_ads_state {
23         struct tldap_context *ld;
24         struct dom_sid domainsid;
25         char *domaindn;
26         char *configdn;
27         char *netbiosname;
28 };
29
30 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
31                                     struct samu *sam_acct,
32                                     const DOM_SID *sid);
33 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
34                                DOM_SID *sid);
35 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
36                                struct dom_sid *psid);
37 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
38                                const struct dom_sid *sid,
39                                TALLOC_CTX *mem_ctx, char **pdn);
40
41 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
42                               time_t *ptime)
43 {
44         uint64_t tmp;
45
46         if (!tldap_pull_uint64(msg, attr, &tmp)) {
47                 return false;
48         }
49         *ptime = uint64s_nt_time_to_unix_abs(&tmp);
50         return true;
51 }
52
53 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
54 {
55         uint32_t rid;
56         sid_peek_rid(sid, &rid);
57         return rid;
58 }
59
60 struct pdb_ads_samu_private {
61         char *dn;
62         struct tldap_message *ldapmsg;
63 };
64
65 static struct samu *pdb_ads_init_guest(TALLOC_CTX *mem_ctx,
66                                        struct pdb_methods *m)
67 {
68         struct pdb_ads_state *state = talloc_get_type_abort(
69                 m->private_data, struct pdb_ads_state);
70         struct dom_sid guest_sid;
71         struct samu *guest;
72         NTSTATUS status;
73
74         sid_compose(&guest_sid, &state->domainsid, DOMAIN_USER_RID_GUEST);
75
76         guest = samu_new(mem_ctx);
77         if (guest == NULL) {
78                 return NULL;
79         }
80
81         status = pdb_ads_getsampwsid(m, guest, &guest_sid);
82         if (!NT_STATUS_IS_OK(status)) {
83                 DEBUG(10, ("Could not init guest account: %s\n",
84                            nt_errstr(status)));
85                 TALLOC_FREE(guest);
86                 return NULL;
87         }
88         return guest;
89 }
90
91 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
92         struct pdb_methods *m, struct samu *sam)
93 {
94         struct pdb_ads_samu_private *result;
95         uint32_t rid;
96
97         result = (struct pdb_ads_samu_private *)
98                 pdb_get_backend_private_data(sam, m);
99
100         if (result != NULL) {
101                 return talloc_get_type_abort(
102                         result, struct pdb_ads_samu_private);
103         }
104
105         /*
106          * This is now a weirdness of the passdb API. For the guest user we
107          * are not asked first.
108          */
109         sid_peek_rid(pdb_get_user_sid(sam), &rid);
110
111         if (rid == DOMAIN_USER_RID_GUEST) {
112                 struct samu *guest = pdb_ads_init_guest(talloc_tos(), m);
113
114                 if (guest == NULL) {
115                         return NULL;
116                 }
117                 result = talloc_get_type_abort(
118                         pdb_get_backend_private_data(guest, m),
119                         struct pdb_ads_samu_private);
120                 pdb_set_backend_private_data(
121                         sam, talloc_move(sam, &result), NULL, m, PDB_SET);
122                 TALLOC_FREE(guest);
123                 return talloc_get_type_abort(
124                         pdb_get_backend_private_data(sam, m),
125                         struct pdb_ads_samu_private);
126         }
127
128         return NULL;
129 }
130
131 static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m,
132                                           struct samu *sam,
133                                           struct tldap_message *entry)
134 {
135         struct pdb_ads_state *state = talloc_get_type_abort(
136                 m->private_data, struct pdb_ads_state);
137         TALLOC_CTX *frame = talloc_stackframe();
138         struct pdb_ads_samu_private *priv;
139         NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
140         char *str;
141         time_t tmp_time;
142         struct dom_sid sid;
143         uint64_t n;
144         DATA_BLOB blob;
145
146         priv = talloc(sam, struct pdb_ads_samu_private);
147         if (priv == NULL) {
148                 return NT_STATUS_NO_MEMORY;
149         }
150         if (!tldap_entry_dn(entry, &priv->dn)) {
151                 TALLOC_FREE(priv);
152                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
153         }
154
155         str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
156         if (str == NULL) {
157                 DEBUG(10, ("no samAccountName\n"));
158                 goto fail;
159         }
160         pdb_set_username(sam, str, PDB_SET);
161         TALLOC_FREE(str);
162
163         if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
164                 pdb_set_logon_time(sam, tmp_time, PDB_SET);
165         }
166         if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
167                 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
168         }
169         if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
170                 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
171         }
172         if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
173                 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
174         }
175
176         str = tldap_talloc_single_attribute(entry, "samAccoutName",
177                                             talloc_tos());
178         if (str != NULL) {
179                 pdb_set_username(sam, str, PDB_SET);
180         }
181
182         str = tldap_talloc_single_attribute(entry, "displayName",
183                                             talloc_tos());
184         if (str != NULL) {
185                 pdb_set_fullname(sam, str, PDB_SET);
186         }
187
188         str = tldap_talloc_single_attribute(entry, "homeDirectory",
189                                             talloc_tos());
190         if (str != NULL) {
191                 pdb_set_homedir(sam, str, PDB_SET);
192         }
193
194         str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
195         if (str != NULL) {
196                 pdb_set_dir_drive(sam, str, PDB_SET);
197         }
198
199         str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
200         if (str != NULL) {
201                 pdb_set_logon_script(sam, str, PDB_SET);
202         }
203
204         str = tldap_talloc_single_attribute(entry, "profilePath",
205                                             talloc_tos());
206         if (str != NULL) {
207                 pdb_set_profile_path(sam, str, PDB_SET);
208         }
209
210         str = tldap_talloc_single_attribute(entry, "profilePath",
211                                             talloc_tos());
212         if (str != NULL) {
213                 pdb_set_profile_path(sam, str, PDB_SET);
214         }
215
216         if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
217                 DEBUG(10, ("Could not pull SID\n"));
218                 goto fail;
219         }
220         pdb_set_user_sid(sam, &sid, PDB_SET);
221
222         if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
223                 DEBUG(10, ("Could not pull userAccountControl\n"));
224                 goto fail;
225         }
226         pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET);
227
228         if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
229                 if (blob.length != NT_HASH_LEN) {
230                         DEBUG(0, ("Got NT hash of length %d, expected %d\n",
231                                   (int)blob.length, NT_HASH_LEN));
232                         goto fail;
233                 }
234                 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
235         }
236
237         if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
238                 if (blob.length != LM_HASH_LEN) {
239                         DEBUG(0, ("Got LM hash of length %d, expected %d\n",
240                                   (int)blob.length, LM_HASH_LEN));
241                         goto fail;
242                 }
243                 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
244         }
245
246         if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
247                 sid_compose(&sid, &state->domainsid, n);
248                 pdb_set_group_sid(sam, &sid, PDB_SET);
249
250         }
251
252         priv->ldapmsg = talloc_move(priv, &entry);
253         pdb_set_backend_private_data(sam, priv, NULL, m, PDB_SET);
254
255         status = NT_STATUS_OK;
256 fail:
257         TALLOC_FREE(frame);
258         return status;
259 }
260
261 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
262                                       struct tldap_message *existing,
263                                       TALLOC_CTX *mem_ctx,
264                                       int *pnum_mods, struct tldap_mod **pmods,
265                                       struct samu *sam)
266 {
267         bool ret = true;
268
269         /* TODO: All fields :-) */
270
271         ret &= tldap_make_mod_fmt(
272                 existing, mem_ctx, pnum_mods, pmods, "displayName",
273                 "%s", pdb_get_fullname(sam));
274
275         ret &= tldap_make_mod_blob(
276                 existing, mem_ctx, pnum_mods, pmods, "unicodePwd",
277                 data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN));
278
279         ret &= tldap_make_mod_blob(
280                 existing, mem_ctx, pnum_mods, pmods, "dBCSPwd",
281                 data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN));
282
283         return ret;
284 }
285
286 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
287                                        struct pdb_ads_state *state,
288                                        struct samu *sam_acct,
289                                        const char *filter)
290 {
291         const char * attrs[] = {
292                 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
293                 "sAMAccountName", "displayName", "homeDirectory",
294                 "homeDrive", "scriptPath", "profilePath", "description",
295                 "userWorkstations", "comment", "userParameters", "objectSid",
296                 "primaryGroupID", "userAccountControl", "logonHours",
297                 "badPwdCount", "logonCount", "countryCode", "codePage",
298                 "unicodePwd", "dBCSPwd" };
299         struct tldap_message **users;
300         int rc, count;
301
302         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
303                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
304                               &users, "%s", filter);
305         if (rc != TLDAP_SUCCESS) {
306                 DEBUG(10, ("ldap_search failed %s\n",
307                            tldap_errstr(debug_ctx(), state->ld, rc)));
308                 return NT_STATUS_LDAP(rc);
309         }
310
311         count = talloc_array_length(users);
312         if (count != 1) {
313                 DEBUG(10, ("Expected 1 user, got %d\n", count));
314                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
315         }
316
317         return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]);
318 }
319
320 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
321                                     struct samu *sam_acct,
322                                     const char *username)
323 {
324         struct pdb_ads_state *state = talloc_get_type_abort(
325                 m->private_data, struct pdb_ads_state);
326         char *filter;
327
328         filter = talloc_asprintf(
329                 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
330                 username);
331         NT_STATUS_HAVE_NO_MEMORY(filter);
332
333         return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
334 }
335
336 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
337                                     struct samu *sam_acct,
338                                     const DOM_SID *sid)
339 {
340         struct pdb_ads_state *state = talloc_get_type_abort(
341                 m->private_data, struct pdb_ads_state);
342         char *sidstr, *filter;
343
344         sidstr = sid_binstring(talloc_tos(), sid);
345         NT_STATUS_HAVE_NO_MEMORY(sidstr);
346
347         filter = talloc_asprintf(
348                 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
349         TALLOC_FREE(sidstr);
350         NT_STATUS_HAVE_NO_MEMORY(filter);
351
352         return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
353 }
354
355 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
356                                     TALLOC_CTX *tmp_ctx,
357                                     const char *name, uint32 acct_flags,
358                                     uint32 *rid)
359 {
360         struct pdb_ads_state *state = talloc_get_type_abort(
361                 m->private_data, struct pdb_ads_state);
362         const char *attrs[1] = { "objectSid" };
363         struct tldap_mod *mods = NULL;
364         int num_mods = 0;
365         struct tldap_message **user;
366         struct dom_sid sid;
367         char *dn;
368         int rc;
369         bool ok;
370
371         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
372                              state->domaindn);
373         if (dn == NULL) {
374                 return NT_STATUS_NO_MEMORY;
375         }
376
377         /* TODO: Create machines etc */
378
379         ok = true;
380         ok &= tldap_make_mod_fmt(
381                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
382         ok &= tldap_make_mod_fmt(
383                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
384                 name);
385         if (!ok) {
386                 return NT_STATUS_NO_MEMORY;
387         }
388
389         rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
390         if (rc != TLDAP_SUCCESS) {
391                 DEBUG(10, ("ldap_add failed %s\n",
392                            tldap_errstr(debug_ctx(), state->ld, rc)));
393                 TALLOC_FREE(dn);
394                 return NT_STATUS_LDAP(rc);
395         }
396
397         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
398                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &user,
399                              "(&(objectclass=user)(samaccountname=%s))",
400                              name);
401         if (rc != TLDAP_SUCCESS) {
402                 DEBUG(10, ("Could not find just created user %s: %s\n",
403                            name, tldap_errstr(debug_ctx(), state->ld, rc)));
404                 TALLOC_FREE(dn);
405                 return NT_STATUS_LDAP(rc);
406         }
407
408         if (talloc_array_length(user) != 1) {
409                 DEBUG(10, ("Got %d users, expected one\n",
410                            (int)talloc_array_length(user)));
411                 TALLOC_FREE(dn);
412                 return NT_STATUS_LDAP(rc);
413         }
414
415         if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
416                 DEBUG(10, ("Could not fetch objectSid from user %s\n",
417                            name));
418                 TALLOC_FREE(dn);
419                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
420         }
421
422         sid_peek_rid(&sid, rid);
423         TALLOC_FREE(dn);
424         return NT_STATUS_OK;
425 }
426
427 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
428                                     TALLOC_CTX *tmp_ctx,
429                                     struct samu *sam)
430 {
431         struct pdb_ads_state *state = talloc_get_type_abort(
432                 m->private_data, struct pdb_ads_state);
433         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
434         int rc;
435
436         rc = tldap_delete(state->ld, priv->dn, NULL, NULL);
437         if (rc != TLDAP_SUCCESS) {
438                 DEBUG(10, ("ldap_delete for %s failed: %s\n", priv->dn,
439                            tldap_errstr(debug_ctx(), state->ld, rc)));
440                 return NT_STATUS_LDAP(rc);
441         }
442         return NT_STATUS_OK;
443 }
444
445 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
446                                         struct samu *sampass)
447 {
448         return NT_STATUS_NOT_IMPLEMENTED;
449 }
450
451 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
452                                            struct samu *sam)
453 {
454         struct pdb_ads_state *state = talloc_get_type_abort(
455                 m->private_data, struct pdb_ads_state);
456         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
457         struct tldap_mod *mods = NULL;
458         int rc, num_mods = 0;
459
460         if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
461                                        &num_mods, &mods, sam)) {
462                 return NT_STATUS_NO_MEMORY;
463         }
464
465         rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, NULL);
466         if (rc != TLDAP_SUCCESS) {
467                 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
468                            tldap_errstr(debug_ctx(), state->ld, rc)));
469                 return NT_STATUS_LDAP(rc);
470         }
471
472         TALLOC_FREE(mods);
473
474         return NT_STATUS_OK;
475 }
476
477 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
478                                            struct samu *username)
479 {
480         return NT_STATUS_NOT_IMPLEMENTED;
481 }
482
483 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
484                                            struct samu *oldname,
485                                            const char *newname)
486 {
487         return NT_STATUS_NOT_IMPLEMENTED;
488 }
489
490 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
491                                               struct samu *sam_acct,
492                                               bool success)
493 {
494         return NT_STATUS_NOT_IMPLEMENTED;
495 }
496
497 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
498                                     const char *filter)
499 {
500         struct pdb_ads_state *state = talloc_get_type_abort(
501                 m->private_data, struct pdb_ads_state);
502         const char *attrs[4] = { "objectSid", "description", "samAccountName",
503                                  "groupType" };
504         char *str;
505         struct tldap_message **group;
506         uint32_t grouptype;
507         int rc;
508
509         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
510                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
511                               &group, "%s", filter);
512         if (rc != TLDAP_SUCCESS) {
513                 DEBUG(10, ("ldap_search failed %s\n",
514                            tldap_errstr(debug_ctx(), state->ld, rc)));
515                 return NT_STATUS_LDAP(rc);
516         }
517         if (talloc_array_length(group) != 1) {
518                 DEBUG(10, ("Expected 1 user, got %d\n",
519                            (int)talloc_array_length(group)));
520                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
521         }
522
523         if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
524                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
525         }
526         map->gid = pdb_ads_sid2gid(&map->sid);
527
528         if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
529                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
530         }
531         switch (grouptype) {
532         case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
533         case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
534                 map->sid_name_use = SID_NAME_ALIAS;
535                 break;
536         case GTYPE_SECURITY_GLOBAL_GROUP:
537                 map->sid_name_use = SID_NAME_DOM_GRP;
538                 break;
539         default:
540                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
541         }
542
543         str = tldap_talloc_single_attribute(group[0], "samAccountName",
544                                             talloc_tos());
545         if (str == NULL) {
546                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
547         }
548         fstrcpy(map->nt_name, str);
549         TALLOC_FREE(str);
550
551         str = tldap_talloc_single_attribute(group[0], "description",
552                                             talloc_tos());
553         if (str != NULL) {
554                 fstrcpy(map->comment, str);
555                 TALLOC_FREE(str);
556         } else {
557                 map->comment[0] = '\0';
558         }
559
560         TALLOC_FREE(group);
561         return NT_STATUS_OK;
562 }
563
564 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
565                                  DOM_SID sid)
566 {
567         char *filter;
568         NTSTATUS status;
569
570         filter = talloc_asprintf(talloc_tos(),
571                                  "(&(objectsid=%s)(objectclass=group))",
572                                  sid_string_talloc(talloc_tos(), &sid));
573         if (filter == NULL) {
574                 return NT_STATUS_NO_MEMORY;
575         }
576
577         status = pdb_ads_getgrfilter(m, map, filter);
578         TALLOC_FREE(filter);
579         return status;
580 }
581
582 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
583                                  gid_t gid)
584 {
585         struct dom_sid sid;
586         pdb_ads_gid_to_sid(m, gid, &sid);
587         return pdb_ads_getgrsid(m, map, sid);
588 }
589
590 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
591                                  const char *name)
592 {
593         char *filter;
594         NTSTATUS status;
595
596         filter = talloc_asprintf(talloc_tos(),
597                                  "(&(samaccountname=%s)(objectclass=group))",
598                                  name);
599         if (filter == NULL) {
600                 return NT_STATUS_NO_MEMORY;
601         }
602
603         status = pdb_ads_getgrfilter(m, map, filter);
604         TALLOC_FREE(filter);
605         return status;
606 }
607
608 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
609                                          TALLOC_CTX *mem_ctx, const char *name,
610                                          uint32 *rid)
611 {
612         TALLOC_CTX *frame = talloc_stackframe();
613         struct pdb_ads_state *state = talloc_get_type_abort(
614                 m->private_data, struct pdb_ads_state);
615         const char *attrs[1] = { "objectSid" };
616         int num_mods = 0;
617         struct tldap_mod *mods = NULL;
618         struct tldap_message **alias;
619         struct dom_sid sid;
620         char *dn;
621         int rc;
622         bool ok = true;
623
624         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
625                              state->domaindn);
626         if (dn == NULL) {
627                 TALLOC_FREE(frame);
628                 return NT_STATUS_NO_MEMORY;
629         }
630
631         ok &= tldap_make_mod_fmt(
632                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
633                 name);
634         ok &= tldap_make_mod_fmt(
635                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
636         ok &= tldap_make_mod_fmt(
637                 NULL, talloc_tos(), &num_mods, &mods, "groupType",
638                 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
639
640         if (!ok) {
641                 TALLOC_FREE(frame);
642                 return NT_STATUS_NO_MEMORY;
643         }
644
645         rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
646         if (rc != TLDAP_SUCCESS) {
647                 DEBUG(10, ("ldap_add failed %s\n",
648                            tldap_errstr(debug_ctx(), state->ld, rc)));
649                 TALLOC_FREE(frame);
650                 return NT_STATUS_LDAP(rc);
651         }
652
653         rc = tldap_search_fmt(
654                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
655                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
656                 "(&(objectclass=group)(samaccountname=%s))", name);
657         if (rc != TLDAP_SUCCESS) {
658                 DEBUG(10, ("Could not find just created alias %s: %s\n",
659                            name, tldap_errstr(debug_ctx(), state->ld, rc)));
660                 TALLOC_FREE(frame);
661                 return NT_STATUS_LDAP(rc);
662         }
663
664         if (talloc_array_length(alias) != 1) {
665                 DEBUG(10, ("Got %d alias, expected one\n",
666                            (int)talloc_array_length(alias)));
667                 TALLOC_FREE(frame);
668                 return NT_STATUS_LDAP(rc);
669         }
670
671         if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
672                 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
673                            name));
674                 TALLOC_FREE(frame);
675                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
676         }
677
678         sid_peek_rid(&sid, rid);
679         TALLOC_FREE(frame);
680         return NT_STATUS_OK;
681 }
682
683 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
684                                          TALLOC_CTX *mem_ctx, uint32 rid)
685 {
686         struct pdb_ads_state *state = talloc_get_type_abort(
687                 m->private_data, struct pdb_ads_state);
688         struct dom_sid sid;
689         char *sidstr;
690         struct tldap_message **msg;
691         char *dn;
692         int rc;
693
694         sid_compose(&sid, &state->domainsid, rid);
695
696         sidstr = sid_binstring(talloc_tos(), &sid);
697         NT_STATUS_HAVE_NO_MEMORY(sidstr);
698
699         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
700                               NULL, 0, 0, talloc_tos(), &msg,
701                               ("(&(objectSid=%s)(objectClass=group))"),
702                               sidstr);
703         TALLOC_FREE(sidstr);
704         if (rc != TLDAP_SUCCESS) {
705                 DEBUG(10, ("ldap_search failed %s\n",
706                            tldap_errstr(debug_ctx(), state->ld, rc)));
707                 return NT_STATUS_LDAP(rc);
708         }
709
710         switch talloc_array_length(msg) {
711         case 0:
712                 return NT_STATUS_NO_SUCH_GROUP;
713         case 1:
714                 break;
715         default:
716                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
717         }
718
719         if (!tldap_entry_dn(msg[0], &dn)) {
720                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
721         }
722
723         rc = tldap_delete(state->ld, dn, NULL, NULL);
724         if (rc != TLDAP_SUCCESS) {
725                 DEBUG(10, ("ldap_delete failed: %s\n",
726                            tldap_errstr(debug_ctx(), state->ld, rc)));
727                 TALLOC_FREE(dn);
728                 return NT_STATUS_LDAP(rc);
729         }
730
731         TALLOC_FREE(msg);
732         return NT_STATUS_OK;
733 }
734
735 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
736                                                 GROUP_MAP *map)
737 {
738         return NT_STATUS_NOT_IMPLEMENTED;
739 }
740
741 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
742                                                    GROUP_MAP *map)
743 {
744         return NT_STATUS_NOT_IMPLEMENTED;
745 }
746
747 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
748                                                    DOM_SID sid)
749 {
750         return NT_STATUS_NOT_IMPLEMENTED;
751 }
752
753 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
754                                            const DOM_SID *sid,
755                                            enum lsa_SidType sid_name_use,
756                                            GROUP_MAP **pp_rmap,
757                                            size_t *p_num_entries,
758                                            bool unix_only)
759 {
760         return NT_STATUS_NOT_IMPLEMENTED;
761 }
762
763 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
764                                            TALLOC_CTX *mem_ctx,
765                                            const DOM_SID *group,
766                                            uint32 **pmembers,
767                                            size_t *pnum_members)
768 {
769         struct pdb_ads_state *state = talloc_get_type_abort(
770                 m->private_data, struct pdb_ads_state);
771         const char *attrs[1] = { "member" };
772         char *sidstr;
773         struct tldap_message **msg;
774         int i, rc, num_members;
775         DATA_BLOB *blobs;
776         uint32_t *members;
777
778         sidstr = sid_binstring(talloc_tos(), group);
779         NT_STATUS_HAVE_NO_MEMORY(sidstr);
780
781         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
782                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
783                               "(objectsid=%s)", sidstr);
784         TALLOC_FREE(sidstr);
785         if (rc != TLDAP_SUCCESS) {
786                 DEBUG(10, ("ldap_search failed %s\n",
787                            tldap_errstr(debug_ctx(), state->ld, rc)));
788                 return NT_STATUS_LDAP(rc);
789         }
790         switch talloc_array_length(msg) {
791         case 0:
792                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
793                 break;
794         case 1:
795                 break;
796         default:
797                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
798                 break;
799         }
800
801         if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
802                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
803         }
804
805         members = talloc_array(mem_ctx, uint32_t, num_members);
806         if (members == NULL) {
807                 return NT_STATUS_NO_MEMORY;
808         }
809
810         for (i=0; i<num_members; i++) {
811                 struct dom_sid sid;
812                 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &sid)
813                     || !sid_peek_rid(&sid, &members[i])) {
814                         TALLOC_FREE(members);
815                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
816                 }
817         }
818
819         *pmembers = members;
820         *pnum_members = num_members;
821         return NT_STATUS_OK;
822 }
823
824 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
825                                                TALLOC_CTX *mem_ctx,
826                                                struct samu *user,
827                                                DOM_SID **pp_sids,
828                                                gid_t **pp_gids,
829                                                size_t *p_num_groups)
830 {
831         struct pdb_ads_state *state = talloc_get_type_abort(
832                 m->private_data, struct pdb_ads_state);
833         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
834                 m, user);
835         const char *attrs[1] = { "objectSid" };
836         struct tldap_message **groups;
837         int i, rc, count;
838         size_t num_groups;
839         struct dom_sid *group_sids;
840         gid_t *gids;
841
842         rc = tldap_search_fmt(
843                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
844                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
845                 "(&(member=%s)(grouptype=%d)(objectclass=group))",
846                 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
847         if (rc != TLDAP_SUCCESS) {
848                 DEBUG(10, ("ldap_search failed %s\n",
849                            tldap_errstr(debug_ctx(), state->ld, rc)));
850                 return NT_STATUS_LDAP(rc);
851         }
852
853         count = talloc_array_length(groups);
854
855         group_sids = talloc_array(mem_ctx, struct dom_sid, count);
856         if (group_sids == NULL) {
857                 return NT_STATUS_NO_MEMORY;
858         }
859         gids = talloc_array(mem_ctx, gid_t, count);
860         if (gids == NULL) {
861                 TALLOC_FREE(group_sids);
862                 return NT_STATUS_NO_MEMORY;
863         }
864         num_groups = 0;
865
866         for (i=0; i<count; i++) {
867                 if (!tldap_pull_binsid(groups[i], "objectSid",
868                                        &group_sids[num_groups])) {
869                         continue;
870                 }
871                 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
872
873                 num_groups += 1;
874                 if (num_groups == count) {
875                         break;
876                 }
877         }
878
879         *pp_sids = group_sids;
880         *pp_gids = gids;
881         *p_num_groups = num_groups;
882         return NT_STATUS_OK;
883 }
884
885 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
886                                                TALLOC_CTX *mem_ctx,
887                                                struct samu *user)
888 {
889         return NT_STATUS_NOT_IMPLEMENTED;
890 }
891
892 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
893                                      TALLOC_CTX *mem_ctx,
894                                      uint32 grouprid, uint32 memberrid,
895                                      int mod_op)
896 {
897         struct pdb_ads_state *state = talloc_get_type_abort(
898                 m->private_data, struct pdb_ads_state);
899         TALLOC_CTX *frame = talloc_stackframe();
900         struct dom_sid groupsid, membersid;
901         char *groupdn, *memberdn;
902         struct tldap_mod *mods;
903         int rc;
904         NTSTATUS status;
905
906         sid_compose(&groupsid, &state->domainsid, grouprid);
907         sid_compose(&membersid, &state->domainsid, memberrid);
908
909         status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
910         if (!NT_STATUS_IS_OK(status)) {
911                 TALLOC_FREE(frame);
912                 TALLOC_FREE(frame);
913                 return NT_STATUS_NO_SUCH_GROUP;
914         }
915         status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
916         if (!NT_STATUS_IS_OK(status)) {
917                 TALLOC_FREE(frame);
918                 return NT_STATUS_NO_SUCH_USER;
919         }
920
921         mods = NULL;
922
923         if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
924                                "member", memberdn)) {
925                 TALLOC_FREE(frame);
926                 return NT_STATUS_NO_MEMORY;
927         }
928
929         rc = tldap_modify(state->ld, groupdn, 1, mods, NULL, NULL);
930         TALLOC_FREE(frame);
931         if (rc != TLDAP_SUCCESS) {
932                 DEBUG(10, ("ldap_modify failed: %s\n",
933                            tldap_errstr(debug_ctx(), state->ld, rc)));
934                 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
935                         return NT_STATUS_MEMBER_IN_GROUP;
936                 }
937                 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
938                         return NT_STATUS_MEMBER_NOT_IN_GROUP;
939                 }
940                 return NT_STATUS_LDAP(rc);
941         }
942
943         return NT_STATUS_OK;
944 }
945
946 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
947                                      TALLOC_CTX *mem_ctx,
948                                      uint32 group_rid, uint32 member_rid)
949 {
950         return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
951                                     TLDAP_MOD_ADD);
952 }
953
954 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
955                                      TALLOC_CTX *mem_ctx,
956                                      uint32 group_rid, uint32 member_rid)
957 {
958         return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
959                                     TLDAP_MOD_DELETE);
960 }
961
962 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
963                                      const char *name, uint32 *rid)
964 {
965         TALLOC_CTX *frame = talloc_stackframe();
966         struct pdb_ads_state *state = talloc_get_type_abort(
967                 m->private_data, struct pdb_ads_state);
968         const char *attrs[1] = { "objectSid" };
969         int num_mods = 0;
970         struct tldap_mod *mods = NULL;
971         struct tldap_message **alias;
972         struct dom_sid sid;
973         char *dn;
974         int rc;
975         bool ok = true;
976
977         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
978                              state->domaindn);
979         if (dn == NULL) {
980                 TALLOC_FREE(frame);
981                 return NT_STATUS_NO_MEMORY;
982         }
983
984         ok &= tldap_make_mod_fmt(
985                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
986                 name);
987         ok &= tldap_make_mod_fmt(
988                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
989         ok &= tldap_make_mod_fmt(
990                 NULL, talloc_tos(), &num_mods, &mods, "groupType",
991                 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
992
993         if (!ok) {
994                 TALLOC_FREE(frame);
995                 return NT_STATUS_NO_MEMORY;
996         }
997
998         rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
999         if (rc != TLDAP_SUCCESS) {
1000                 DEBUG(10, ("ldap_add failed %s\n",
1001                            tldap_errstr(debug_ctx(), state->ld, rc)));
1002                 TALLOC_FREE(frame);
1003                 return NT_STATUS_LDAP(rc);
1004         }
1005
1006         rc = tldap_search_fmt(
1007                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1008                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1009                 "(&(objectclass=group)(samaccountname=%s))", name);
1010         if (rc != TLDAP_SUCCESS) {
1011                 DEBUG(10, ("Could not find just created alias %s: %s\n",
1012                            name, tldap_errstr(debug_ctx(), state->ld, rc)));
1013                 TALLOC_FREE(frame);
1014                 return NT_STATUS_LDAP(rc);
1015         }
1016
1017         if (talloc_array_length(alias) != 1) {
1018                 DEBUG(10, ("Got %d alias, expected one\n",
1019                            (int)talloc_array_length(alias)));
1020                 TALLOC_FREE(frame);
1021                 return NT_STATUS_LDAP(rc);
1022         }
1023
1024         if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1025                 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1026                            name));
1027                 TALLOC_FREE(frame);
1028                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1029         }
1030
1031         sid_peek_rid(&sid, rid);
1032         TALLOC_FREE(frame);
1033         return NT_STATUS_OK;
1034 }
1035
1036 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1037                                      const DOM_SID *sid)
1038 {
1039         struct pdb_ads_state *state = talloc_get_type_abort(
1040                 m->private_data, struct pdb_ads_state);
1041         struct tldap_message **alias;
1042         char *sidstr, *dn;
1043         int rc;
1044
1045         sidstr = sid_binstring(talloc_tos(), sid);
1046         if (sidstr == NULL) {
1047                 return NT_STATUS_NO_MEMORY;
1048         }
1049
1050         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1051                               NULL, 0, 0, talloc_tos(), &alias,
1052                               "(&(objectSid=%s)(objectclass=group)"
1053                               "(|(grouptype=%d)(grouptype=%d)))",
1054                               sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1055                               GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1056         TALLOC_FREE(sidstr);
1057         if (rc != TLDAP_SUCCESS) {
1058                 DEBUG(10, ("ldap_search failed: %s\n",
1059                            tldap_errstr(debug_ctx(), state->ld, rc)));
1060                 TALLOC_FREE(dn);
1061                 return NT_STATUS_LDAP(rc);
1062         }
1063         if (talloc_array_length(alias) != 1) {
1064                 DEBUG(10, ("Expected 1 alias, got %d\n",
1065                            (int)talloc_array_length(alias)));
1066                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1067         }
1068         if (!tldap_entry_dn(alias[0], &dn)) {
1069                 DEBUG(10, ("Could not get DN for alias %s\n",
1070                            sid_string_dbg(sid)));
1071                 return NT_STATUS_INTERNAL_ERROR;
1072         }
1073
1074         rc = tldap_delete(state->ld, dn, NULL, NULL);
1075         if (rc != TLDAP_SUCCESS) {
1076                 DEBUG(10, ("ldap_delete failed: %s\n",
1077                            tldap_errstr(debug_ctx(), state->ld, rc)));
1078                 TALLOC_FREE(dn);
1079                 return NT_STATUS_LDAP(rc);
1080         }
1081
1082         return NT_STATUS_OK;
1083 }
1084
1085 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
1086                                       const DOM_SID *sid,
1087                                       struct acct_info *info)
1088 {
1089         return NT_STATUS_NOT_IMPLEMENTED;
1090 }
1091
1092 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1093                                       const DOM_SID *sid,
1094                                       struct acct_info *info)
1095 {
1096         return NT_STATUS_NOT_IMPLEMENTED;
1097 }
1098
1099 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1100                                const struct dom_sid *sid,
1101                                TALLOC_CTX *mem_ctx, char **pdn)
1102 {
1103         struct tldap_message **msg;
1104         char *sidstr, *dn;
1105         int rc;
1106
1107         sidstr = sid_binstring(talloc_tos(), sid);
1108         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1109
1110         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1111                               NULL, 0, 0, talloc_tos(), &msg,
1112                               "(objectsid=%s)", sidstr);
1113         TALLOC_FREE(sidstr);
1114         if (rc != TLDAP_SUCCESS) {
1115                 DEBUG(10, ("ldap_search failed %s\n",
1116                            tldap_errstr(debug_ctx(), state->ld, rc)));
1117                 return NT_STATUS_LDAP(rc);
1118         }
1119
1120         switch talloc_array_length(msg) {
1121         case 0:
1122                 return NT_STATUS_NOT_FOUND;
1123         case 1:
1124                 break;
1125         default:
1126                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1127         }
1128
1129         if (!tldap_entry_dn(msg[0], &dn)) {
1130                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1131         }
1132
1133         dn = talloc_strdup(mem_ctx, dn);
1134         if (dn == NULL) {
1135                 return NT_STATUS_NO_MEMORY;
1136         }
1137         TALLOC_FREE(msg);
1138
1139         *pdn = dn;
1140         return NT_STATUS_OK;
1141 }
1142
1143 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1144                                      const DOM_SID *alias,
1145                                      const DOM_SID *member,
1146                                      int mod_op)
1147 {
1148         struct pdb_ads_state *state = talloc_get_type_abort(
1149                 m->private_data, struct pdb_ads_state);
1150         TALLOC_CTX *frame = talloc_stackframe();
1151         struct tldap_mod *mods;
1152         int rc;
1153         char *aliasdn, *memberdn;
1154         NTSTATUS status;
1155
1156         status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1157         if (!NT_STATUS_IS_OK(status)) {
1158                 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1159                            sid_string_dbg(alias), nt_errstr(status)));
1160                 TALLOC_FREE(frame);
1161                 return NT_STATUS_NO_SUCH_ALIAS;
1162         }
1163         status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1164         if (!NT_STATUS_IS_OK(status)) {
1165                 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1166                            sid_string_dbg(member), nt_errstr(status)));
1167                 TALLOC_FREE(frame);
1168                 return status;
1169         }
1170
1171         mods = NULL;
1172
1173         if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1174                                "member", memberdn)) {
1175                 TALLOC_FREE(frame);
1176                 return NT_STATUS_NO_MEMORY;
1177         }
1178
1179         rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
1180         TALLOC_FREE(frame);
1181         if (rc != TLDAP_SUCCESS) {
1182                 DEBUG(10, ("ldap_modify failed: %s\n",
1183                            tldap_errstr(debug_ctx(), state->ld, rc)));
1184                 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1185                         return NT_STATUS_MEMBER_IN_ALIAS;
1186                 }
1187                 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1188                         return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1189                 }
1190                 return NT_STATUS_LDAP(rc);
1191         }
1192
1193         return NT_STATUS_OK;
1194 }
1195
1196 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1197                                      const DOM_SID *alias,
1198                                      const DOM_SID *member)
1199 {
1200         return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1201 }
1202
1203 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1204                                      const DOM_SID *alias,
1205                                      const DOM_SID *member)
1206 {
1207         return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1208 }
1209
1210 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1211                                struct dom_sid *psid)
1212 {
1213         const char *attrs[1] = { "objectSid" };
1214         struct tldap_message **msg;
1215         char *dn;
1216         size_t len;
1217         int rc;
1218         bool ret;
1219
1220         if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1221                                    dnblob->data, dnblob->length, &dn, &len,
1222                                    false)) {
1223                 return false;
1224         }
1225         rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1226                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1227                               &msg, "(objectclass=*)");
1228         TALLOC_FREE(dn);
1229         if (talloc_array_length(msg) != 1) {
1230                 DEBUG(10, ("Got %d objects, expected one\n",
1231                            (int)talloc_array_length(msg)));
1232                 TALLOC_FREE(msg);
1233                 return false;
1234         }
1235
1236         ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1237         TALLOC_FREE(msg);
1238         return ret;
1239 }
1240
1241 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1242                                       const DOM_SID *alias,
1243                                       TALLOC_CTX *mem_ctx,
1244                                       DOM_SID **pmembers,
1245                                       size_t *pnum_members)
1246 {
1247         struct pdb_ads_state *state = talloc_get_type_abort(
1248                 m->private_data, struct pdb_ads_state);
1249         const char *attrs[1] = { "member" };
1250         char *sidstr;
1251         struct tldap_message **msg;
1252         int i, rc, num_members;
1253         DATA_BLOB *blobs;
1254         struct dom_sid *members;
1255
1256         sidstr = sid_binstring(talloc_tos(), alias);
1257         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1258
1259         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1260                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1261                               "(objectsid=%s)", sidstr);
1262         TALLOC_FREE(sidstr);
1263         if (rc != TLDAP_SUCCESS) {
1264                 DEBUG(10, ("ldap_search failed %s\n",
1265                            tldap_errstr(debug_ctx(), state->ld, rc)));
1266                 return NT_STATUS_LDAP(rc);
1267         }
1268         switch talloc_array_length(msg) {
1269         case 0:
1270                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1271                 break;
1272         case 1:
1273                 break;
1274         default:
1275                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1276                 break;
1277         }
1278
1279         if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1280                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1281         }
1282
1283         members = talloc_array(mem_ctx, struct dom_sid, num_members);
1284         if (members == NULL) {
1285                 return NT_STATUS_NO_MEMORY;
1286         }
1287
1288         for (i=0; i<num_members; i++) {
1289                 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1290                         TALLOC_FREE(members);
1291                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1292                 }
1293         }
1294
1295         *pmembers = members;
1296         *pnum_members = num_members;
1297         return NT_STATUS_OK;
1298 }
1299
1300 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1301                                                TALLOC_CTX *mem_ctx,
1302                                                const DOM_SID *domain_sid,
1303                                                const DOM_SID *members,
1304                                                size_t num_members,
1305                                                uint32 **pp_alias_rids,
1306                                                size_t *p_num_alias_rids)
1307 {
1308         return NT_STATUS_NOT_IMPLEMENTED;
1309 }
1310
1311 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1312                                     const DOM_SID *domain_sid,
1313                                     int num_rids,
1314                                     uint32 *rids,
1315                                     const char **pp_names,
1316                                     enum lsa_SidType *attrs)
1317 {
1318         return NT_STATUS_NOT_IMPLEMENTED;
1319 }
1320
1321 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1322                                      const DOM_SID *domain_sid,
1323                                      int num_names,
1324                                      const char **pp_names,
1325                                      uint32 *rids,
1326                                      enum lsa_SidType *attrs)
1327 {
1328         return NT_STATUS_NOT_IMPLEMENTED;
1329 }
1330
1331 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1332                                            int policy_index, uint32 *value)
1333 {
1334         return account_policy_get(policy_index, value)
1335                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1336 }
1337
1338 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1339                                            int policy_index, uint32 value)
1340 {
1341         return account_policy_set(policy_index, value)
1342                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1343 }
1344
1345 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1346                                     time_t *seq_num)
1347 {
1348         return NT_STATUS_NOT_IMPLEMENTED;
1349 }
1350
1351 struct pdb_ads_search_state {
1352         uint32_t acct_flags;
1353         struct samr_displayentry *entries;
1354         uint32_t num_entries;
1355         ssize_t array_size;
1356         uint32_t current;
1357 };
1358
1359 static bool pdb_ads_next_entry(struct pdb_search *search,
1360                                struct samr_displayentry *entry)
1361 {
1362         struct pdb_ads_search_state *state = talloc_get_type_abort(
1363                 search->private_data, struct pdb_ads_search_state);
1364
1365         if (state->current == state->num_entries) {
1366                 return false;
1367         }
1368
1369         entry->idx = state->entries[state->current].idx;
1370         entry->rid = state->entries[state->current].rid;
1371         entry->acct_flags = state->entries[state->current].acct_flags;
1372
1373         entry->account_name = talloc_strdup(
1374                 search, state->entries[state->current].account_name);
1375         entry->fullname = talloc_strdup(
1376                 search, state->entries[state->current].fullname);
1377         entry->description = talloc_strdup(
1378                 search, state->entries[state->current].description);
1379
1380         if ((entry->account_name == NULL) || (entry->fullname == NULL)
1381             || (entry->description == NULL)) {
1382                 DEBUG(0, ("talloc_strdup failed\n"));
1383                 return false;
1384         }
1385
1386         state->current += 1;
1387         return true;
1388 }
1389
1390 static void pdb_ads_search_end(struct pdb_search *search)
1391 {
1392         struct pdb_ads_search_state *state = talloc_get_type_abort(
1393                 search->private_data, struct pdb_ads_search_state);
1394         TALLOC_FREE(state);
1395 }
1396
1397 static bool pdb_ads_search_filter(struct pdb_methods *m,
1398                                   struct pdb_search *search,
1399                                   const char *filter,
1400                                   struct pdb_ads_search_state **pstate)
1401 {
1402         struct pdb_ads_state *state = talloc_get_type_abort(
1403                 m->private_data, struct pdb_ads_state);
1404         struct pdb_ads_search_state *sstate;
1405         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1406                                  "userAccountControl", "description" };
1407         struct tldap_message **users;
1408         int i, rc, num_users;
1409
1410         sstate = talloc_zero(search, struct pdb_ads_search_state);
1411         if (sstate == NULL) {
1412                 return false;
1413         }
1414
1415         rc = tldap_search_fmt(
1416                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1417                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1418                 "%s", filter);
1419         if (rc != TLDAP_SUCCESS) {
1420                 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1421                            tldap_errstr(debug_ctx(), state->ld, rc)));
1422                 return false;
1423         }
1424
1425         num_users = talloc_array_length(users);
1426
1427         sstate->entries = talloc_array(sstate, struct samr_displayentry,
1428                                        num_users);
1429         if (sstate->entries == NULL) {
1430                 DEBUG(10, ("talloc failed\n"));
1431                 return false;
1432         }
1433
1434         sstate->num_entries = 0;
1435
1436         for (i=0; i<num_users; i++) {
1437                 struct samr_displayentry *e;
1438                 struct dom_sid sid;
1439
1440                 e = &sstate->entries[sstate->num_entries];
1441
1442                 e->idx = sstate->num_entries;
1443                 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1444                         DEBUG(10, ("Could not pull sid\n"));
1445                         continue;
1446                 }
1447                 sid_peek_rid(&sid, &e->rid);
1448                 e->acct_flags = ACB_NORMAL;
1449                 e->account_name = tldap_talloc_single_attribute(
1450                         users[i], "samAccountName", sstate->entries);
1451                 if (e->account_name == NULL) {
1452                         return false;
1453                 }
1454                 e->fullname = tldap_talloc_single_attribute(
1455                         users[i], "displayName", sstate->entries);
1456                 if (e->fullname == NULL) {
1457                         e->fullname = "";
1458                 }
1459                 e->description = tldap_talloc_single_attribute(
1460                         users[i], "description", sstate->entries);
1461                 if (e->description == NULL) {
1462                         e->description = "";
1463                 }
1464
1465                 sstate->num_entries += 1;
1466                 if (sstate->num_entries >= num_users) {
1467                         break;
1468                 }
1469         }
1470
1471         search->private_data = sstate;
1472         search->next_entry = pdb_ads_next_entry;
1473         search->search_end = pdb_ads_search_end;
1474         *pstate = sstate;
1475         return true;
1476 }
1477
1478 static bool pdb_ads_search_users(struct pdb_methods *m,
1479                                  struct pdb_search *search,
1480                                  uint32 acct_flags)
1481 {
1482         struct pdb_ads_search_state *sstate;
1483         bool ret;
1484
1485         ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1486         if (!ret) {
1487                 return false;
1488         }
1489         sstate->acct_flags = acct_flags;
1490         return true;
1491 }
1492
1493 static bool pdb_ads_search_groups(struct pdb_methods *m,
1494                                   struct pdb_search *search)
1495 {
1496         struct pdb_ads_search_state *sstate;
1497         char *filter;
1498         bool ret;
1499
1500         filter = talloc_asprintf(talloc_tos(),
1501                                  "(&(grouptype=%d)(objectclass=group))",
1502                                  GTYPE_SECURITY_GLOBAL_GROUP);
1503         if (filter == NULL) {
1504                 return false;
1505         }
1506         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1507         TALLOC_FREE(filter);
1508         if (!ret) {
1509                 return false;
1510         }
1511         sstate->acct_flags = 0;
1512         return true;
1513 }
1514
1515 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1516                                    struct pdb_search *search,
1517                                    const DOM_SID *sid)
1518 {
1519         struct pdb_ads_search_state *sstate;
1520         char *filter;
1521         bool ret;
1522
1523         filter = talloc_asprintf(
1524                 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1525                 sid_check_is_builtin(sid)
1526                 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1527                 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1528
1529         if (filter == NULL) {
1530                 return false;
1531         }
1532         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1533         TALLOC_FREE(filter);
1534         if (!ret) {
1535                 return false;
1536         }
1537         sstate->acct_flags = 0;
1538         return true;
1539 }
1540
1541 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1542                                uint32 *rid)
1543 {
1544         return false;
1545 }
1546
1547 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1548                                DOM_SID *sid)
1549 {
1550         struct pdb_ads_state *state = talloc_get_type_abort(
1551                 m->private_data, struct pdb_ads_state);
1552         sid_compose(sid, &state->domainsid, uid);
1553         return true;
1554 }
1555
1556 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1557                                DOM_SID *sid)
1558 {
1559         struct pdb_ads_state *state = talloc_get_type_abort(
1560                 m->private_data, struct pdb_ads_state);
1561         sid_compose(sid, &state->domainsid, gid);
1562         return true;
1563 }
1564
1565 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1566                               union unid_t *id, enum lsa_SidType *type)
1567 {
1568         struct pdb_ads_state *state = talloc_get_type_abort(
1569                 m->private_data, struct pdb_ads_state);
1570         struct tldap_message **msg;
1571         char *sidstr;
1572         uint32_t rid;
1573         int rc;
1574
1575         /*
1576          * This is a big, big hack: Just hard-code the rid as uid/gid.
1577          */
1578
1579         sid_peek_rid(sid, &rid);
1580
1581         sidstr = sid_binstring(talloc_tos(), sid);
1582         if (sidstr == NULL) {
1583                 return false;
1584         }
1585
1586         rc = tldap_search_fmt(
1587                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1588                 NULL, 0, 0, talloc_tos(), &msg,
1589                 "(&(objectsid=%s)(objectclass=user))", sidstr);
1590         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1591                 id->uid = rid;
1592                 *type = SID_NAME_USER;
1593                 TALLOC_FREE(sidstr);
1594                 return true;
1595         }
1596
1597         rc = tldap_search_fmt(
1598                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1599                 NULL, 0, 0, talloc_tos(), &msg,
1600                 "(&(objectsid=%s)(objectclass=group))", sidstr);
1601         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1602                 id->gid = rid;
1603                 *type = SID_NAME_DOM_GRP;
1604                 TALLOC_FREE(sidstr);
1605                 return true;
1606         }
1607
1608         TALLOC_FREE(sidstr);
1609         return false;
1610 }
1611
1612 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1613 {
1614         return false;
1615 }
1616
1617 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1618 {
1619         return false;
1620 }
1621
1622 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1623                                       const char *domain, char** pwd,
1624                                       DOM_SID *sid,
1625                                       time_t *pass_last_set_time)
1626 {
1627         return false;
1628 }
1629
1630 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1631                                       const char* domain, const char* pwd,
1632                                       const DOM_SID *sid)
1633 {
1634         return false;
1635 }
1636
1637 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1638                                       const char *domain)
1639 {
1640         return false;
1641 }
1642
1643 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1644                                          TALLOC_CTX *mem_ctx,
1645                                          uint32 *num_domains,
1646                                          struct trustdom_info ***domains)
1647 {
1648         return NT_STATUS_NOT_IMPLEMENTED;
1649 }
1650
1651 static void pdb_ads_init_methods(struct pdb_methods *m)
1652 {
1653         m->name = "ads";
1654         m->getsampwnam = pdb_ads_getsampwnam;
1655         m->getsampwsid = pdb_ads_getsampwsid;
1656         m->create_user = pdb_ads_create_user;
1657         m->delete_user = pdb_ads_delete_user;
1658         m->add_sam_account = pdb_ads_add_sam_account;
1659         m->update_sam_account = pdb_ads_update_sam_account;
1660         m->delete_sam_account = pdb_ads_delete_sam_account;
1661         m->rename_sam_account = pdb_ads_rename_sam_account;
1662         m->update_login_attempts = pdb_ads_update_login_attempts;
1663         m->getgrsid = pdb_ads_getgrsid;
1664         m->getgrgid = pdb_ads_getgrgid;
1665         m->getgrnam = pdb_ads_getgrnam;
1666         m->create_dom_group = pdb_ads_create_dom_group;
1667         m->delete_dom_group = pdb_ads_delete_dom_group;
1668         m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1669         m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1670         m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1671         m->enum_group_mapping = pdb_ads_enum_group_mapping;
1672         m->enum_group_members = pdb_ads_enum_group_members;
1673         m->enum_group_memberships = pdb_ads_enum_group_memberships;
1674         m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1675         m->add_groupmem = pdb_ads_add_groupmem;
1676         m->del_groupmem = pdb_ads_del_groupmem;
1677         m->create_alias = pdb_ads_create_alias;
1678         m->delete_alias = pdb_ads_delete_alias;
1679         m->get_aliasinfo = pdb_ads_get_aliasinfo;
1680         m->set_aliasinfo = pdb_ads_set_aliasinfo;
1681         m->add_aliasmem = pdb_ads_add_aliasmem;
1682         m->del_aliasmem = pdb_ads_del_aliasmem;
1683         m->enum_aliasmem = pdb_ads_enum_aliasmem;
1684         m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1685         m->lookup_rids = pdb_ads_lookup_rids;
1686         m->lookup_names = pdb_ads_lookup_names;
1687         m->get_account_policy = pdb_ads_get_account_policy;
1688         m->set_account_policy = pdb_ads_set_account_policy;
1689         m->get_seq_num = pdb_ads_get_seq_num;
1690         m->search_users = pdb_ads_search_users;
1691         m->search_groups = pdb_ads_search_groups;
1692         m->search_aliases = pdb_ads_search_aliases;
1693         m->uid_to_rid = pdb_ads_uid_to_rid;
1694         m->uid_to_sid = pdb_ads_uid_to_sid;
1695         m->gid_to_sid = pdb_ads_gid_to_sid;
1696         m->sid_to_id = pdb_ads_sid_to_id;
1697         m->rid_algorithm = pdb_ads_rid_algorithm;
1698         m->new_rid = pdb_ads_new_rid;
1699         m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1700         m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1701         m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1702         m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1703 }
1704
1705 static void free_private_data(void **vp)
1706 {
1707         struct pdb_ads_state *state = talloc_get_type_abort(
1708                 *vp, struct pdb_ads_state);
1709
1710         TALLOC_FREE(state->ld);
1711         return;
1712 }
1713
1714 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1715                                 const char *location)
1716 {
1717         const char *rootdse_attrs[2] = {
1718                 "defaultNamingContext", "configurationNamingContext" };
1719         const char *domain_attrs[1] = { "objectSid" };
1720         const char *ncname_attrs[1] = { "netbiosname" };
1721         struct tldap_message **rootdse, **domain, **ncname;
1722         TALLOC_CTX *frame = talloc_stackframe();
1723         struct sockaddr_un sunaddr;
1724         NTSTATUS status;
1725         int num_domains;
1726         int fd, rc;
1727
1728         ZERO_STRUCT(sunaddr);
1729         sunaddr.sun_family = AF_UNIX;
1730         strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1731
1732         status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1733                                  0, 0, &fd);
1734         if (!NT_STATUS_IS_OK(status)) {
1735                 DEBUG(10, ("Could not connect to %s: %s\n", location,
1736                            nt_errstr(status)));
1737                 goto done;
1738         }
1739
1740         state->ld = tldap_context_create(state, fd);
1741         if (state->ld == NULL) {
1742                 close(fd);
1743                 status = NT_STATUS_NO_MEMORY;
1744                 goto done;
1745         }
1746
1747         rc = tldap_search_fmt(
1748                 state->ld, "", TLDAP_SCOPE_BASE,
1749                 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1750                 talloc_tos(), &rootdse, "(objectclass=*)");
1751         if (rc != TLDAP_SUCCESS) {
1752                 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1753                            tldap_errstr(debug_ctx(), state->ld, rc)));
1754                 status = NT_STATUS_LDAP(rc);
1755                 goto done;
1756         }
1757         if (talloc_array_length(rootdse) != 1) {
1758                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1759                 goto done;
1760         }
1761
1762         state->domaindn = tldap_talloc_single_attribute(
1763                 rootdse[0], "defaultNamingContext", state);
1764         if (state->domaindn == NULL) {
1765                 DEBUG(10, ("Could not get defaultNamingContext\n"));
1766                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1767                 goto done;
1768         }
1769         DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1770
1771         state->configdn = tldap_talloc_single_attribute(
1772                 rootdse[0], "configurationNamingContext", state);
1773         if (state->domaindn == NULL) {
1774                 DEBUG(10, ("Could not get configurationNamingContext\n"));
1775                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1776                 goto done;
1777         }
1778         DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1779
1780         /*
1781          * Figure out our domain's SID
1782          */
1783         rc = tldap_search_fmt(
1784                 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1785                 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1786                 talloc_tos(), &domain, "(objectclass=*)");
1787         if (rc != TLDAP_SUCCESS) {
1788                 DEBUG(10, ("Could not retrieve domain: %s\n",
1789                            tldap_errstr(debug_ctx(), state->ld, rc)));
1790                 status = NT_STATUS_LDAP(rc);
1791                 goto done;
1792         }
1793
1794         num_domains = talloc_array_length(domain);
1795         if (num_domains != 1) {
1796                 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1797                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1798                 goto done;
1799         }
1800         if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1801                 DEBUG(10, ("Could not retrieve domain SID\n"));
1802                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1803                 goto done;
1804         }
1805         DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1806
1807         /*
1808          * Figure out our domain's short name
1809          */
1810         rc = tldap_search_fmt(
1811                 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1812                 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1813                 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1814         if (rc != TLDAP_SUCCESS) {
1815                 DEBUG(10, ("Could not retrieve ncname: %s\n",
1816                            tldap_errstr(debug_ctx(), state->ld, rc)));
1817                 status = NT_STATUS_LDAP(rc);
1818                 goto done;
1819         }
1820         if (talloc_array_length(ncname) != 1) {
1821                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1822                 goto done;
1823         }
1824
1825         state->netbiosname = tldap_talloc_single_attribute(
1826                 ncname[0], "netbiosname", state);
1827         if (state->netbiosname == NULL) {
1828                 DEBUG(10, ("Could not get netbiosname\n"));
1829                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1830                 goto done;
1831         }
1832         DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1833
1834         if (!strequal(lp_workgroup(), state->netbiosname)) {
1835                 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1836                           state->netbiosname, lp_workgroup()));
1837                 status = NT_STATUS_NO_SUCH_DOMAIN;
1838                 goto done;
1839         }
1840
1841         secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1842
1843         status = NT_STATUS_OK;
1844 done:
1845         TALLOC_FREE(frame);
1846         return status;
1847 }
1848
1849 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1850                              const char *location)
1851 {
1852         struct pdb_methods *m;
1853         struct pdb_ads_state *state;
1854         char *tmp = NULL;
1855         NTSTATUS status;
1856
1857         m = talloc(talloc_autofree_context(), struct pdb_methods);
1858         if (m == NULL) {
1859                 return NT_STATUS_NO_MEMORY;
1860         }
1861         state = talloc(m, struct pdb_ads_state);
1862         if (state == NULL) {
1863                 goto nomem;
1864         }
1865         m->private_data = state;
1866         m->free_private_data = free_private_data;
1867         pdb_ads_init_methods(m);
1868
1869         if (location == NULL) {
1870                 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1871                                       lp_private_dir());
1872                 location = tmp;
1873         }
1874         if (location == NULL) {
1875                 goto nomem;
1876         }
1877
1878         status = pdb_ads_connect(state, location);
1879         if (!NT_STATUS_IS_OK(status)) {
1880                 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1881                 goto fail;
1882         }
1883
1884         *pdb_method = m;
1885         return NT_STATUS_OK;
1886 nomem:
1887         status = NT_STATUS_NO_MEMORY;
1888 fail:
1889         TALLOC_FREE(m);
1890         return status;
1891 }
1892
1893 NTSTATUS pdb_ads_init(void);
1894 NTSTATUS pdb_ads_init(void)
1895 {
1896         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
1897                                    pdb_init_ads);
1898 }