Return full info in pdb_ads_search_users()
[samba.git] / source3 / passdb / pdb_ads.c
1 /*
2    Unix SMB/CIFS implementation.
3    pdb_ldap with ads schema
4    Copyright (C) Volker Lendecke 2009
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21
22 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_users(struct pdb_methods *m,
853                                  struct pdb_search *search,
854                                  uint32 acct_flags)
855 {
856         struct pdb_ads_state *state = talloc_get_type_abort(
857                 m->private_data, struct pdb_ads_state);
858         struct pdb_ads_search_state *sstate;
859         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
860                                  "userAccountControl", "description" };
861         struct tldap_message **users;
862         int i, rc, num_users;
863
864         sstate = talloc_zero(search, struct pdb_ads_search_state);
865         if (sstate == NULL) {
866                 return false;
867         }
868         sstate->acct_flags = acct_flags;
869
870         rc = tldap_search_fmt(
871                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
872                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
873                 "(objectclass=user)");
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         return true;
930 }
931
932 static bool pdb_ads_search_groups(struct pdb_methods *m,
933                                   struct pdb_search *search)
934 {
935         return false;
936 }
937
938 static bool pdb_ads_search_aliases(struct pdb_methods *m,
939                                    struct pdb_search *search,
940                                    const DOM_SID *sid)
941 {
942         return false;
943 }
944
945 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
946                                uint32 *rid)
947 {
948         return false;
949 }
950
951 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
952                                DOM_SID *sid)
953 {
954         return false;
955 }
956
957 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
958                                DOM_SID *sid)
959 {
960         return false;
961 }
962
963 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
964                               union unid_t *id, enum lsa_SidType *type)
965 {
966         struct pdb_ads_state *state = talloc_get_type_abort(
967                 m->private_data, struct pdb_ads_state);
968         struct tldap_message **msg;
969         char *sidstr;
970         uint32_t rid;
971         int rc;
972
973         /*
974          * This is a big, big hack: Just hard-code the rid as uid/gid.
975          */
976
977         sid_peek_rid(sid, &rid);
978
979         sidstr = sid_binstring(talloc_tos(), sid);
980         if (sidstr == NULL) {
981                 return false;
982         }
983
984         rc = tldap_search_fmt(
985                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
986                 NULL, 0, 0, talloc_tos(), &msg,
987                 "(&(objectsid=%s)(objectclass=user))", sidstr);
988         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
989                 id->uid = rid;
990                 *type = SID_NAME_USER;
991                 TALLOC_FREE(sidstr);
992                 return true;
993         }
994
995         rc = tldap_search_fmt(
996                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
997                 NULL, 0, 0, talloc_tos(), &msg,
998                 "(&(objectsid=%s)(objectclass=group))", sidstr);
999         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1000                 id->gid = rid;
1001                 *type = SID_NAME_DOM_GRP;
1002                 TALLOC_FREE(sidstr);
1003                 return true;
1004         }
1005
1006         TALLOC_FREE(sidstr);
1007         return false;
1008 }
1009
1010 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1011 {
1012         return false;
1013 }
1014
1015 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1016 {
1017         return false;
1018 }
1019
1020 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1021                                       const char *domain, char** pwd,
1022                                       DOM_SID *sid,
1023                                       time_t *pass_last_set_time)
1024 {
1025         return false;
1026 }
1027
1028 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1029                                       const char* domain, const char* pwd,
1030                                       const DOM_SID *sid)
1031 {
1032         return false;
1033 }
1034
1035 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1036                                       const char *domain)
1037 {
1038         return false;
1039 }
1040
1041 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1042                                          TALLOC_CTX *mem_ctx,
1043                                          uint32 *num_domains,
1044                                          struct trustdom_info ***domains)
1045 {
1046         return NT_STATUS_NOT_IMPLEMENTED;
1047 }
1048
1049 static void pdb_ads_init_methods(struct pdb_methods *m)
1050 {
1051         m->name = "ads";
1052         m->getsampwnam = pdb_ads_getsampwnam;
1053         m->getsampwsid = pdb_ads_getsampwsid;
1054         m->create_user = pdb_ads_create_user;
1055         m->delete_user = pdb_ads_delete_user;
1056         m->add_sam_account = pdb_ads_add_sam_account;
1057         m->update_sam_account = pdb_ads_update_sam_account;
1058         m->delete_sam_account = pdb_ads_delete_sam_account;
1059         m->rename_sam_account = pdb_ads_rename_sam_account;
1060         m->update_login_attempts = pdb_ads_update_login_attempts;
1061         m->getgrsid = pdb_ads_getgrsid;
1062         m->getgrgid = pdb_ads_getgrgid;
1063         m->getgrnam = pdb_ads_getgrnam;
1064         m->create_dom_group = pdb_ads_create_dom_group;
1065         m->delete_dom_group = pdb_ads_delete_dom_group;
1066         m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1067         m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1068         m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1069         m->enum_group_mapping = pdb_ads_enum_group_mapping;
1070         m->enum_group_members = pdb_ads_enum_group_members;
1071         m->enum_group_memberships = pdb_ads_enum_group_memberships;
1072         m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1073         m->add_groupmem = pdb_ads_add_groupmem;
1074         m->del_groupmem = pdb_ads_del_groupmem;
1075         m->create_alias = pdb_ads_create_alias;
1076         m->delete_alias = pdb_ads_delete_alias;
1077         m->get_aliasinfo = pdb_ads_get_aliasinfo;
1078         m->set_aliasinfo = pdb_ads_set_aliasinfo;
1079         m->add_aliasmem = pdb_ads_add_aliasmem;
1080         m->del_aliasmem = pdb_ads_del_aliasmem;
1081         m->enum_aliasmem = pdb_ads_enum_aliasmem;
1082         m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1083         m->lookup_rids = pdb_ads_lookup_rids;
1084         m->lookup_names = pdb_ads_lookup_names;
1085         m->get_account_policy = pdb_ads_get_account_policy;
1086         m->set_account_policy = pdb_ads_set_account_policy;
1087         m->get_seq_num = pdb_ads_get_seq_num;
1088         m->search_users = pdb_ads_search_users;
1089         m->search_groups = pdb_ads_search_groups;
1090         m->search_aliases = pdb_ads_search_aliases;
1091         m->uid_to_rid = pdb_ads_uid_to_rid;
1092         m->uid_to_sid = pdb_ads_uid_to_sid;
1093         m->gid_to_sid = pdb_ads_gid_to_sid;
1094         m->sid_to_id = pdb_ads_sid_to_id;
1095         m->rid_algorithm = pdb_ads_rid_algorithm;
1096         m->new_rid = pdb_ads_new_rid;
1097         m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1098         m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1099         m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1100         m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1101 }
1102
1103 static void free_private_data(void **vp)
1104 {
1105         struct pdb_ads_state *state = talloc_get_type_abort(
1106                 *vp, struct pdb_ads_state);
1107
1108         TALLOC_FREE(state->ld);
1109         return;
1110 }
1111
1112 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1113                                 const char *location)
1114 {
1115         const char *rootdse_attrs[2] = {
1116                 "defaultNamingContext", "configurationNamingContext" };
1117         const char *domain_attrs[1] = { "objectSid" };
1118         const char *ncname_attrs[1] = { "netbiosname" };
1119         struct tldap_message **rootdse, **domain, **ncname;
1120         TALLOC_CTX *frame = talloc_stackframe();
1121         struct sockaddr_un sunaddr;
1122         NTSTATUS status;
1123         int num_domains;
1124         int fd, rc;
1125
1126         ZERO_STRUCT(sunaddr);
1127         sunaddr.sun_family = AF_UNIX;
1128         strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1129
1130         status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1131                                  0, 0, &fd);
1132         if (!NT_STATUS_IS_OK(status)) {
1133                 DEBUG(10, ("Could not connect to %s: %s\n", location,
1134                            nt_errstr(status)));
1135                 goto done;
1136         }
1137
1138         state->ld = tldap_context_create(state, fd);
1139         if (state->ld == NULL) {
1140                 close(fd);
1141                 status = NT_STATUS_NO_MEMORY;
1142                 goto done;
1143         }
1144
1145         rc = tldap_search_fmt(
1146                 state->ld, "", TLDAP_SCOPE_BASE,
1147                 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1148                 talloc_tos(), &rootdse, "(objectclass=*)");
1149         if (rc != TLDAP_SUCCESS) {
1150                 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1151                            tldap_errstr(debug_ctx(), state->ld, rc)));
1152                 status = NT_STATUS_LDAP(rc);
1153                 goto done;
1154         }
1155         if (talloc_array_length(rootdse) != 1) {
1156                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1157                 goto done;
1158         }
1159
1160         state->domaindn = tldap_talloc_single_attribute(
1161                 rootdse[0], "defaultNamingContext", state);
1162         if (state->domaindn == NULL) {
1163                 DEBUG(10, ("Could not get defaultNamingContext\n"));
1164                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1165                 goto done;
1166         }
1167         DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1168
1169         state->configdn = tldap_talloc_single_attribute(
1170                 rootdse[0], "configurationNamingContext", state);
1171         if (state->domaindn == NULL) {
1172                 DEBUG(10, ("Could not get configurationNamingContext\n"));
1173                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1174                 goto done;
1175         }
1176         DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1177
1178         /*
1179          * Figure out our domain's SID
1180          */
1181         rc = tldap_search_fmt(
1182                 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1183                 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1184                 talloc_tos(), &domain, "(objectclass=*)");
1185         if (rc != TLDAP_SUCCESS) {
1186                 DEBUG(10, ("Could not retrieve domain: %s\n",
1187                            tldap_errstr(debug_ctx(), state->ld, rc)));
1188                 status = NT_STATUS_LDAP(rc);
1189                 goto done;
1190         }
1191
1192         num_domains = talloc_array_length(domain);
1193         if (num_domains != 1) {
1194                 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1195                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1196                 goto done;
1197         }
1198         if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1199                 DEBUG(10, ("Could not retrieve domain SID\n"));
1200                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1201                 goto done;
1202         }
1203         DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1204
1205         /*
1206          * Figure out our domain's short name
1207          */
1208         rc = tldap_search_fmt(
1209                 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1210                 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1211                 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1212         if (rc != TLDAP_SUCCESS) {
1213                 DEBUG(10, ("Could not retrieve ncname: %s\n",
1214                            tldap_errstr(debug_ctx(), state->ld, rc)));
1215                 status = NT_STATUS_LDAP(rc);
1216                 goto done;
1217         }
1218         if (talloc_array_length(ncname) != 1) {
1219                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1220                 goto done;
1221         }
1222
1223         state->netbiosname = tldap_talloc_single_attribute(
1224                 ncname[0], "netbiosname", state);
1225         if (state->netbiosname == NULL) {
1226                 DEBUG(10, ("Could not get netbiosname\n"));
1227                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1228                 goto done;
1229         }
1230         DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1231
1232         if (!strequal(lp_workgroup(), state->netbiosname)) {
1233                 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1234                           state->netbiosname, lp_workgroup()));
1235                 status = NT_STATUS_NO_SUCH_DOMAIN;
1236                 goto done;
1237         }
1238
1239         secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1240
1241         status = NT_STATUS_OK;
1242 done:
1243         TALLOC_FREE(frame);
1244         return status;
1245 }
1246
1247 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1248                              const char *location)
1249 {
1250         struct pdb_methods *m;
1251         struct pdb_ads_state *state;
1252         char *tmp = NULL;
1253         NTSTATUS status;
1254
1255         m = talloc(talloc_autofree_context(), struct pdb_methods);
1256         if (m == NULL) {
1257                 return NT_STATUS_NO_MEMORY;
1258         }
1259         state = talloc(m, struct pdb_ads_state);
1260         if (state == NULL) {
1261                 goto nomem;
1262         }
1263         m->private_data = state;
1264         m->free_private_data = free_private_data;
1265         pdb_ads_init_methods(m);
1266
1267         if (location == NULL) {
1268                 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1269                                       lp_private_dir());
1270                 location = tmp;
1271         }
1272         if (location == NULL) {
1273                 goto nomem;
1274         }
1275
1276         status = pdb_ads_connect(state, location);
1277         if (!NT_STATUS_IS_OK(status)) {
1278                 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1279                 goto fail;
1280         }
1281
1282         *pdb_method = m;
1283         return NT_STATUS_OK;
1284 nomem:
1285         status = NT_STATUS_NO_MEMORY;
1286 fail:
1287         TALLOC_FREE(m);
1288         return status;
1289 }
1290
1291 NTSTATUS pdb_ads_init(void);
1292 NTSTATUS pdb_ads_init(void)
1293 {
1294         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
1295                                    pdb_init_ads);
1296 }