More pdb_ads stuff
[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 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
26                                DOM_SID *sid);
27
28
29 struct pdb_ads_state {
30         struct tldap_context *ld;
31         struct dom_sid domainsid;
32         char *domaindn;
33         char *configdn;
34         char *netbiosname;
35 };
36
37 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
38                               time_t *ptime)
39 {
40         uint64_t tmp;
41
42         if (!tldap_pull_uint64(msg, attr, &tmp)) {
43                 return false;
44         }
45         *ptime = uint64s_nt_time_to_unix_abs(&tmp);
46         return true;
47 }
48
49 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
50 {
51         uint32_t rid;
52         sid_peek_rid(sid, &rid);
53         return rid;
54 }
55
56 struct pdb_ads_samu_private {
57         char *dn;
58         struct tldap_message *ldapmsg;
59 };
60
61 static struct samu *pdb_ads_init_guest(TALLOC_CTX *mem_ctx,
62                                        struct pdb_methods *m)
63 {
64         struct pdb_ads_state *state = talloc_get_type_abort(
65                 m->private_data, struct pdb_ads_state);
66         struct dom_sid guest_sid;
67         struct samu *guest;
68         NTSTATUS status;
69
70         sid_compose(&guest_sid, &state->domainsid, DOMAIN_USER_RID_GUEST);
71
72         guest = samu_new(mem_ctx);
73         if (guest == NULL) {
74                 return NULL;
75         }
76
77         status = pdb_ads_getsampwsid(m, guest, &guest_sid);
78         if (!NT_STATUS_IS_OK(status)) {
79                 DEBUG(10, ("Could not init guest account: %s\n",
80                            nt_errstr(status)));
81                 TALLOC_FREE(guest);
82                 return NULL;
83         }
84         return guest;
85 }
86
87 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
88         struct pdb_methods *m, struct samu *sam)
89 {
90         struct pdb_ads_samu_private *result;
91         uint32_t rid;
92
93         result = (struct pdb_ads_samu_private *)
94                 pdb_get_backend_private_data(sam, m);
95
96         if (result != NULL) {
97                 return talloc_get_type_abort(
98                         result, struct pdb_ads_samu_private);
99         }
100
101         /*
102          * This is now a weirdness of the passdb API. For the guest user we
103          * are not asked first.
104          */
105         sid_peek_rid(pdb_get_user_sid(sam), &rid);
106
107         if (rid == DOMAIN_USER_RID_GUEST) {
108                 struct samu *guest = pdb_ads_init_guest(talloc_tos(), m);
109
110                 if (guest == NULL) {
111                         return NULL;
112                 }
113                 result = talloc_get_type_abort(
114                         pdb_get_backend_private_data(guest, m),
115                         struct pdb_ads_samu_private);
116                 pdb_set_backend_private_data(
117                         sam, talloc_move(sam, &result), NULL, m, PDB_SET);
118                 TALLOC_FREE(guest);
119                 return talloc_get_type_abort(
120                         pdb_get_backend_private_data(sam, m),
121                         struct pdb_ads_samu_private);
122         }
123
124         return NULL;
125 }
126
127 static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m,
128                                           struct samu *sam,
129                                           struct tldap_message *entry)
130 {
131         struct pdb_ads_state *state = talloc_get_type_abort(
132                 m->private_data, struct pdb_ads_state);
133         TALLOC_CTX *frame = talloc_stackframe();
134         struct pdb_ads_samu_private *priv;
135         NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
136         char *str;
137         time_t tmp_time;
138         struct dom_sid sid;
139         uint64_t n;
140         DATA_BLOB blob;
141
142         priv = talloc(sam, struct pdb_ads_samu_private);
143         if (priv == NULL) {
144                 return NT_STATUS_NO_MEMORY;
145         }
146         if (!tldap_entry_dn(entry, &priv->dn)) {
147                 TALLOC_FREE(priv);
148                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
149         }
150
151         str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
152         if (str == NULL) {
153                 DEBUG(10, ("no samAccountName\n"));
154                 goto fail;
155         }
156         pdb_set_username(sam, str, PDB_SET);
157         TALLOC_FREE(str);
158
159         if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
160                 pdb_set_logon_time(sam, tmp_time, PDB_SET);
161         }
162         if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
163                 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
164         }
165         if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
166                 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
167         }
168         if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
169                 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
170         }
171
172         str = tldap_talloc_single_attribute(entry, "samAccoutName",
173                                             talloc_tos());
174         if (str != NULL) {
175                 pdb_set_username(sam, str, PDB_SET);
176         }
177
178         str = tldap_talloc_single_attribute(entry, "displayName",
179                                             talloc_tos());
180         if (str != NULL) {
181                 pdb_set_fullname(sam, str, PDB_SET);
182         }
183
184         str = tldap_talloc_single_attribute(entry, "homeDirectory",
185                                             talloc_tos());
186         if (str != NULL) {
187                 pdb_set_homedir(sam, str, PDB_SET);
188         }
189
190         str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
191         if (str != NULL) {
192                 pdb_set_dir_drive(sam, str, PDB_SET);
193         }
194
195         str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
196         if (str != NULL) {
197                 pdb_set_logon_script(sam, str, PDB_SET);
198         }
199
200         str = tldap_talloc_single_attribute(entry, "profilePath",
201                                             talloc_tos());
202         if (str != NULL) {
203                 pdb_set_profile_path(sam, str, PDB_SET);
204         }
205
206         str = tldap_talloc_single_attribute(entry, "profilePath",
207                                             talloc_tos());
208         if (str != NULL) {
209                 pdb_set_profile_path(sam, str, PDB_SET);
210         }
211
212         if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
213                 DEBUG(10, ("Could not pull SID\n"));
214                 goto fail;
215         }
216         pdb_set_user_sid(sam, &sid, PDB_SET);
217
218         if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
219                 DEBUG(10, ("Could not pull userAccountControl\n"));
220                 goto fail;
221         }
222         pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET);
223
224         if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
225                 if (blob.length != NT_HASH_LEN) {
226                         DEBUG(0, ("Got NT hash of length %d, expected %d\n",
227                                   (int)blob.length, NT_HASH_LEN));
228                         goto fail;
229                 }
230                 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
231         }
232
233         if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
234                 if (blob.length != LM_HASH_LEN) {
235                         DEBUG(0, ("Got LM hash of length %d, expected %d\n",
236                                   (int)blob.length, LM_HASH_LEN));
237                         goto fail;
238                 }
239                 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
240         }
241
242         if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
243                 sid_compose(&sid, &state->domainsid, n);
244                 pdb_set_group_sid(sam, &sid, PDB_SET);
245
246         }
247
248         priv->ldapmsg = talloc_move(priv, &entry);
249         pdb_set_backend_private_data(sam, priv, NULL, m, PDB_SET);
250
251         status = NT_STATUS_OK;
252 fail:
253         TALLOC_FREE(frame);
254         return status;
255 }
256
257 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
258                                       struct tldap_message *existing,
259                                       TALLOC_CTX *mem_ctx,
260                                       int *pnum_mods, struct tldap_mod **pmods,
261                                       struct samu *sam)
262 {
263         bool ret = true;
264
265         /* TODO: All fields :-) */
266
267         ret &= tldap_make_mod_fmt(
268                 existing, mem_ctx, pnum_mods, pmods, "displayName",
269                 pdb_get_fullname(sam));
270
271         ret &= tldap_make_mod_blob(
272                 existing, mem_ctx, pnum_mods, pmods, "unicodePwd",
273                 data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN));
274
275         ret &= tldap_make_mod_blob(
276                 existing, mem_ctx, pnum_mods, pmods, "dBCSPwd",
277                 data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN));
278
279         return ret;
280 }
281
282 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
283                                        struct pdb_ads_state *state,
284                                        struct samu *sam_acct,
285                                        const char *filter)
286 {
287         const char * attrs[] = {
288                 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
289                 "sAMAccountName", "displayName", "homeDirectory",
290                 "homeDrive", "scriptPath", "profilePath", "description",
291                 "userWorkstations", "comment", "userParameters", "objectSid",
292                 "primaryGroupID", "userAccountControl", "logonHours",
293                 "badPwdCount", "logonCount", "countryCode", "codePage",
294                 "unicodePwd", "dBCSPwd" };
295         struct tldap_message **users;
296         int rc, count;
297
298         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
299                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
300                               &users, "%s", filter);
301         if (rc != TLDAP_SUCCESS) {
302                 DEBUG(10, ("ldap_search failed %s\n",
303                            tldap_errstr(debug_ctx(), state->ld, rc)));
304                 return NT_STATUS_LDAP(rc);
305         }
306
307         count = talloc_array_length(users);
308         if (count != 1) {
309                 DEBUG(10, ("Expected 1 user, got %d\n", count));
310                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
311         }
312
313         return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]);
314 }
315
316 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
317                                     struct samu *sam_acct,
318                                     const char *username)
319 {
320         struct pdb_ads_state *state = talloc_get_type_abort(
321                 m->private_data, struct pdb_ads_state);
322         char *filter;
323
324         filter = talloc_asprintf(
325                 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
326                 username);
327         NT_STATUS_HAVE_NO_MEMORY(filter);
328
329         return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
330 }
331
332 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
333                                     struct samu *sam_acct,
334                                     const DOM_SID *sid)
335 {
336         struct pdb_ads_state *state = talloc_get_type_abort(
337                 m->private_data, struct pdb_ads_state);
338         char *sidstr, *filter;
339
340         sidstr = sid_binstring(talloc_tos(), sid);
341         NT_STATUS_HAVE_NO_MEMORY(sidstr);
342
343         filter = talloc_asprintf(
344                 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
345         TALLOC_FREE(sidstr);
346         NT_STATUS_HAVE_NO_MEMORY(filter);
347
348         return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
349 }
350
351 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
352                                     TALLOC_CTX *tmp_ctx,
353                                     const char *name, uint32 acct_flags,
354                                     uint32 *rid)
355 {
356         struct pdb_ads_state *state = talloc_get_type_abort(
357                 m->private_data, struct pdb_ads_state);
358         const char *attrs[1] = { "objectSid" };
359         struct tldap_mod *mods = NULL;
360         int num_mods = 0;
361         struct tldap_message **user;
362         struct dom_sid sid;
363         char *dn;
364         int rc;
365         bool ok;
366
367         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
368                              state->domaindn);
369         if (dn == NULL) {
370                 return NT_STATUS_NO_MEMORY;
371         }
372
373         /* TODO: Create machines etc */
374
375         ok = true;
376         ok &= tldap_make_mod_fmt(
377                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
378         ok &= tldap_make_mod_fmt(
379                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
380                 name);
381         if (!ok) {
382                 return NT_STATUS_NO_MEMORY;
383         }
384
385         rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
386         if (rc != TLDAP_SUCCESS) {
387                 DEBUG(10, ("ldap_add failed %s\n",
388                            tldap_errstr(debug_ctx(), state->ld, rc)));
389                 TALLOC_FREE(dn);
390                 return NT_STATUS_LDAP(rc);
391         }
392
393         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
394                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &user,
395                              "(&(objectclass=user)(samaccountname=%s))",
396                              name);
397         if (rc != TLDAP_SUCCESS) {
398                 DEBUG(10, ("Could not find just created user %s: %s\n",
399                            name, tldap_errstr(debug_ctx(), state->ld, rc)));
400                 TALLOC_FREE(dn);
401                 return NT_STATUS_LDAP(rc);
402         }
403
404         if (talloc_array_length(user) != 1) {
405                 DEBUG(10, ("Got %d users, expected one\n",
406                            (int)talloc_array_length(user)));
407                 TALLOC_FREE(dn);
408                 return NT_STATUS_LDAP(rc);
409         }
410
411         if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
412                 DEBUG(10, ("Could not fetch objectSid from user %s\n",
413                            name));
414                 TALLOC_FREE(dn);
415                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
416         }
417
418         sid_peek_rid(&sid, rid);
419         TALLOC_FREE(dn);
420         return NT_STATUS_OK;
421 }
422
423 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
424                                     TALLOC_CTX *tmp_ctx,
425                                     struct samu *sam)
426 {
427         struct pdb_ads_state *state = talloc_get_type_abort(
428                 m->private_data, struct pdb_ads_state);
429         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
430         int rc;
431
432         rc = tldap_delete(state->ld, priv->dn, NULL, NULL);
433         if (rc != TLDAP_SUCCESS) {
434                 DEBUG(10, ("ldap_delete for %s failed: %s\n", priv->dn,
435                            tldap_errstr(debug_ctx(), state->ld, rc)));
436                 return NT_STATUS_LDAP(rc);
437         }
438         return NT_STATUS_OK;
439 }
440
441 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
442                                         struct samu *sampass)
443 {
444         return NT_STATUS_NOT_IMPLEMENTED;
445 }
446
447 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
448                                            struct samu *sam)
449 {
450         struct pdb_ads_state *state = talloc_get_type_abort(
451                 m->private_data, struct pdb_ads_state);
452         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
453         struct tldap_mod *mods = NULL;
454         int rc, num_mods = 0;
455
456         if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
457                                        &num_mods, &mods, sam)) {
458                 return NT_STATUS_NO_MEMORY;
459         }
460
461         rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, NULL);
462         if (rc != TLDAP_SUCCESS) {
463                 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
464                            tldap_errstr(debug_ctx(), state->ld, rc)));
465                 return NT_STATUS_LDAP(rc);
466         }
467
468         TALLOC_FREE(mods);
469
470         return NT_STATUS_OK;
471 }
472
473 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
474                                            struct samu *username)
475 {
476         return NT_STATUS_NOT_IMPLEMENTED;
477 }
478
479 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
480                                            struct samu *oldname,
481                                            const char *newname)
482 {
483         return NT_STATUS_NOT_IMPLEMENTED;
484 }
485
486 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
487                                               struct samu *sam_acct,
488                                               bool success)
489 {
490         return NT_STATUS_NOT_IMPLEMENTED;
491 }
492
493 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
494                                     const char *filter)
495 {
496         struct pdb_ads_state *state = talloc_get_type_abort(
497                 m->private_data, struct pdb_ads_state);
498         const char *attrs[4] = { "objectSid", "description", "samAccountName",
499                                  "groupType" };
500         char *str;
501         struct tldap_message **group;
502         uint32_t grouptype;
503         int rc;
504
505         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
506                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
507                               &group, "%s", filter);
508         if (rc != TLDAP_SUCCESS) {
509                 DEBUG(10, ("ldap_search failed %s\n",
510                            tldap_errstr(debug_ctx(), state->ld, rc)));
511                 return NT_STATUS_LDAP(rc);
512         }
513         if (talloc_array_length(group) != 1) {
514                 DEBUG(10, ("Expected 1 user, got %d\n",
515                            talloc_array_length(group)));
516                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
517         }
518
519         if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
520                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
521         }
522         map->gid = pdb_ads_sid2gid(&map->sid);
523
524         if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
525                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
526         }
527         switch (grouptype) {
528         case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
529         case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
530                 map->sid_name_use = SID_NAME_ALIAS;
531                 break;
532         case GTYPE_SECURITY_GLOBAL_GROUP:
533                 map->sid_name_use = SID_NAME_DOM_GRP;
534                 break;
535         default:
536                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
537         }
538
539         str = tldap_talloc_single_attribute(group[0], "samAccountName",
540                                             talloc_tos());
541         if (str == NULL) {
542                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
543         }
544         fstrcpy(map->nt_name, str);
545         TALLOC_FREE(str);
546
547         str = tldap_talloc_single_attribute(group[0], "description",
548                                             talloc_tos());
549         if (str != NULL) {
550                 fstrcpy(map->comment, str);
551                 TALLOC_FREE(str);
552         } else {
553                 map->comment[0] = '\0';
554         }
555
556         TALLOC_FREE(group);
557         return NT_STATUS_OK;
558 }
559
560 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
561                                  DOM_SID sid)
562 {
563         char *filter;
564         NTSTATUS status;
565
566         filter = talloc_asprintf(talloc_tos(),
567                                  "(&(objectsid=%s)(objectclass=group))",
568                                  sid_string_talloc(talloc_tos(), &sid));
569         if (filter == NULL) {
570                 return NT_STATUS_NO_MEMORY;
571         }
572
573         status = pdb_ads_getgrfilter(m, map, filter);
574         TALLOC_FREE(filter);
575         return status;
576 }
577
578 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
579                                  gid_t gid)
580 {
581         struct dom_sid sid;
582         pdb_ads_gid_to_sid(m, gid, &sid);
583         return pdb_ads_getgrsid(m, map, sid);
584 }
585
586 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
587                                  const char *name)
588 {
589         char *filter;
590         NTSTATUS status;
591
592         filter = talloc_asprintf(talloc_tos(),
593                                  "(&(samaccountname=%s)(objectclass=group))",
594                                  name);
595         if (filter == NULL) {
596                 return NT_STATUS_NO_MEMORY;
597         }
598
599         status = pdb_ads_getgrfilter(m, map, filter);
600         TALLOC_FREE(filter);
601         return status;
602 }
603
604 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
605                                          TALLOC_CTX *mem_ctx, const char *name,
606                                          uint32 *rid)
607 {
608         return NT_STATUS_NOT_IMPLEMENTED;
609 }
610
611 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
612                                          TALLOC_CTX *mem_ctx, uint32 rid)
613 {
614         return NT_STATUS_NOT_IMPLEMENTED;
615 }
616
617 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
618                                                 GROUP_MAP *map)
619 {
620         return NT_STATUS_NOT_IMPLEMENTED;
621 }
622
623 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
624                                                    GROUP_MAP *map)
625 {
626         return NT_STATUS_NOT_IMPLEMENTED;
627 }
628
629 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
630                                                    DOM_SID sid)
631 {
632         return NT_STATUS_NOT_IMPLEMENTED;
633 }
634
635 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
636                                            const DOM_SID *sid,
637                                            enum lsa_SidType sid_name_use,
638                                            GROUP_MAP **pp_rmap,
639                                            size_t *p_num_entries,
640                                            bool unix_only)
641 {
642         return NT_STATUS_NOT_IMPLEMENTED;
643 }
644
645 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
646                                            TALLOC_CTX *mem_ctx,
647                                            const DOM_SID *group,
648                                            uint32 **pp_member_rids,
649                                            size_t *p_num_members)
650 {
651         return NT_STATUS_NOT_IMPLEMENTED;
652 }
653
654 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
655                                                TALLOC_CTX *mem_ctx,
656                                                struct samu *user,
657                                                DOM_SID **pp_sids,
658                                                gid_t **pp_gids,
659                                                size_t *p_num_groups)
660 {
661         struct pdb_ads_state *state = talloc_get_type_abort(
662                 m->private_data, struct pdb_ads_state);
663         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
664                 m, user);
665         const char *attrs[1] = { "objectSid" };
666         struct tldap_message **groups;
667         int i, rc, count;
668         size_t num_groups;
669         struct dom_sid *group_sids;
670         gid_t *gids;
671
672         rc = tldap_search_fmt(
673                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
674                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
675                 "(&(member=%s)(grouptype=%d)(objectclass=group))",
676                 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
677         if (rc != TLDAP_SUCCESS) {
678                 DEBUG(10, ("ldap_search failed %s\n",
679                            tldap_errstr(debug_ctx(), state->ld, rc)));
680                 return NT_STATUS_LDAP(rc);
681         }
682
683         count = talloc_array_length(groups);
684
685         group_sids = talloc_array(mem_ctx, struct dom_sid, count);
686         if (group_sids == NULL) {
687                 return NT_STATUS_NO_MEMORY;
688         }
689         gids = talloc_array(mem_ctx, gid_t, count);
690         if (gids == NULL) {
691                 TALLOC_FREE(group_sids);
692                 return NT_STATUS_NO_MEMORY;
693         }
694         num_groups = 0;
695
696         for (i=0; i<count; i++) {
697                 if (!tldap_pull_binsid(groups[i], "objectSid",
698                                        &group_sids[num_groups])) {
699                         continue;
700                 }
701                 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
702
703                 num_groups += 1;
704                 if (num_groups == count) {
705                         break;
706                 }
707         }
708
709         *pp_sids = group_sids;
710         *pp_gids = gids;
711         *p_num_groups = num_groups;
712         return NT_STATUS_OK;
713 }
714
715 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
716                                                TALLOC_CTX *mem_ctx,
717                                                struct samu *user)
718 {
719         return NT_STATUS_NOT_IMPLEMENTED;
720 }
721
722 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
723                                      TALLOC_CTX *mem_ctx,
724                                      uint32 group_rid, uint32 member_rid)
725 {
726         return NT_STATUS_NOT_IMPLEMENTED;
727 }
728
729 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
730                                      TALLOC_CTX *mem_ctx,
731                                      uint32 group_rid, uint32 member_rid)
732 {
733         return NT_STATUS_NOT_IMPLEMENTED;
734 }
735
736 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
737                                      const char *name, uint32 *rid)
738 {
739         TALLOC_CTX *frame = talloc_stackframe();
740         struct pdb_ads_state *state = talloc_get_type_abort(
741                 m->private_data, struct pdb_ads_state);
742         const char *attrs[1] = { "objectSid" };
743         int num_mods = 0;
744         struct tldap_mod *mods = NULL;
745         struct tldap_message **alias;
746         struct dom_sid sid;
747         char *dn;
748         int rc;
749         bool ok = true;
750
751         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
752                              state->domaindn);
753         if (dn == NULL) {
754                 TALLOC_FREE(frame);
755                 return NT_STATUS_NO_MEMORY;
756         }
757
758         ok &= tldap_make_mod_fmt(
759                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
760                 name);
761         ok &= tldap_make_mod_fmt(
762                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
763         ok &= tldap_make_mod_fmt(
764                 NULL, talloc_tos(), &num_mods, &mods, "groupType",
765                 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
766
767         if (!ok) {
768                 TALLOC_FREE(frame);
769                 return NT_STATUS_NO_MEMORY;
770         }
771
772         rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
773         if (rc != TLDAP_SUCCESS) {
774                 DEBUG(10, ("ldap_add failed %s\n",
775                            tldap_errstr(debug_ctx(), state->ld, rc)));
776                 TALLOC_FREE(frame);
777                 return NT_STATUS_LDAP(rc);
778         }
779
780         rc = tldap_search_fmt(
781                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
782                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
783                 "(&(objectclass=group)(samaccountname=%s))", name);
784         if (rc != TLDAP_SUCCESS) {
785                 DEBUG(10, ("Could not find just created alias %s: %s\n",
786                            name, tldap_errstr(debug_ctx(), state->ld, rc)));
787                 TALLOC_FREE(frame);
788                 return NT_STATUS_LDAP(rc);
789         }
790
791         if (talloc_array_length(alias) != 1) {
792                 DEBUG(10, ("Got %d alias, expected one\n",
793                            (int)talloc_array_length(alias)));
794                 TALLOC_FREE(frame);
795                 return NT_STATUS_LDAP(rc);
796         }
797
798         if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
799                 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
800                            name));
801                 TALLOC_FREE(frame);
802                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
803         }
804
805         sid_peek_rid(&sid, rid);
806         TALLOC_FREE(frame);
807         return NT_STATUS_OK;
808 }
809
810 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
811                                      const DOM_SID *sid)
812 {
813         return NT_STATUS_NOT_IMPLEMENTED;
814 }
815
816 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
817                                       const DOM_SID *sid,
818                                       struct acct_info *info)
819 {
820         return NT_STATUS_NOT_IMPLEMENTED;
821 }
822
823 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
824                                       const DOM_SID *sid,
825                                       struct acct_info *info)
826 {
827         return NT_STATUS_NOT_IMPLEMENTED;
828 }
829
830 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
831                                      const DOM_SID *alias,
832                                      const DOM_SID *member)
833 {
834         return NT_STATUS_NOT_IMPLEMENTED;
835 }
836
837 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
838                                      const DOM_SID *alias,
839                                      const DOM_SID *member)
840 {
841         return NT_STATUS_NOT_IMPLEMENTED;
842 }
843
844 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
845                                       const DOM_SID *alias, DOM_SID **members,
846                                       size_t *p_num_members)
847 {
848         return NT_STATUS_NOT_IMPLEMENTED;
849 }
850
851 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
852                                                TALLOC_CTX *mem_ctx,
853                                                const DOM_SID *domain_sid,
854                                                const DOM_SID *members,
855                                                size_t num_members,
856                                                uint32 **pp_alias_rids,
857                                                size_t *p_num_alias_rids)
858 {
859         return NT_STATUS_NOT_IMPLEMENTED;
860 }
861
862 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
863                                     const DOM_SID *domain_sid,
864                                     int num_rids,
865                                     uint32 *rids,
866                                     const char **pp_names,
867                                     enum lsa_SidType *attrs)
868 {
869         return NT_STATUS_NOT_IMPLEMENTED;
870 }
871
872 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
873                                      const DOM_SID *domain_sid,
874                                      int num_names,
875                                      const char **pp_names,
876                                      uint32 *rids,
877                                      enum lsa_SidType *attrs)
878 {
879         return NT_STATUS_NOT_IMPLEMENTED;
880 }
881
882 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
883                                            int policy_index, uint32 *value)
884 {
885         return account_policy_get(policy_index, value)
886                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
887 }
888
889 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
890                                            int policy_index, uint32 value)
891 {
892         return account_policy_set(policy_index, value)
893                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
894 }
895
896 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
897                                     time_t *seq_num)
898 {
899         return NT_STATUS_NOT_IMPLEMENTED;
900 }
901
902 struct pdb_ads_search_state {
903         uint32_t acct_flags;
904         struct samr_displayentry *entries;
905         uint32_t num_entries;
906         ssize_t array_size;
907         uint32_t current;
908 };
909
910 static bool pdb_ads_next_entry(struct pdb_search *search,
911                                struct samr_displayentry *entry)
912 {
913         struct pdb_ads_search_state *state = talloc_get_type_abort(
914                 search->private_data, struct pdb_ads_search_state);
915
916         if (state->current == state->num_entries) {
917                 return false;
918         }
919
920         entry->idx = state->entries[state->current].idx;
921         entry->rid = state->entries[state->current].rid;
922         entry->acct_flags = state->entries[state->current].acct_flags;
923
924         entry->account_name = talloc_strdup(
925                 search, state->entries[state->current].account_name);
926         entry->fullname = talloc_strdup(
927                 search, state->entries[state->current].fullname);
928         entry->description = talloc_strdup(
929                 search, state->entries[state->current].description);
930
931         if ((entry->account_name == NULL) || (entry->fullname == NULL)
932             || (entry->description == NULL)) {
933                 DEBUG(0, ("talloc_strdup failed\n"));
934                 return false;
935         }
936
937         state->current += 1;
938         return true;
939 }
940
941 static void pdb_ads_search_end(struct pdb_search *search)
942 {
943         struct pdb_ads_search_state *state = talloc_get_type_abort(
944                 search->private_data, struct pdb_ads_search_state);
945         TALLOC_FREE(state);
946 }
947
948 static bool pdb_ads_search_filter(struct pdb_methods *m,
949                                   struct pdb_search *search,
950                                   const char *filter,
951                                   struct pdb_ads_search_state **pstate)
952 {
953         struct pdb_ads_state *state = talloc_get_type_abort(
954                 m->private_data, struct pdb_ads_state);
955         struct pdb_ads_search_state *sstate;
956         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
957                                  "userAccountControl", "description" };
958         struct tldap_message **users;
959         int i, rc, num_users;
960
961         sstate = talloc_zero(search, struct pdb_ads_search_state);
962         if (sstate == NULL) {
963                 return false;
964         }
965
966         rc = tldap_search_fmt(
967                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
968                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
969                 "%s", filter);
970         if (rc != TLDAP_SUCCESS) {
971                 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
972                            tldap_errstr(debug_ctx(), state->ld, rc)));
973                 return false;
974         }
975
976         num_users = talloc_array_length(users);
977
978         sstate->entries = talloc_array(sstate, struct samr_displayentry,
979                                        num_users);
980         if (sstate->entries == NULL) {
981                 DEBUG(10, ("talloc failed\n"));
982                 return false;
983         }
984
985         sstate->num_entries = 0;
986
987         for (i=0; i<num_users; i++) {
988                 struct samr_displayentry *e;
989                 struct dom_sid sid;
990
991                 e = &sstate->entries[sstate->num_entries];
992
993                 e->idx = sstate->num_entries;
994                 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
995                         DEBUG(10, ("Could not pull sid\n"));
996                         continue;
997                 }
998                 sid_peek_rid(&sid, &e->rid);
999                 e->acct_flags = ACB_NORMAL;
1000                 e->account_name = tldap_talloc_single_attribute(
1001                         users[i], "samAccountName", sstate->entries);
1002                 if (e->account_name == NULL) {
1003                         return false;
1004                 }
1005                 e->fullname = tldap_talloc_single_attribute(
1006                         users[i], "displayName", sstate->entries);
1007                 if (e->fullname == NULL) {
1008                         e->fullname = "";
1009                 }
1010                 e->description = tldap_talloc_single_attribute(
1011                         users[i], "description", sstate->entries);
1012                 if (e->description == NULL) {
1013                         e->description = "";
1014                 }
1015
1016                 sstate->num_entries += 1;
1017                 if (sstate->num_entries >= num_users) {
1018                         break;
1019                 }
1020         }
1021
1022         search->private_data = sstate;
1023         search->next_entry = pdb_ads_next_entry;
1024         search->search_end = pdb_ads_search_end;
1025         *pstate = sstate;
1026         return true;
1027 }
1028
1029 static bool pdb_ads_search_users(struct pdb_methods *m,
1030                                  struct pdb_search *search,
1031                                  uint32 acct_flags)
1032 {
1033         struct pdb_ads_search_state *sstate;
1034         bool ret;
1035
1036         ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1037         if (!ret) {
1038                 return false;
1039         }
1040         sstate->acct_flags = acct_flags;
1041         return true;
1042 }
1043
1044 static bool pdb_ads_search_groups(struct pdb_methods *m,
1045                                   struct pdb_search *search)
1046 {
1047         struct pdb_ads_search_state *sstate;
1048         char *filter;
1049         bool ret;
1050
1051         filter = talloc_asprintf(talloc_tos(),
1052                                  "(&(grouptype=%d)(objectclass=group))",
1053                                  GTYPE_SECURITY_GLOBAL_GROUP);
1054         if (filter == NULL) {
1055                 return false;
1056         }
1057         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1058         TALLOC_FREE(filter);
1059         if (!ret) {
1060                 return false;
1061         }
1062         sstate->acct_flags = 0;
1063         return true;
1064 }
1065
1066 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1067                                    struct pdb_search *search,
1068                                    const DOM_SID *sid)
1069 {
1070         struct pdb_ads_search_state *sstate;
1071         char *filter;
1072         bool ret;
1073
1074         filter = talloc_asprintf(
1075                 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1076                 sid_check_is_builtin(sid)
1077                 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1078                 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1079
1080         if (filter == NULL) {
1081                 return false;
1082         }
1083         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1084         TALLOC_FREE(filter);
1085         if (!ret) {
1086                 return false;
1087         }
1088         sstate->acct_flags = 0;
1089         return true;
1090 }
1091
1092 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1093                                uint32 *rid)
1094 {
1095         return false;
1096 }
1097
1098 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1099                                DOM_SID *sid)
1100 {
1101         struct pdb_ads_state *state = talloc_get_type_abort(
1102                 m->private_data, struct pdb_ads_state);
1103         sid_compose(sid, &state->domainsid, uid);
1104         return true;
1105 }
1106
1107 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1108                                DOM_SID *sid)
1109 {
1110         struct pdb_ads_state *state = talloc_get_type_abort(
1111                 m->private_data, struct pdb_ads_state);
1112         sid_compose(sid, &state->domainsid, gid);
1113         return true;
1114 }
1115
1116 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1117                               union unid_t *id, enum lsa_SidType *type)
1118 {
1119         struct pdb_ads_state *state = talloc_get_type_abort(
1120                 m->private_data, struct pdb_ads_state);
1121         struct tldap_message **msg;
1122         char *sidstr;
1123         uint32_t rid;
1124         int rc;
1125
1126         /*
1127          * This is a big, big hack: Just hard-code the rid as uid/gid.
1128          */
1129
1130         sid_peek_rid(sid, &rid);
1131
1132         sidstr = sid_binstring(talloc_tos(), sid);
1133         if (sidstr == NULL) {
1134                 return false;
1135         }
1136
1137         rc = tldap_search_fmt(
1138                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1139                 NULL, 0, 0, talloc_tos(), &msg,
1140                 "(&(objectsid=%s)(objectclass=user))", sidstr);
1141         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1142                 id->uid = rid;
1143                 *type = SID_NAME_USER;
1144                 TALLOC_FREE(sidstr);
1145                 return true;
1146         }
1147
1148         rc = tldap_search_fmt(
1149                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1150                 NULL, 0, 0, talloc_tos(), &msg,
1151                 "(&(objectsid=%s)(objectclass=group))", sidstr);
1152         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1153                 id->gid = rid;
1154                 *type = SID_NAME_DOM_GRP;
1155                 TALLOC_FREE(sidstr);
1156                 return true;
1157         }
1158
1159         TALLOC_FREE(sidstr);
1160         return false;
1161 }
1162
1163 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1164 {
1165         return false;
1166 }
1167
1168 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1169 {
1170         return false;
1171 }
1172
1173 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1174                                       const char *domain, char** pwd,
1175                                       DOM_SID *sid,
1176                                       time_t *pass_last_set_time)
1177 {
1178         return false;
1179 }
1180
1181 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1182                                       const char* domain, const char* pwd,
1183                                       const DOM_SID *sid)
1184 {
1185         return false;
1186 }
1187
1188 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1189                                       const char *domain)
1190 {
1191         return false;
1192 }
1193
1194 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1195                                          TALLOC_CTX *mem_ctx,
1196                                          uint32 *num_domains,
1197                                          struct trustdom_info ***domains)
1198 {
1199         return NT_STATUS_NOT_IMPLEMENTED;
1200 }
1201
1202 static void pdb_ads_init_methods(struct pdb_methods *m)
1203 {
1204         m->name = "ads";
1205         m->getsampwnam = pdb_ads_getsampwnam;
1206         m->getsampwsid = pdb_ads_getsampwsid;
1207         m->create_user = pdb_ads_create_user;
1208         m->delete_user = pdb_ads_delete_user;
1209         m->add_sam_account = pdb_ads_add_sam_account;
1210         m->update_sam_account = pdb_ads_update_sam_account;
1211         m->delete_sam_account = pdb_ads_delete_sam_account;
1212         m->rename_sam_account = pdb_ads_rename_sam_account;
1213         m->update_login_attempts = pdb_ads_update_login_attempts;
1214         m->getgrsid = pdb_ads_getgrsid;
1215         m->getgrgid = pdb_ads_getgrgid;
1216         m->getgrnam = pdb_ads_getgrnam;
1217         m->create_dom_group = pdb_ads_create_dom_group;
1218         m->delete_dom_group = pdb_ads_delete_dom_group;
1219         m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1220         m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1221         m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1222         m->enum_group_mapping = pdb_ads_enum_group_mapping;
1223         m->enum_group_members = pdb_ads_enum_group_members;
1224         m->enum_group_memberships = pdb_ads_enum_group_memberships;
1225         m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1226         m->add_groupmem = pdb_ads_add_groupmem;
1227         m->del_groupmem = pdb_ads_del_groupmem;
1228         m->create_alias = pdb_ads_create_alias;
1229         m->delete_alias = pdb_ads_delete_alias;
1230         m->get_aliasinfo = pdb_ads_get_aliasinfo;
1231         m->set_aliasinfo = pdb_ads_set_aliasinfo;
1232         m->add_aliasmem = pdb_ads_add_aliasmem;
1233         m->del_aliasmem = pdb_ads_del_aliasmem;
1234         m->enum_aliasmem = pdb_ads_enum_aliasmem;
1235         m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1236         m->lookup_rids = pdb_ads_lookup_rids;
1237         m->lookup_names = pdb_ads_lookup_names;
1238         m->get_account_policy = pdb_ads_get_account_policy;
1239         m->set_account_policy = pdb_ads_set_account_policy;
1240         m->get_seq_num = pdb_ads_get_seq_num;
1241         m->search_users = pdb_ads_search_users;
1242         m->search_groups = pdb_ads_search_groups;
1243         m->search_aliases = pdb_ads_search_aliases;
1244         m->uid_to_rid = pdb_ads_uid_to_rid;
1245         m->uid_to_sid = pdb_ads_uid_to_sid;
1246         m->gid_to_sid = pdb_ads_gid_to_sid;
1247         m->sid_to_id = pdb_ads_sid_to_id;
1248         m->rid_algorithm = pdb_ads_rid_algorithm;
1249         m->new_rid = pdb_ads_new_rid;
1250         m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1251         m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1252         m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1253         m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1254 }
1255
1256 static void free_private_data(void **vp)
1257 {
1258         struct pdb_ads_state *state = talloc_get_type_abort(
1259                 *vp, struct pdb_ads_state);
1260
1261         TALLOC_FREE(state->ld);
1262         return;
1263 }
1264
1265 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1266                                 const char *location)
1267 {
1268         const char *rootdse_attrs[2] = {
1269                 "defaultNamingContext", "configurationNamingContext" };
1270         const char *domain_attrs[1] = { "objectSid" };
1271         const char *ncname_attrs[1] = { "netbiosname" };
1272         struct tldap_message **rootdse, **domain, **ncname;
1273         TALLOC_CTX *frame = talloc_stackframe();
1274         struct sockaddr_un sunaddr;
1275         NTSTATUS status;
1276         int num_domains;
1277         int fd, rc;
1278
1279         ZERO_STRUCT(sunaddr);
1280         sunaddr.sun_family = AF_UNIX;
1281         strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1282
1283         status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1284                                  0, 0, &fd);
1285         if (!NT_STATUS_IS_OK(status)) {
1286                 DEBUG(10, ("Could not connect to %s: %s\n", location,
1287                            nt_errstr(status)));
1288                 goto done;
1289         }
1290
1291         state->ld = tldap_context_create(state, fd);
1292         if (state->ld == NULL) {
1293                 close(fd);
1294                 status = NT_STATUS_NO_MEMORY;
1295                 goto done;
1296         }
1297
1298         rc = tldap_search_fmt(
1299                 state->ld, "", TLDAP_SCOPE_BASE,
1300                 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1301                 talloc_tos(), &rootdse, "(objectclass=*)");
1302         if (rc != TLDAP_SUCCESS) {
1303                 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1304                            tldap_errstr(debug_ctx(), state->ld, rc)));
1305                 status = NT_STATUS_LDAP(rc);
1306                 goto done;
1307         }
1308         if (talloc_array_length(rootdse) != 1) {
1309                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1310                 goto done;
1311         }
1312
1313         state->domaindn = tldap_talloc_single_attribute(
1314                 rootdse[0], "defaultNamingContext", state);
1315         if (state->domaindn == NULL) {
1316                 DEBUG(10, ("Could not get defaultNamingContext\n"));
1317                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1318                 goto done;
1319         }
1320         DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1321
1322         state->configdn = tldap_talloc_single_attribute(
1323                 rootdse[0], "configurationNamingContext", state);
1324         if (state->domaindn == NULL) {
1325                 DEBUG(10, ("Could not get configurationNamingContext\n"));
1326                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1327                 goto done;
1328         }
1329         DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1330
1331         /*
1332          * Figure out our domain's SID
1333          */
1334         rc = tldap_search_fmt(
1335                 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1336                 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1337                 talloc_tos(), &domain, "(objectclass=*)");
1338         if (rc != TLDAP_SUCCESS) {
1339                 DEBUG(10, ("Could not retrieve domain: %s\n",
1340                            tldap_errstr(debug_ctx(), state->ld, rc)));
1341                 status = NT_STATUS_LDAP(rc);
1342                 goto done;
1343         }
1344
1345         num_domains = talloc_array_length(domain);
1346         if (num_domains != 1) {
1347                 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1348                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1349                 goto done;
1350         }
1351         if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1352                 DEBUG(10, ("Could not retrieve domain SID\n"));
1353                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1354                 goto done;
1355         }
1356         DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1357
1358         /*
1359          * Figure out our domain's short name
1360          */
1361         rc = tldap_search_fmt(
1362                 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1363                 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1364                 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1365         if (rc != TLDAP_SUCCESS) {
1366                 DEBUG(10, ("Could not retrieve ncname: %s\n",
1367                            tldap_errstr(debug_ctx(), state->ld, rc)));
1368                 status = NT_STATUS_LDAP(rc);
1369                 goto done;
1370         }
1371         if (talloc_array_length(ncname) != 1) {
1372                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1373                 goto done;
1374         }
1375
1376         state->netbiosname = tldap_talloc_single_attribute(
1377                 ncname[0], "netbiosname", state);
1378         if (state->netbiosname == NULL) {
1379                 DEBUG(10, ("Could not get netbiosname\n"));
1380                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1381                 goto done;
1382         }
1383         DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1384
1385         if (!strequal(lp_workgroup(), state->netbiosname)) {
1386                 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1387                           state->netbiosname, lp_workgroup()));
1388                 status = NT_STATUS_NO_SUCH_DOMAIN;
1389                 goto done;
1390         }
1391
1392         secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1393
1394         status = NT_STATUS_OK;
1395 done:
1396         TALLOC_FREE(frame);
1397         return status;
1398 }
1399
1400 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1401                              const char *location)
1402 {
1403         struct pdb_methods *m;
1404         struct pdb_ads_state *state;
1405         char *tmp = NULL;
1406         NTSTATUS status;
1407
1408         m = talloc(talloc_autofree_context(), struct pdb_methods);
1409         if (m == NULL) {
1410                 return NT_STATUS_NO_MEMORY;
1411         }
1412         state = talloc(m, struct pdb_ads_state);
1413         if (state == NULL) {
1414                 goto nomem;
1415         }
1416         m->private_data = state;
1417         m->free_private_data = free_private_data;
1418         pdb_ads_init_methods(m);
1419
1420         if (location == NULL) {
1421                 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1422                                       lp_private_dir());
1423                 location = tmp;
1424         }
1425         if (location == NULL) {
1426                 goto nomem;
1427         }
1428
1429         status = pdb_ads_connect(state, location);
1430         if (!NT_STATUS_IS_OK(status)) {
1431                 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1432                 goto fail;
1433         }
1434
1435         *pdb_method = m;
1436         return NT_STATUS_OK;
1437 nomem:
1438         status = NT_STATUS_NO_MEMORY;
1439 fail:
1440         TALLOC_FREE(m);
1441         return status;
1442 }
1443
1444 NTSTATUS pdb_ads_init(void);
1445 NTSTATUS pdb_ads_init(void)
1446 {
1447         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
1448                                    pdb_init_ads);
1449 }