Add an early prototyp of pdb_ads.c.
[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_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",
860                                  "userAccountControl" };
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 = "Name";
905                 e->fullname = "Full Name";
906                 e->description = "Beschreibung";
907
908                 sstate->num_entries += 1;
909                 if (sstate->num_entries >= num_users) {
910                         break;
911                 }
912         }
913
914         search->private_data = sstate;
915         search->next_entry = pdb_ads_next_entry;
916         search->search_end = pdb_ads_search_end;
917         return true;
918 }
919
920 static bool pdb_ads_search_groups(struct pdb_methods *m,
921                                   struct pdb_search *search)
922 {
923         return false;
924 }
925
926 static bool pdb_ads_search_aliases(struct pdb_methods *m,
927                                    struct pdb_search *search,
928                                    const DOM_SID *sid)
929 {
930         return false;
931 }
932
933 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
934                                uint32 *rid)
935 {
936         return false;
937 }
938
939 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
940                                DOM_SID *sid)
941 {
942         return false;
943 }
944
945 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
946                                DOM_SID *sid)
947 {
948         return false;
949 }
950
951 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
952                               union unid_t *id, enum lsa_SidType *type)
953 {
954         struct pdb_ads_state *state = talloc_get_type_abort(
955                 m->private_data, struct pdb_ads_state);
956         struct tldap_message **msg;
957         char *sidstr;
958         uint32_t rid;
959         int rc;
960
961         /*
962          * This is a big, big hack: Just hard-code the rid as uid/gid.
963          */
964
965         sid_peek_rid(sid, &rid);
966
967         sidstr = sid_binstring(talloc_tos(), sid);
968         if (sidstr == NULL) {
969                 return false;
970         }
971
972         rc = tldap_search_fmt(
973                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
974                 NULL, 0, 0, talloc_tos(), &msg,
975                 "(&(objectsid=%s)(objectclass=user))", sidstr);
976         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
977                 id->uid = rid;
978                 *type = SID_NAME_USER;
979                 TALLOC_FREE(sidstr);
980                 return true;
981         }
982
983         rc = tldap_search_fmt(
984                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
985                 NULL, 0, 0, talloc_tos(), &msg,
986                 "(&(objectsid=%s)(objectclass=group))", sidstr);
987         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
988                 id->gid = rid;
989                 *type = SID_NAME_DOM_GRP;
990                 TALLOC_FREE(sidstr);
991                 return true;
992         }
993
994         TALLOC_FREE(sidstr);
995         return false;
996 }
997
998 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
999 {
1000         return false;
1001 }
1002
1003 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1004 {
1005         return false;
1006 }
1007
1008 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1009                                       const char *domain, char** pwd,
1010                                       DOM_SID *sid,
1011                                       time_t *pass_last_set_time)
1012 {
1013         return false;
1014 }
1015
1016 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1017                                       const char* domain, const char* pwd,
1018                                       const DOM_SID *sid)
1019 {
1020         return false;
1021 }
1022
1023 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1024                                       const char *domain)
1025 {
1026         return false;
1027 }
1028
1029 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1030                                          TALLOC_CTX *mem_ctx,
1031                                          uint32 *num_domains,
1032                                          struct trustdom_info ***domains)
1033 {
1034         return NT_STATUS_NOT_IMPLEMENTED;
1035 }
1036
1037 static void pdb_ads_init_methods(struct pdb_methods *m)
1038 {
1039         m->name = "ads";
1040         m->getsampwnam = pdb_ads_getsampwnam;
1041         m->getsampwsid = pdb_ads_getsampwsid;
1042         m->create_user = pdb_ads_create_user;
1043         m->delete_user = pdb_ads_delete_user;
1044         m->add_sam_account = pdb_ads_add_sam_account;
1045         m->update_sam_account = pdb_ads_update_sam_account;
1046         m->delete_sam_account = pdb_ads_delete_sam_account;
1047         m->rename_sam_account = pdb_ads_rename_sam_account;
1048         m->update_login_attempts = pdb_ads_update_login_attempts;
1049         m->getgrsid = pdb_ads_getgrsid;
1050         m->getgrgid = pdb_ads_getgrgid;
1051         m->getgrnam = pdb_ads_getgrnam;
1052         m->create_dom_group = pdb_ads_create_dom_group;
1053         m->delete_dom_group = pdb_ads_delete_dom_group;
1054         m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1055         m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1056         m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1057         m->enum_group_mapping = pdb_ads_enum_group_mapping;
1058         m->enum_group_members = pdb_ads_enum_group_members;
1059         m->enum_group_memberships = pdb_ads_enum_group_memberships;
1060         m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1061         m->add_groupmem = pdb_ads_add_groupmem;
1062         m->del_groupmem = pdb_ads_del_groupmem;
1063         m->create_alias = pdb_ads_create_alias;
1064         m->delete_alias = pdb_ads_delete_alias;
1065         m->get_aliasinfo = pdb_ads_get_aliasinfo;
1066         m->set_aliasinfo = pdb_ads_set_aliasinfo;
1067         m->add_aliasmem = pdb_ads_add_aliasmem;
1068         m->del_aliasmem = pdb_ads_del_aliasmem;
1069         m->enum_aliasmem = pdb_ads_enum_aliasmem;
1070         m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1071         m->lookup_rids = pdb_ads_lookup_rids;
1072         m->lookup_names = pdb_ads_lookup_names;
1073         m->get_account_policy = pdb_ads_get_account_policy;
1074         m->set_account_policy = pdb_ads_set_account_policy;
1075         m->get_seq_num = pdb_ads_get_seq_num;
1076         m->search_users = pdb_ads_search_users;
1077         m->search_groups = pdb_ads_search_groups;
1078         m->search_aliases = pdb_ads_search_aliases;
1079         m->uid_to_rid = pdb_ads_uid_to_rid;
1080         m->uid_to_sid = pdb_ads_uid_to_sid;
1081         m->gid_to_sid = pdb_ads_gid_to_sid;
1082         m->sid_to_id = pdb_ads_sid_to_id;
1083         m->rid_algorithm = pdb_ads_rid_algorithm;
1084         m->new_rid = pdb_ads_new_rid;
1085         m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1086         m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1087         m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1088         m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1089 }
1090
1091 static void free_private_data(void **vp)
1092 {
1093         struct pdb_ads_state *state = talloc_get_type_abort(
1094                 *vp, struct pdb_ads_state);
1095
1096         TALLOC_FREE(state->ld);
1097         return;
1098 }
1099
1100 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1101                                 const char *location)
1102 {
1103         const char *rootdse_attrs[2] = {
1104                 "defaultNamingContext", "configurationNamingContext" };
1105         const char *domain_attrs[1] = { "objectSid" };
1106         const char *ncname_attrs[1] = { "netbiosname" };
1107         struct tldap_message **rootdse, **domain, **ncname;
1108         TALLOC_CTX *frame = talloc_stackframe();
1109         struct sockaddr_un sunaddr;
1110         NTSTATUS status;
1111         int num_domains;
1112         int fd, rc;
1113
1114         ZERO_STRUCT(sunaddr);
1115         sunaddr.sun_family = AF_UNIX;
1116         strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1117
1118         status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1119                                  0, 0, &fd);
1120         if (!NT_STATUS_IS_OK(status)) {
1121                 DEBUG(10, ("Could not connect to %s: %s\n", location,
1122                            nt_errstr(status)));
1123                 goto done;
1124         }
1125
1126         state->ld = tldap_context_create(state, fd);
1127         if (state->ld == NULL) {
1128                 close(fd);
1129                 status = NT_STATUS_NO_MEMORY;
1130                 goto done;
1131         }
1132
1133         rc = tldap_search_fmt(
1134                 state->ld, "", TLDAP_SCOPE_BASE,
1135                 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1136                 talloc_tos(), &rootdse, "(objectclass=*)");
1137         if (rc != TLDAP_SUCCESS) {
1138                 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1139                            tldap_errstr(debug_ctx(), state->ld, rc)));
1140                 status = NT_STATUS_LDAP(rc);
1141                 goto done;
1142         }
1143         if (talloc_array_length(rootdse) != 1) {
1144                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1145                 goto done;
1146         }
1147
1148         state->domaindn = tldap_talloc_single_attribute(
1149                 rootdse[0], "defaultNamingContext", state);
1150         if (state->domaindn == NULL) {
1151                 DEBUG(10, ("Could not get defaultNamingContext\n"));
1152                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1153                 goto done;
1154         }
1155         DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1156
1157         state->configdn = tldap_talloc_single_attribute(
1158                 rootdse[0], "configurationNamingContext", state);
1159         if (state->domaindn == NULL) {
1160                 DEBUG(10, ("Could not get configurationNamingContext\n"));
1161                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1162                 goto done;
1163         }
1164         DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1165
1166         /*
1167          * Figure out our domain's SID
1168          */
1169         rc = tldap_search_fmt(
1170                 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1171                 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1172                 talloc_tos(), &domain, "(objectclass=*)");
1173         if (rc != TLDAP_SUCCESS) {
1174                 DEBUG(10, ("Could not retrieve domain: %s\n",
1175                            tldap_errstr(debug_ctx(), state->ld, rc)));
1176                 status = NT_STATUS_LDAP(rc);
1177                 goto done;
1178         }
1179
1180         num_domains = talloc_array_length(domain);
1181         if (num_domains != 1) {
1182                 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1183                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1184                 goto done;
1185         }
1186         if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1187                 DEBUG(10, ("Could not retrieve domain SID\n"));
1188                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1189                 goto done;
1190         }
1191         DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1192
1193         /*
1194          * Figure out our domain's short name
1195          */
1196         rc = tldap_search_fmt(
1197                 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1198                 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1199                 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1200         if (rc != TLDAP_SUCCESS) {
1201                 DEBUG(10, ("Could not retrieve ncname: %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(ncname) != 1) {
1207                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1208                 goto done;
1209         }
1210
1211         state->netbiosname = tldap_talloc_single_attribute(
1212                 ncname[0], "netbiosname", state);
1213         if (state->netbiosname == NULL) {
1214                 DEBUG(10, ("Could not get netbiosname\n"));
1215                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1216                 goto done;
1217         }
1218         DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1219
1220         if (!strequal(lp_workgroup(), state->netbiosname)) {
1221                 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1222                           state->netbiosname, lp_workgroup()));
1223                 status = NT_STATUS_NO_SUCH_DOMAIN;
1224                 goto done;
1225         }
1226
1227         secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1228
1229         status = NT_STATUS_OK;
1230 done:
1231         TALLOC_FREE(frame);
1232         return status;
1233 }
1234
1235 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1236                              const char *location)
1237 {
1238         struct pdb_methods *m;
1239         struct pdb_ads_state *state;
1240         char *tmp = NULL;
1241         NTSTATUS status;
1242
1243         m = talloc(talloc_autofree_context(), struct pdb_methods);
1244         if (m == NULL) {
1245                 return NT_STATUS_NO_MEMORY;
1246         }
1247         state = talloc(m, struct pdb_ads_state);
1248         if (state == NULL) {
1249                 goto nomem;
1250         }
1251         m->private_data = state;
1252         m->free_private_data = free_private_data;
1253         pdb_ads_init_methods(m);
1254
1255         if (location == NULL) {
1256                 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1257                                       lp_private_dir());
1258                 location = tmp;
1259         }
1260         if (location == NULL) {
1261                 goto nomem;
1262         }
1263
1264         status = pdb_ads_connect(state, location);
1265         if (!NT_STATUS_IS_OK(status)) {
1266                 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1267                 goto fail;
1268         }
1269
1270         *pdb_method = m;
1271         return NT_STATUS_OK;
1272 nomem:
1273         status = NT_STATUS_NO_MEMORY;
1274 fail:
1275         TALLOC_FREE(m);
1276         return status;
1277 }
1278
1279 NTSTATUS pdb_ads_init(void);
1280 NTSTATUS pdb_ads_init(void)
1281 {
1282         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
1283                                    pdb_init_ads);
1284 }