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