Make "net sam list" work for groups, aliases and builtins
[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 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
23                                     struct samu *sam_acct,
24                                     const DOM_SID *sid);
25
26 struct pdb_ads_state {
27         struct tldap_context *ld;
28         struct dom_sid domainsid;
29         char *domaindn;
30         char *configdn;
31         char *netbiosname;
32 };
33
34 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
35                               time_t *ptime)
36 {
37         uint64_t tmp;
38
39         if (!tldap_pull_uint64(msg, attr, &tmp)) {
40                 return false;
41         }
42         *ptime = uint64s_nt_time_to_unix_abs(&tmp);
43         return true;
44 }
45
46 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
47 {
48         uint32_t rid;
49         sid_peek_rid(sid, &rid);
50         return rid;
51 }
52
53 struct pdb_ads_samu_private {
54         char *dn;
55         struct tldap_message *ldapmsg;
56 };
57
58 static struct samu *pdb_ads_init_guest(TALLOC_CTX *mem_ctx,
59                                        struct pdb_methods *m)
60 {
61         struct pdb_ads_state *state = talloc_get_type_abort(
62                 m->private_data, struct pdb_ads_state);
63         struct dom_sid guest_sid;
64         struct samu *guest;
65         NTSTATUS status;
66
67         sid_compose(&guest_sid, &state->domainsid, DOMAIN_USER_RID_GUEST);
68
69         guest = samu_new(mem_ctx);
70         if (guest == NULL) {
71                 return NULL;
72         }
73
74         status = pdb_ads_getsampwsid(m, guest, &guest_sid);
75         if (!NT_STATUS_IS_OK(status)) {
76                 DEBUG(10, ("Could not init guest account: %s\n",
77                            nt_errstr(status)));
78                 TALLOC_FREE(guest);
79                 return NULL;
80         }
81         return guest;
82 }
83
84 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
85         struct pdb_methods *m, struct samu *sam)
86 {
87         struct pdb_ads_samu_private *result;
88         uint32_t rid;
89
90         result = (struct pdb_ads_samu_private *)
91                 pdb_get_backend_private_data(sam, m);
92
93         if (result != NULL) {
94                 return talloc_get_type_abort(
95                         result, struct pdb_ads_samu_private);
96         }
97
98         /*
99          * This is now a weirdness of the passdb API. For the guest user we
100          * are not asked first.
101          */
102         sid_peek_rid(pdb_get_user_sid(sam), &rid);
103
104         if (rid == DOMAIN_USER_RID_GUEST) {
105                 struct samu *guest = pdb_ads_init_guest(talloc_tos(), m);
106
107                 if (guest == NULL) {
108                         return NULL;
109                 }
110                 result = talloc_get_type_abort(
111                         pdb_get_backend_private_data(guest, m),
112                         struct pdb_ads_samu_private);
113                 pdb_set_backend_private_data(
114                         sam, talloc_move(sam, &result), NULL, m, PDB_SET);
115                 TALLOC_FREE(guest);
116                 return talloc_get_type_abort(
117                         pdb_get_backend_private_data(sam, m),
118                         struct pdb_ads_samu_private);
119         }
120
121         return NULL;
122 }
123
124 static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m,
125                                           struct samu *sam,
126                                           struct tldap_message *entry)
127 {
128         struct pdb_ads_state *state = talloc_get_type_abort(
129                 m->private_data, struct pdb_ads_state);
130         TALLOC_CTX *frame = talloc_stackframe();
131         struct pdb_ads_samu_private *priv;
132         NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
133         char *str;
134         time_t tmp_time;
135         struct dom_sid sid;
136         uint64_t n;
137         DATA_BLOB blob;
138
139         priv = talloc(sam, struct pdb_ads_samu_private);
140         if (priv == NULL) {
141                 return NT_STATUS_NO_MEMORY;
142         }
143         if (!tldap_entry_dn(entry, &priv->dn)) {
144                 TALLOC_FREE(priv);
145                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
146         }
147
148         str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
149         if (str == NULL) {
150                 DEBUG(10, ("no samAccountName\n"));
151                 goto fail;
152         }
153         pdb_set_username(sam, str, PDB_SET);
154         TALLOC_FREE(str);
155
156         if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
157                 pdb_set_logon_time(sam, tmp_time, PDB_SET);
158         }
159         if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
160                 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
161         }
162         if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
163                 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
164         }
165         if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
166                 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
167         }
168
169         str = tldap_talloc_single_attribute(entry, "samAccoutName",
170                                             talloc_tos());
171         if (str != NULL) {
172                 pdb_set_username(sam, str, 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                 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, 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_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
491                                  DOM_SID sid)
492 {
493         return NT_STATUS_NOT_IMPLEMENTED;
494 }
495
496 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
497                                  gid_t gid)
498 {
499         return NT_STATUS_NOT_IMPLEMENTED;
500 }
501
502 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
503                                  const char *name)
504 {
505         return NT_STATUS_NOT_IMPLEMENTED;
506 }
507
508 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
509                                          TALLOC_CTX *mem_ctx, const char *name,
510                                          uint32 *rid)
511 {
512         return NT_STATUS_NOT_IMPLEMENTED;
513 }
514
515 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
516                                          TALLOC_CTX *mem_ctx, uint32 rid)
517 {
518         return NT_STATUS_NOT_IMPLEMENTED;
519 }
520
521 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
522                                                 GROUP_MAP *map)
523 {
524         return NT_STATUS_NOT_IMPLEMENTED;
525 }
526
527 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
528                                                    GROUP_MAP *map)
529 {
530         return NT_STATUS_NOT_IMPLEMENTED;
531 }
532
533 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
534                                                    DOM_SID sid)
535 {
536         return NT_STATUS_NOT_IMPLEMENTED;
537 }
538
539 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
540                                            const DOM_SID *sid,
541                                            enum lsa_SidType sid_name_use,
542                                            GROUP_MAP **pp_rmap,
543                                            size_t *p_num_entries,
544                                            bool unix_only)
545 {
546         return NT_STATUS_NOT_IMPLEMENTED;
547 }
548
549 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
550                                            TALLOC_CTX *mem_ctx,
551                                            const DOM_SID *group,
552                                            uint32 **pp_member_rids,
553                                            size_t *p_num_members)
554 {
555         return NT_STATUS_NOT_IMPLEMENTED;
556 }
557
558 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
559                                                TALLOC_CTX *mem_ctx,
560                                                struct samu *user,
561                                                DOM_SID **pp_sids,
562                                                gid_t **pp_gids,
563                                                size_t *p_num_groups)
564 {
565         struct pdb_ads_state *state = talloc_get_type_abort(
566                 m->private_data, struct pdb_ads_state);
567         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
568                 m, user);
569         const char *attrs[1] = { "objectSid" };
570         struct tldap_message **groups;
571         int i, rc, count;
572         size_t num_groups;
573         struct dom_sid *group_sids;
574         gid_t *gids;
575
576         rc = tldap_search_fmt(
577                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
578                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
579                 "(&(member=%s)(grouptype=%d)(objectclass=group))",
580                 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
581         if (rc != TLDAP_SUCCESS) {
582                 DEBUG(10, ("ldap_search failed %s\n",
583                            tldap_errstr(debug_ctx(), state->ld, rc)));
584                 return NT_STATUS_LDAP(rc);
585         }
586
587         count = talloc_array_length(groups);
588
589         group_sids = talloc_array(mem_ctx, struct dom_sid, count);
590         if (group_sids == NULL) {
591                 return NT_STATUS_NO_MEMORY;
592         }
593         gids = talloc_array(mem_ctx, gid_t, count);
594         if (gids == NULL) {
595                 TALLOC_FREE(group_sids);
596                 return NT_STATUS_NO_MEMORY;
597         }
598         num_groups = 0;
599
600         for (i=0; i<count; i++) {
601                 if (!tldap_pull_binsid(groups[i], "objectSid",
602                                        &group_sids[num_groups])) {
603                         continue;
604                 }
605                 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
606
607                 num_groups += 1;
608                 if (num_groups == count) {
609                         break;
610                 }
611         }
612
613         *pp_sids = group_sids;
614         *pp_gids = gids;
615         *p_num_groups = num_groups;
616         return NT_STATUS_OK;
617 }
618
619 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
620                                                TALLOC_CTX *mem_ctx,
621                                                struct samu *user)
622 {
623         return NT_STATUS_NOT_IMPLEMENTED;
624 }
625
626 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
627                                      TALLOC_CTX *mem_ctx,
628                                      uint32 group_rid, uint32 member_rid)
629 {
630         return NT_STATUS_NOT_IMPLEMENTED;
631 }
632
633 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
634                                      TALLOC_CTX *mem_ctx,
635                                      uint32 group_rid, uint32 member_rid)
636 {
637         return NT_STATUS_NOT_IMPLEMENTED;
638 }
639
640 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
641                                      const char *name, uint32 *rid)
642 {
643         TALLOC_CTX *frame = talloc_stackframe();
644         struct pdb_ads_state *state = talloc_get_type_abort(
645                 m->private_data, struct pdb_ads_state);
646         const char *attrs[1] = { "objectSid" };
647         int num_mods = 0;
648         struct tldap_mod *mods = NULL;
649         struct tldap_message **alias;
650         struct dom_sid sid;
651         char *dn;
652         int rc;
653         bool ok = true;
654
655         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
656                              state->domaindn);
657         if (dn == NULL) {
658                 TALLOC_FREE(frame);
659                 return NT_STATUS_NO_MEMORY;
660         }
661
662         ok &= tldap_make_mod_fmt(
663                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
664                 name);
665         ok &= tldap_make_mod_fmt(
666                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
667         ok &= tldap_make_mod_fmt(
668                 NULL, talloc_tos(), &num_mods, &mods, "groupType",
669                 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
670
671         if (!ok) {
672                 TALLOC_FREE(frame);
673                 return NT_STATUS_NO_MEMORY;
674         }
675
676         rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
677         if (rc != TLDAP_SUCCESS) {
678                 DEBUG(10, ("ldap_add failed %s\n",
679                            tldap_errstr(debug_ctx(), state->ld, rc)));
680                 TALLOC_FREE(frame);
681                 return NT_STATUS_LDAP(rc);
682         }
683
684         rc = tldap_search_fmt(
685                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
686                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
687                 "(&(objectclass=group)(samaccountname=%s))", name);
688         if (rc != TLDAP_SUCCESS) {
689                 DEBUG(10, ("Could not find just created alias %s: %s\n",
690                            name, tldap_errstr(debug_ctx(), state->ld, rc)));
691                 TALLOC_FREE(frame);
692                 return NT_STATUS_LDAP(rc);
693         }
694
695         if (talloc_array_length(alias) != 1) {
696                 DEBUG(10, ("Got %d alias, expected one\n",
697                            (int)talloc_array_length(alias)));
698                 TALLOC_FREE(frame);
699                 return NT_STATUS_LDAP(rc);
700         }
701
702         if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
703                 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
704                            name));
705                 TALLOC_FREE(frame);
706                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
707         }
708
709         sid_peek_rid(&sid, rid);
710         TALLOC_FREE(frame);
711         return NT_STATUS_OK;
712 }
713
714 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
715                                      const DOM_SID *sid)
716 {
717         return NT_STATUS_NOT_IMPLEMENTED;
718 }
719
720 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
721                                       const DOM_SID *sid,
722                                       struct acct_info *info)
723 {
724         return NT_STATUS_NOT_IMPLEMENTED;
725 }
726
727 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
728                                       const DOM_SID *sid,
729                                       struct acct_info *info)
730 {
731         return NT_STATUS_NOT_IMPLEMENTED;
732 }
733
734 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
735                                      const DOM_SID *alias,
736                                      const DOM_SID *member)
737 {
738         return NT_STATUS_NOT_IMPLEMENTED;
739 }
740
741 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
742                                      const DOM_SID *alias,
743                                      const DOM_SID *member)
744 {
745         return NT_STATUS_NOT_IMPLEMENTED;
746 }
747
748 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
749                                       const DOM_SID *alias, DOM_SID **members,
750                                       size_t *p_num_members)
751 {
752         return NT_STATUS_NOT_IMPLEMENTED;
753 }
754
755 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
756                                                TALLOC_CTX *mem_ctx,
757                                                const DOM_SID *domain_sid,
758                                                const DOM_SID *members,
759                                                size_t num_members,
760                                                uint32 **pp_alias_rids,
761                                                size_t *p_num_alias_rids)
762 {
763         return NT_STATUS_NOT_IMPLEMENTED;
764 }
765
766 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
767                                     const DOM_SID *domain_sid,
768                                     int num_rids,
769                                     uint32 *rids,
770                                     const char **pp_names,
771                                     enum lsa_SidType *attrs)
772 {
773         return NT_STATUS_NOT_IMPLEMENTED;
774 }
775
776 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
777                                      const DOM_SID *domain_sid,
778                                      int num_names,
779                                      const char **pp_names,
780                                      uint32 *rids,
781                                      enum lsa_SidType *attrs)
782 {
783         return NT_STATUS_NOT_IMPLEMENTED;
784 }
785
786 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
787                                            int policy_index, uint32 *value)
788 {
789         return account_policy_get(policy_index, value)
790                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
791 }
792
793 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
794                                            int policy_index, uint32 value)
795 {
796         return account_policy_set(policy_index, value)
797                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
798 }
799
800 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
801                                     time_t *seq_num)
802 {
803         return NT_STATUS_NOT_IMPLEMENTED;
804 }
805
806 struct pdb_ads_search_state {
807         uint32_t acct_flags;
808         struct samr_displayentry *entries;
809         uint32_t num_entries;
810         ssize_t array_size;
811         uint32_t current;
812 };
813
814 static bool pdb_ads_next_entry(struct pdb_search *search,
815                                struct samr_displayentry *entry)
816 {
817         struct pdb_ads_search_state *state = talloc_get_type_abort(
818                 search->private_data, struct pdb_ads_search_state);
819
820         if (state->current == state->num_entries) {
821                 return false;
822         }
823
824         entry->idx = state->entries[state->current].idx;
825         entry->rid = state->entries[state->current].rid;
826         entry->acct_flags = state->entries[state->current].acct_flags;
827
828         entry->account_name = talloc_strdup(
829                 search, state->entries[state->current].account_name);
830         entry->fullname = talloc_strdup(
831                 search, state->entries[state->current].fullname);
832         entry->description = talloc_strdup(
833                 search, state->entries[state->current].description);
834
835         if ((entry->account_name == NULL) || (entry->fullname == NULL)
836             || (entry->description == NULL)) {
837                 DEBUG(0, ("talloc_strdup failed\n"));
838                 return false;
839         }
840
841         state->current += 1;
842         return true;
843 }
844
845 static void pdb_ads_search_end(struct pdb_search *search)
846 {
847         struct pdb_ads_search_state *state = talloc_get_type_abort(
848                 search->private_data, struct pdb_ads_search_state);
849         TALLOC_FREE(state);
850 }
851
852 static bool pdb_ads_search_filter(struct pdb_methods *m,
853                                   struct pdb_search *search,
854                                   const char *filter,
855                                   struct pdb_ads_search_state **pstate)
856 {
857         struct pdb_ads_state *state = talloc_get_type_abort(
858                 m->private_data, struct pdb_ads_state);
859         struct pdb_ads_search_state *sstate;
860         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
861                                  "userAccountControl", "description" };
862         struct tldap_message **users;
863         int i, rc, num_users;
864
865         sstate = talloc_zero(search, struct pdb_ads_search_state);
866         if (sstate == NULL) {
867                 return false;
868         }
869
870         rc = tldap_search_fmt(
871                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
872                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
873                 "%s", filter);
874         if (rc != TLDAP_SUCCESS) {
875                 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
876                            tldap_errstr(debug_ctx(), state->ld, rc)));
877                 return false;
878         }
879
880         num_users = talloc_array_length(users);
881
882         sstate->entries = talloc_array(sstate, struct samr_displayentry,
883                                        num_users);
884         if (sstate->entries == NULL) {
885                 DEBUG(10, ("talloc failed\n"));
886                 return false;
887         }
888
889         sstate->num_entries = 0;
890
891         for (i=0; i<num_users; i++) {
892                 struct samr_displayentry *e;
893                 struct dom_sid sid;
894
895                 e = &sstate->entries[sstate->num_entries];
896
897                 e->idx = sstate->num_entries;
898                 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
899                         DEBUG(10, ("Could not pull sid\n"));
900                         continue;
901                 }
902                 sid_peek_rid(&sid, &e->rid);
903                 e->acct_flags = ACB_NORMAL;
904                 e->account_name = tldap_talloc_single_attribute(
905                         users[i], "samAccountName", sstate->entries);
906                 if (e->account_name == NULL) {
907                         return false;
908                 }
909                 e->fullname = tldap_talloc_single_attribute(
910                         users[i], "displayName", sstate->entries);
911                 if (e->fullname == NULL) {
912                         e->fullname = "";
913                 }
914                 e->description = tldap_talloc_single_attribute(
915                         users[i], "description", sstate->entries);
916                 if (e->description == NULL) {
917                         e->description = "";
918                 }
919
920                 sstate->num_entries += 1;
921                 if (sstate->num_entries >= num_users) {
922                         break;
923                 }
924         }
925
926         search->private_data = sstate;
927         search->next_entry = pdb_ads_next_entry;
928         search->search_end = pdb_ads_search_end;
929         *pstate = sstate;
930         return true;
931 }
932
933 static bool pdb_ads_search_users(struct pdb_methods *m,
934                                  struct pdb_search *search,
935                                  uint32 acct_flags)
936 {
937         struct pdb_ads_search_state *sstate;
938         bool ret;
939
940         ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
941         if (!ret) {
942                 return false;
943         }
944         sstate->acct_flags = acct_flags;
945         return true;
946 }
947
948 static bool pdb_ads_search_groups(struct pdb_methods *m,
949                                   struct pdb_search *search)
950 {
951         struct pdb_ads_search_state *sstate;
952         char *filter;
953         bool ret;
954
955         filter = talloc_asprintf(talloc_tos(),
956                                  "(&(grouptype=%d)(objectclass=group))",
957                                  GTYPE_SECURITY_GLOBAL_GROUP);
958         if (filter == NULL) {
959                 return false;
960         }
961         ret = pdb_ads_search_filter(m, search, filter, &sstate);
962         TALLOC_FREE(filter);
963         if (!ret) {
964                 return false;
965         }
966         sstate->acct_flags = 0;
967         return true;
968 }
969
970 static bool pdb_ads_search_aliases(struct pdb_methods *m,
971                                    struct pdb_search *search,
972                                    const DOM_SID *sid)
973 {
974         struct pdb_ads_search_state *sstate;
975         char *filter;
976         bool ret;
977
978         filter = talloc_asprintf(
979                 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
980                 sid_check_is_builtin(sid)
981                 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
982                 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
983
984         if (filter == NULL) {
985                 return false;
986         }
987         ret = pdb_ads_search_filter(m, search, filter, &sstate);
988         TALLOC_FREE(filter);
989         if (!ret) {
990                 return false;
991         }
992         sstate->acct_flags = 0;
993         return true;
994 }
995
996 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
997                                uint32 *rid)
998 {
999         return false;
1000 }
1001
1002 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1003                                DOM_SID *sid)
1004 {
1005         return false;
1006 }
1007
1008 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1009                                DOM_SID *sid)
1010 {
1011         return false;
1012 }
1013
1014 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1015                               union unid_t *id, enum lsa_SidType *type)
1016 {
1017         struct pdb_ads_state *state = talloc_get_type_abort(
1018                 m->private_data, struct pdb_ads_state);
1019         struct tldap_message **msg;
1020         char *sidstr;
1021         uint32_t rid;
1022         int rc;
1023
1024         /*
1025          * This is a big, big hack: Just hard-code the rid as uid/gid.
1026          */
1027
1028         sid_peek_rid(sid, &rid);
1029
1030         sidstr = sid_binstring(talloc_tos(), sid);
1031         if (sidstr == NULL) {
1032                 return false;
1033         }
1034
1035         rc = tldap_search_fmt(
1036                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1037                 NULL, 0, 0, talloc_tos(), &msg,
1038                 "(&(objectsid=%s)(objectclass=user))", sidstr);
1039         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1040                 id->uid = rid;
1041                 *type = SID_NAME_USER;
1042                 TALLOC_FREE(sidstr);
1043                 return true;
1044         }
1045
1046         rc = tldap_search_fmt(
1047                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1048                 NULL, 0, 0, talloc_tos(), &msg,
1049                 "(&(objectsid=%s)(objectclass=group))", sidstr);
1050         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1051                 id->gid = rid;
1052                 *type = SID_NAME_DOM_GRP;
1053                 TALLOC_FREE(sidstr);
1054                 return true;
1055         }
1056
1057         TALLOC_FREE(sidstr);
1058         return false;
1059 }
1060
1061 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1062 {
1063         return false;
1064 }
1065
1066 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1067 {
1068         return false;
1069 }
1070
1071 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1072                                       const char *domain, char** pwd,
1073                                       DOM_SID *sid,
1074                                       time_t *pass_last_set_time)
1075 {
1076         return false;
1077 }
1078
1079 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1080                                       const char* domain, const char* pwd,
1081                                       const DOM_SID *sid)
1082 {
1083         return false;
1084 }
1085
1086 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1087                                       const char *domain)
1088 {
1089         return false;
1090 }
1091
1092 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1093                                          TALLOC_CTX *mem_ctx,
1094                                          uint32 *num_domains,
1095                                          struct trustdom_info ***domains)
1096 {
1097         return NT_STATUS_NOT_IMPLEMENTED;
1098 }
1099
1100 static void pdb_ads_init_methods(struct pdb_methods *m)
1101 {
1102         m->name = "ads";
1103         m->getsampwnam = pdb_ads_getsampwnam;
1104         m->getsampwsid = pdb_ads_getsampwsid;
1105         m->create_user = pdb_ads_create_user;
1106         m->delete_user = pdb_ads_delete_user;
1107         m->add_sam_account = pdb_ads_add_sam_account;
1108         m->update_sam_account = pdb_ads_update_sam_account;
1109         m->delete_sam_account = pdb_ads_delete_sam_account;
1110         m->rename_sam_account = pdb_ads_rename_sam_account;
1111         m->update_login_attempts = pdb_ads_update_login_attempts;
1112         m->getgrsid = pdb_ads_getgrsid;
1113         m->getgrgid = pdb_ads_getgrgid;
1114         m->getgrnam = pdb_ads_getgrnam;
1115         m->create_dom_group = pdb_ads_create_dom_group;
1116         m->delete_dom_group = pdb_ads_delete_dom_group;
1117         m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1118         m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1119         m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1120         m->enum_group_mapping = pdb_ads_enum_group_mapping;
1121         m->enum_group_members = pdb_ads_enum_group_members;
1122         m->enum_group_memberships = pdb_ads_enum_group_memberships;
1123         m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1124         m->add_groupmem = pdb_ads_add_groupmem;
1125         m->del_groupmem = pdb_ads_del_groupmem;
1126         m->create_alias = pdb_ads_create_alias;
1127         m->delete_alias = pdb_ads_delete_alias;
1128         m->get_aliasinfo = pdb_ads_get_aliasinfo;
1129         m->set_aliasinfo = pdb_ads_set_aliasinfo;
1130         m->add_aliasmem = pdb_ads_add_aliasmem;
1131         m->del_aliasmem = pdb_ads_del_aliasmem;
1132         m->enum_aliasmem = pdb_ads_enum_aliasmem;
1133         m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1134         m->lookup_rids = pdb_ads_lookup_rids;
1135         m->lookup_names = pdb_ads_lookup_names;
1136         m->get_account_policy = pdb_ads_get_account_policy;
1137         m->set_account_policy = pdb_ads_set_account_policy;
1138         m->get_seq_num = pdb_ads_get_seq_num;
1139         m->search_users = pdb_ads_search_users;
1140         m->search_groups = pdb_ads_search_groups;
1141         m->search_aliases = pdb_ads_search_aliases;
1142         m->uid_to_rid = pdb_ads_uid_to_rid;
1143         m->uid_to_sid = pdb_ads_uid_to_sid;
1144         m->gid_to_sid = pdb_ads_gid_to_sid;
1145         m->sid_to_id = pdb_ads_sid_to_id;
1146         m->rid_algorithm = pdb_ads_rid_algorithm;
1147         m->new_rid = pdb_ads_new_rid;
1148         m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1149         m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1150         m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1151         m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1152 }
1153
1154 static void free_private_data(void **vp)
1155 {
1156         struct pdb_ads_state *state = talloc_get_type_abort(
1157                 *vp, struct pdb_ads_state);
1158
1159         TALLOC_FREE(state->ld);
1160         return;
1161 }
1162
1163 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1164                                 const char *location)
1165 {
1166         const char *rootdse_attrs[2] = {
1167                 "defaultNamingContext", "configurationNamingContext" };
1168         const char *domain_attrs[1] = { "objectSid" };
1169         const char *ncname_attrs[1] = { "netbiosname" };
1170         struct tldap_message **rootdse, **domain, **ncname;
1171         TALLOC_CTX *frame = talloc_stackframe();
1172         struct sockaddr_un sunaddr;
1173         NTSTATUS status;
1174         int num_domains;
1175         int fd, rc;
1176
1177         ZERO_STRUCT(sunaddr);
1178         sunaddr.sun_family = AF_UNIX;
1179         strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1180
1181         status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1182                                  0, 0, &fd);
1183         if (!NT_STATUS_IS_OK(status)) {
1184                 DEBUG(10, ("Could not connect to %s: %s\n", location,
1185                            nt_errstr(status)));
1186                 goto done;
1187         }
1188
1189         state->ld = tldap_context_create(state, fd);
1190         if (state->ld == NULL) {
1191                 close(fd);
1192                 status = NT_STATUS_NO_MEMORY;
1193                 goto done;
1194         }
1195
1196         rc = tldap_search_fmt(
1197                 state->ld, "", TLDAP_SCOPE_BASE,
1198                 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1199                 talloc_tos(), &rootdse, "(objectclass=*)");
1200         if (rc != TLDAP_SUCCESS) {
1201                 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1202                            tldap_errstr(debug_ctx(), state->ld, rc)));
1203                 status = NT_STATUS_LDAP(rc);
1204                 goto done;
1205         }
1206         if (talloc_array_length(rootdse) != 1) {
1207                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1208                 goto done;
1209         }
1210
1211         state->domaindn = tldap_talloc_single_attribute(
1212                 rootdse[0], "defaultNamingContext", state);
1213         if (state->domaindn == NULL) {
1214                 DEBUG(10, ("Could not get defaultNamingContext\n"));
1215                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1216                 goto done;
1217         }
1218         DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1219
1220         state->configdn = tldap_talloc_single_attribute(
1221                 rootdse[0], "configurationNamingContext", state);
1222         if (state->domaindn == NULL) {
1223                 DEBUG(10, ("Could not get configurationNamingContext\n"));
1224                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1225                 goto done;
1226         }
1227         DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1228
1229         /*
1230          * Figure out our domain's SID
1231          */
1232         rc = tldap_search_fmt(
1233                 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1234                 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1235                 talloc_tos(), &domain, "(objectclass=*)");
1236         if (rc != TLDAP_SUCCESS) {
1237                 DEBUG(10, ("Could not retrieve domain: %s\n",
1238                            tldap_errstr(debug_ctx(), state->ld, rc)));
1239                 status = NT_STATUS_LDAP(rc);
1240                 goto done;
1241         }
1242
1243         num_domains = talloc_array_length(domain);
1244         if (num_domains != 1) {
1245                 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1246                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1247                 goto done;
1248         }
1249         if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1250                 DEBUG(10, ("Could not retrieve domain SID\n"));
1251                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1252                 goto done;
1253         }
1254         DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1255
1256         /*
1257          * Figure out our domain's short name
1258          */
1259         rc = tldap_search_fmt(
1260                 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1261                 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1262                 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1263         if (rc != TLDAP_SUCCESS) {
1264                 DEBUG(10, ("Could not retrieve ncname: %s\n",
1265                            tldap_errstr(debug_ctx(), state->ld, rc)));
1266                 status = NT_STATUS_LDAP(rc);
1267                 goto done;
1268         }
1269         if (talloc_array_length(ncname) != 1) {
1270                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1271                 goto done;
1272         }
1273
1274         state->netbiosname = tldap_talloc_single_attribute(
1275                 ncname[0], "netbiosname", state);
1276         if (state->netbiosname == NULL) {
1277                 DEBUG(10, ("Could not get netbiosname\n"));
1278                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1279                 goto done;
1280         }
1281         DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1282
1283         if (!strequal(lp_workgroup(), state->netbiosname)) {
1284                 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1285                           state->netbiosname, lp_workgroup()));
1286                 status = NT_STATUS_NO_SUCH_DOMAIN;
1287                 goto done;
1288         }
1289
1290         secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1291
1292         status = NT_STATUS_OK;
1293 done:
1294         TALLOC_FREE(frame);
1295         return status;
1296 }
1297
1298 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1299                              const char *location)
1300 {
1301         struct pdb_methods *m;
1302         struct pdb_ads_state *state;
1303         char *tmp = NULL;
1304         NTSTATUS status;
1305
1306         m = talloc(talloc_autofree_context(), struct pdb_methods);
1307         if (m == NULL) {
1308                 return NT_STATUS_NO_MEMORY;
1309         }
1310         state = talloc(m, struct pdb_ads_state);
1311         if (state == NULL) {
1312                 goto nomem;
1313         }
1314         m->private_data = state;
1315         m->free_private_data = free_private_data;
1316         pdb_ads_init_methods(m);
1317
1318         if (location == NULL) {
1319                 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1320                                       lp_private_dir());
1321                 location = tmp;
1322         }
1323         if (location == NULL) {
1324                 goto nomem;
1325         }
1326
1327         status = pdb_ads_connect(state, location);
1328         if (!NT_STATUS_IS_OK(status)) {
1329                 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1330                 goto fail;
1331         }
1332
1333         *pdb_method = m;
1334         return NT_STATUS_OK;
1335 nomem:
1336         status = NT_STATUS_NO_MEMORY;
1337 fail:
1338         TALLOC_FREE(m);
1339         return status;
1340 }
1341
1342 NTSTATUS pdb_ads_init(void);
1343 NTSTATUS pdb_ads_init(void)
1344 {
1345         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
1346                                    pdb_init_ads);
1347 }