3081046f2d87ef89d01263cada8b2b160bf11597
[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 **pp_names,
1341                                     enum lsa_SidType *attrs)
1342 {
1343         return NT_STATUS_NOT_IMPLEMENTED;
1344 }
1345
1346 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1347                                      const DOM_SID *domain_sid,
1348                                      int num_names,
1349                                      const char **pp_names,
1350                                      uint32 *rids,
1351                                      enum lsa_SidType *attrs)
1352 {
1353         return NT_STATUS_NOT_IMPLEMENTED;
1354 }
1355
1356 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1357                                            int policy_index, uint32 *value)
1358 {
1359         return account_policy_get(policy_index, value)
1360                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1361 }
1362
1363 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1364                                            int policy_index, uint32 value)
1365 {
1366         return account_policy_set(policy_index, value)
1367                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1368 }
1369
1370 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1371                                     time_t *seq_num)
1372 {
1373         return NT_STATUS_NOT_IMPLEMENTED;
1374 }
1375
1376 struct pdb_ads_search_state {
1377         uint32_t acct_flags;
1378         struct samr_displayentry *entries;
1379         uint32_t num_entries;
1380         ssize_t array_size;
1381         uint32_t current;
1382 };
1383
1384 static bool pdb_ads_next_entry(struct pdb_search *search,
1385                                struct samr_displayentry *entry)
1386 {
1387         struct pdb_ads_search_state *state = talloc_get_type_abort(
1388                 search->private_data, struct pdb_ads_search_state);
1389
1390         if (state->current == state->num_entries) {
1391                 return false;
1392         }
1393
1394         entry->idx = state->entries[state->current].idx;
1395         entry->rid = state->entries[state->current].rid;
1396         entry->acct_flags = state->entries[state->current].acct_flags;
1397
1398         entry->account_name = talloc_strdup(
1399                 search, state->entries[state->current].account_name);
1400         entry->fullname = talloc_strdup(
1401                 search, state->entries[state->current].fullname);
1402         entry->description = talloc_strdup(
1403                 search, state->entries[state->current].description);
1404
1405         if ((entry->account_name == NULL) || (entry->fullname == NULL)
1406             || (entry->description == NULL)) {
1407                 DEBUG(0, ("talloc_strdup failed\n"));
1408                 return false;
1409         }
1410
1411         state->current += 1;
1412         return true;
1413 }
1414
1415 static void pdb_ads_search_end(struct pdb_search *search)
1416 {
1417         struct pdb_ads_search_state *state = talloc_get_type_abort(
1418                 search->private_data, struct pdb_ads_search_state);
1419         TALLOC_FREE(state);
1420 }
1421
1422 static bool pdb_ads_search_filter(struct pdb_methods *m,
1423                                   struct pdb_search *search,
1424                                   const char *filter,
1425                                   struct pdb_ads_search_state **pstate)
1426 {
1427         struct pdb_ads_state *state = talloc_get_type_abort(
1428                 m->private_data, struct pdb_ads_state);
1429         struct pdb_ads_search_state *sstate;
1430         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1431                                  "userAccountControl", "description" };
1432         struct tldap_message **users;
1433         int i, rc, num_users;
1434
1435         sstate = talloc_zero(search, struct pdb_ads_search_state);
1436         if (sstate == NULL) {
1437                 return false;
1438         }
1439
1440         rc = tldap_search_fmt(
1441                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1442                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1443                 "%s", filter);
1444         if (rc != TLDAP_SUCCESS) {
1445                 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1446                            tldap_errstr(debug_ctx(), state->ld, rc)));
1447                 return false;
1448         }
1449
1450         num_users = talloc_array_length(users);
1451
1452         sstate->entries = talloc_array(sstate, struct samr_displayentry,
1453                                        num_users);
1454         if (sstate->entries == NULL) {
1455                 DEBUG(10, ("talloc failed\n"));
1456                 return false;
1457         }
1458
1459         sstate->num_entries = 0;
1460
1461         for (i=0; i<num_users; i++) {
1462                 struct samr_displayentry *e;
1463                 struct dom_sid sid;
1464
1465                 e = &sstate->entries[sstate->num_entries];
1466
1467                 e->idx = sstate->num_entries;
1468                 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1469                         DEBUG(10, ("Could not pull sid\n"));
1470                         continue;
1471                 }
1472                 sid_peek_rid(&sid, &e->rid);
1473                 e->acct_flags = ACB_NORMAL;
1474                 e->account_name = tldap_talloc_single_attribute(
1475                         users[i], "samAccountName", sstate->entries);
1476                 if (e->account_name == NULL) {
1477                         return false;
1478                 }
1479                 e->fullname = tldap_talloc_single_attribute(
1480                         users[i], "displayName", sstate->entries);
1481                 if (e->fullname == NULL) {
1482                         e->fullname = "";
1483                 }
1484                 e->description = tldap_talloc_single_attribute(
1485                         users[i], "description", sstate->entries);
1486                 if (e->description == NULL) {
1487                         e->description = "";
1488                 }
1489
1490                 sstate->num_entries += 1;
1491                 if (sstate->num_entries >= num_users) {
1492                         break;
1493                 }
1494         }
1495
1496         search->private_data = sstate;
1497         search->next_entry = pdb_ads_next_entry;
1498         search->search_end = pdb_ads_search_end;
1499         *pstate = sstate;
1500         return true;
1501 }
1502
1503 static bool pdb_ads_search_users(struct pdb_methods *m,
1504                                  struct pdb_search *search,
1505                                  uint32 acct_flags)
1506 {
1507         struct pdb_ads_search_state *sstate;
1508         bool ret;
1509
1510         ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1511         if (!ret) {
1512                 return false;
1513         }
1514         sstate->acct_flags = acct_flags;
1515         return true;
1516 }
1517
1518 static bool pdb_ads_search_groups(struct pdb_methods *m,
1519                                   struct pdb_search *search)
1520 {
1521         struct pdb_ads_search_state *sstate;
1522         char *filter;
1523         bool ret;
1524
1525         filter = talloc_asprintf(talloc_tos(),
1526                                  "(&(grouptype=%d)(objectclass=group))",
1527                                  GTYPE_SECURITY_GLOBAL_GROUP);
1528         if (filter == NULL) {
1529                 return false;
1530         }
1531         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1532         TALLOC_FREE(filter);
1533         if (!ret) {
1534                 return false;
1535         }
1536         sstate->acct_flags = 0;
1537         return true;
1538 }
1539
1540 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1541                                    struct pdb_search *search,
1542                                    const DOM_SID *sid)
1543 {
1544         struct pdb_ads_search_state *sstate;
1545         char *filter;
1546         bool ret;
1547
1548         filter = talloc_asprintf(
1549                 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1550                 sid_check_is_builtin(sid)
1551                 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1552                 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1553
1554         if (filter == NULL) {
1555                 return false;
1556         }
1557         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1558         TALLOC_FREE(filter);
1559         if (!ret) {
1560                 return false;
1561         }
1562         sstate->acct_flags = 0;
1563         return true;
1564 }
1565
1566 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1567                                uint32 *rid)
1568 {
1569         return false;
1570 }
1571
1572 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1573                                DOM_SID *sid)
1574 {
1575         struct pdb_ads_state *state = talloc_get_type_abort(
1576                 m->private_data, struct pdb_ads_state);
1577         sid_compose(sid, &state->domainsid, uid);
1578         return true;
1579 }
1580
1581 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1582                                DOM_SID *sid)
1583 {
1584         struct pdb_ads_state *state = talloc_get_type_abort(
1585                 m->private_data, struct pdb_ads_state);
1586         sid_compose(sid, &state->domainsid, gid);
1587         return true;
1588 }
1589
1590 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1591                               union unid_t *id, enum lsa_SidType *type)
1592 {
1593         struct pdb_ads_state *state = talloc_get_type_abort(
1594                 m->private_data, struct pdb_ads_state);
1595         struct tldap_message **msg;
1596         char *sidstr;
1597         uint32_t rid;
1598         int rc;
1599
1600         /*
1601          * This is a big, big hack: Just hard-code the rid as uid/gid.
1602          */
1603
1604         sid_peek_rid(sid, &rid);
1605
1606         sidstr = sid_binstring(talloc_tos(), sid);
1607         if (sidstr == NULL) {
1608                 return false;
1609         }
1610
1611         rc = tldap_search_fmt(
1612                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1613                 NULL, 0, 0, talloc_tos(), &msg,
1614                 "(&(objectsid=%s)(objectclass=user))", sidstr);
1615         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1616                 id->uid = rid;
1617                 *type = SID_NAME_USER;
1618                 TALLOC_FREE(sidstr);
1619                 return true;
1620         }
1621
1622         rc = tldap_search_fmt(
1623                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1624                 NULL, 0, 0, talloc_tos(), &msg,
1625                 "(&(objectsid=%s)(objectclass=group))", sidstr);
1626         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1627                 id->gid = rid;
1628                 *type = SID_NAME_DOM_GRP;
1629                 TALLOC_FREE(sidstr);
1630                 return true;
1631         }
1632
1633         TALLOC_FREE(sidstr);
1634         return false;
1635 }
1636
1637 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1638 {
1639         return false;
1640 }
1641
1642 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1643 {
1644         return false;
1645 }
1646
1647 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1648                                       const char *domain, char** pwd,
1649                                       DOM_SID *sid,
1650                                       time_t *pass_last_set_time)
1651 {
1652         return false;
1653 }
1654
1655 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1656                                       const char* domain, const char* pwd,
1657                                       const DOM_SID *sid)
1658 {
1659         return false;
1660 }
1661
1662 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1663                                       const char *domain)
1664 {
1665         return false;
1666 }
1667
1668 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1669                                          TALLOC_CTX *mem_ctx,
1670                                          uint32 *num_domains,
1671                                          struct trustdom_info ***domains)
1672 {
1673         return NT_STATUS_NOT_IMPLEMENTED;
1674 }
1675
1676 static void pdb_ads_init_methods(struct pdb_methods *m)
1677 {
1678         m->name = "ads";
1679         m->getsampwnam = pdb_ads_getsampwnam;
1680         m->getsampwsid = pdb_ads_getsampwsid;
1681         m->create_user = pdb_ads_create_user;
1682         m->delete_user = pdb_ads_delete_user;
1683         m->add_sam_account = pdb_ads_add_sam_account;
1684         m->update_sam_account = pdb_ads_update_sam_account;
1685         m->delete_sam_account = pdb_ads_delete_sam_account;
1686         m->rename_sam_account = pdb_ads_rename_sam_account;
1687         m->update_login_attempts = pdb_ads_update_login_attempts;
1688         m->getgrsid = pdb_ads_getgrsid;
1689         m->getgrgid = pdb_ads_getgrgid;
1690         m->getgrnam = pdb_ads_getgrnam;
1691         m->create_dom_group = pdb_ads_create_dom_group;
1692         m->delete_dom_group = pdb_ads_delete_dom_group;
1693         m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1694         m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1695         m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1696         m->enum_group_mapping = pdb_ads_enum_group_mapping;
1697         m->enum_group_members = pdb_ads_enum_group_members;
1698         m->enum_group_memberships = pdb_ads_enum_group_memberships;
1699         m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1700         m->add_groupmem = pdb_ads_add_groupmem;
1701         m->del_groupmem = pdb_ads_del_groupmem;
1702         m->create_alias = pdb_ads_create_alias;
1703         m->delete_alias = pdb_ads_delete_alias;
1704         m->get_aliasinfo = pdb_ads_get_aliasinfo;
1705         m->set_aliasinfo = pdb_ads_set_aliasinfo;
1706         m->add_aliasmem = pdb_ads_add_aliasmem;
1707         m->del_aliasmem = pdb_ads_del_aliasmem;
1708         m->enum_aliasmem = pdb_ads_enum_aliasmem;
1709         m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1710         m->lookup_rids = pdb_ads_lookup_rids;
1711         m->lookup_names = pdb_ads_lookup_names;
1712         m->get_account_policy = pdb_ads_get_account_policy;
1713         m->set_account_policy = pdb_ads_set_account_policy;
1714         m->get_seq_num = pdb_ads_get_seq_num;
1715         m->search_users = pdb_ads_search_users;
1716         m->search_groups = pdb_ads_search_groups;
1717         m->search_aliases = pdb_ads_search_aliases;
1718         m->uid_to_rid = pdb_ads_uid_to_rid;
1719         m->uid_to_sid = pdb_ads_uid_to_sid;
1720         m->gid_to_sid = pdb_ads_gid_to_sid;
1721         m->sid_to_id = pdb_ads_sid_to_id;
1722         m->rid_algorithm = pdb_ads_rid_algorithm;
1723         m->new_rid = pdb_ads_new_rid;
1724         m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1725         m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1726         m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1727         m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1728 }
1729
1730 static void free_private_data(void **vp)
1731 {
1732         struct pdb_ads_state *state = talloc_get_type_abort(
1733                 *vp, struct pdb_ads_state);
1734
1735         TALLOC_FREE(state->ld);
1736         return;
1737 }
1738
1739 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1740                                 const char *location)
1741 {
1742         const char *rootdse_attrs[2] = {
1743                 "defaultNamingContext", "configurationNamingContext" };
1744         const char *domain_attrs[1] = { "objectSid" };
1745         const char *ncname_attrs[1] = { "netbiosname" };
1746         struct tldap_message **rootdse, **domain, **ncname;
1747         TALLOC_CTX *frame = talloc_stackframe();
1748         struct sockaddr_un sunaddr;
1749         NTSTATUS status;
1750         int num_domains;
1751         int fd, rc;
1752
1753         ZERO_STRUCT(sunaddr);
1754         sunaddr.sun_family = AF_UNIX;
1755         strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1756
1757         status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1758                                  0, 0, &fd);
1759         if (!NT_STATUS_IS_OK(status)) {
1760                 DEBUG(10, ("Could not connect to %s: %s\n", location,
1761                            nt_errstr(status)));
1762                 goto done;
1763         }
1764
1765         state->ld = tldap_context_create(state, fd);
1766         if (state->ld == NULL) {
1767                 close(fd);
1768                 status = NT_STATUS_NO_MEMORY;
1769                 goto done;
1770         }
1771
1772         rc = tldap_search_fmt(
1773                 state->ld, "", TLDAP_SCOPE_BASE,
1774                 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1775                 talloc_tos(), &rootdse, "(objectclass=*)");
1776         if (rc != TLDAP_SUCCESS) {
1777                 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1778                            tldap_errstr(debug_ctx(), state->ld, rc)));
1779                 status = NT_STATUS_LDAP(rc);
1780                 goto done;
1781         }
1782         if (talloc_array_length(rootdse) != 1) {
1783                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1784                 goto done;
1785         }
1786
1787         state->domaindn = tldap_talloc_single_attribute(
1788                 rootdse[0], "defaultNamingContext", state);
1789         if (state->domaindn == NULL) {
1790                 DEBUG(10, ("Could not get defaultNamingContext\n"));
1791                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1792                 goto done;
1793         }
1794         DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1795
1796         state->configdn = tldap_talloc_single_attribute(
1797                 rootdse[0], "configurationNamingContext", state);
1798         if (state->domaindn == NULL) {
1799                 DEBUG(10, ("Could not get configurationNamingContext\n"));
1800                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1801                 goto done;
1802         }
1803         DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1804
1805         /*
1806          * Figure out our domain's SID
1807          */
1808         rc = tldap_search_fmt(
1809                 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1810                 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1811                 talloc_tos(), &domain, "(objectclass=*)");
1812         if (rc != TLDAP_SUCCESS) {
1813                 DEBUG(10, ("Could not retrieve domain: %s\n",
1814                            tldap_errstr(debug_ctx(), state->ld, rc)));
1815                 status = NT_STATUS_LDAP(rc);
1816                 goto done;
1817         }
1818
1819         num_domains = talloc_array_length(domain);
1820         if (num_domains != 1) {
1821                 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1822                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1823                 goto done;
1824         }
1825         if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1826                 DEBUG(10, ("Could not retrieve domain SID\n"));
1827                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1828                 goto done;
1829         }
1830         DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1831
1832         /*
1833          * Figure out our domain's short name
1834          */
1835         rc = tldap_search_fmt(
1836                 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1837                 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1838                 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1839         if (rc != TLDAP_SUCCESS) {
1840                 DEBUG(10, ("Could not retrieve ncname: %s\n",
1841                            tldap_errstr(debug_ctx(), state->ld, rc)));
1842                 status = NT_STATUS_LDAP(rc);
1843                 goto done;
1844         }
1845         if (talloc_array_length(ncname) != 1) {
1846                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1847                 goto done;
1848         }
1849
1850         state->netbiosname = tldap_talloc_single_attribute(
1851                 ncname[0], "netbiosname", state);
1852         if (state->netbiosname == NULL) {
1853                 DEBUG(10, ("Could not get netbiosname\n"));
1854                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1855                 goto done;
1856         }
1857         DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1858
1859         if (!strequal(lp_workgroup(), state->netbiosname)) {
1860                 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1861                           state->netbiosname, lp_workgroup()));
1862                 status = NT_STATUS_NO_SUCH_DOMAIN;
1863                 goto done;
1864         }
1865
1866         secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1867
1868         status = NT_STATUS_OK;
1869 done:
1870         TALLOC_FREE(frame);
1871         return status;
1872 }
1873
1874 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1875                              const char *location)
1876 {
1877         struct pdb_methods *m;
1878         struct pdb_ads_state *state;
1879         char *tmp = NULL;
1880         NTSTATUS status;
1881
1882         m = talloc(talloc_autofree_context(), struct pdb_methods);
1883         if (m == NULL) {
1884                 return NT_STATUS_NO_MEMORY;
1885         }
1886         state = talloc(m, struct pdb_ads_state);
1887         if (state == NULL) {
1888                 goto nomem;
1889         }
1890         m->private_data = state;
1891         m->free_private_data = free_private_data;
1892         pdb_ads_init_methods(m);
1893
1894         if (location == NULL) {
1895                 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1896                                       lp_private_dir());
1897                 location = tmp;
1898         }
1899         if (location == NULL) {
1900                 goto nomem;
1901         }
1902
1903         status = pdb_ads_connect(state, location);
1904         if (!NT_STATUS_IS_OK(status)) {
1905                 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1906                 goto fail;
1907         }
1908
1909         *pdb_method = m;
1910         return NT_STATUS_OK;
1911 nomem:
1912         status = NT_STATUS_NO_MEMORY;
1913 fail:
1914         TALLOC_FREE(m);
1915         return status;
1916 }
1917
1918 NTSTATUS pdb_ads_init(void);
1919 NTSTATUS pdb_ads_init(void)
1920 {
1921         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
1922                                    pdb_init_ads);
1923 }