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