Activate tldap tracing in pdb_ads
[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_set_aliasinfo(struct pdb_methods *m,
1111                                       const DOM_SID *sid,
1112                                       struct acct_info *info)
1113 {
1114         struct pdb_ads_state *state = talloc_get_type_abort(
1115                 m->private_data, struct pdb_ads_state);
1116         const char *attrs[3] = { "objectSid", "description",
1117                                  "samAccountName" };
1118         struct tldap_message **msg;
1119         char *sidstr, *dn;
1120         int rc;
1121         struct tldap_mod *mods;
1122         int num_mods;
1123         bool ok;
1124
1125         sidstr = sid_binstring(talloc_tos(), sid);
1126         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1127
1128         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1129                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1130                               &msg, "(&(objectSid=%s)(objectclass=group)"
1131                               "(|(grouptype=%d)(grouptype=%d)))",
1132                               sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1133                               GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1134         TALLOC_FREE(sidstr);
1135         if (rc != TLDAP_SUCCESS) {
1136                 DEBUG(10, ("ldap_search failed %s\n",
1137                            tldap_errstr(debug_ctx(), state->ld, rc)));
1138                 return NT_STATUS_LDAP(rc);
1139         }
1140         switch talloc_array_length(msg) {
1141         case 0:
1142                 return NT_STATUS_NO_SUCH_ALIAS;
1143         case 1:
1144                 break;
1145         default:
1146                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1147         }
1148
1149         if (!tldap_entry_dn(msg[0], &dn)) {
1150                 TALLOC_FREE(msg);
1151                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1152         }
1153
1154         mods = NULL;
1155         num_mods = 0;
1156         ok = true;
1157
1158         ok &= tldap_make_mod_fmt(
1159                 msg[0], msg, &num_mods, &mods, "description",
1160                 "%s", info->acct_desc);
1161         ok &= tldap_make_mod_fmt(
1162                 msg[0], msg, &num_mods, &mods, "samAccountName",
1163                 "%s", info->acct_name);
1164         if (!ok) {
1165                 TALLOC_FREE(msg);
1166                 return NT_STATUS_NO_MEMORY;
1167         }
1168         if (num_mods == 0) {
1169                 /* no change */
1170                 TALLOC_FREE(msg);
1171                 return NT_STATUS_OK;
1172         }
1173
1174         rc = tldap_modify(state->ld, dn, num_mods, mods, NULL, NULL);
1175         TALLOC_FREE(msg);
1176         if (rc != TLDAP_SUCCESS) {
1177                 DEBUG(10, ("ldap_modify failed: %s\n",
1178                            tldap_errstr(debug_ctx(), state->ld, rc)));
1179                 return NT_STATUS_LDAP(rc);
1180         }
1181         return NT_STATUS_OK;
1182 }
1183
1184 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1185                                const struct dom_sid *sid,
1186                                TALLOC_CTX *mem_ctx, char **pdn)
1187 {
1188         struct tldap_message **msg;
1189         char *sidstr, *dn;
1190         int rc;
1191
1192         sidstr = sid_binstring(talloc_tos(), sid);
1193         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1194
1195         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1196                               NULL, 0, 0, talloc_tos(), &msg,
1197                               "(objectsid=%s)", sidstr);
1198         TALLOC_FREE(sidstr);
1199         if (rc != TLDAP_SUCCESS) {
1200                 DEBUG(10, ("ldap_search failed %s\n",
1201                            tldap_errstr(debug_ctx(), state->ld, rc)));
1202                 return NT_STATUS_LDAP(rc);
1203         }
1204
1205         switch talloc_array_length(msg) {
1206         case 0:
1207                 return NT_STATUS_NOT_FOUND;
1208         case 1:
1209                 break;
1210         default:
1211                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1212         }
1213
1214         if (!tldap_entry_dn(msg[0], &dn)) {
1215                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1216         }
1217
1218         dn = talloc_strdup(mem_ctx, dn);
1219         if (dn == NULL) {
1220                 return NT_STATUS_NO_MEMORY;
1221         }
1222         TALLOC_FREE(msg);
1223
1224         *pdn = dn;
1225         return NT_STATUS_OK;
1226 }
1227
1228 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1229                                      const DOM_SID *alias,
1230                                      const DOM_SID *member,
1231                                      int mod_op)
1232 {
1233         struct pdb_ads_state *state = talloc_get_type_abort(
1234                 m->private_data, struct pdb_ads_state);
1235         TALLOC_CTX *frame = talloc_stackframe();
1236         struct tldap_mod *mods;
1237         int rc;
1238         char *aliasdn, *memberdn;
1239         NTSTATUS status;
1240
1241         status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1242         if (!NT_STATUS_IS_OK(status)) {
1243                 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1244                            sid_string_dbg(alias), nt_errstr(status)));
1245                 TALLOC_FREE(frame);
1246                 return NT_STATUS_NO_SUCH_ALIAS;
1247         }
1248         status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1249         if (!NT_STATUS_IS_OK(status)) {
1250                 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1251                            sid_string_dbg(member), nt_errstr(status)));
1252                 TALLOC_FREE(frame);
1253                 return status;
1254         }
1255
1256         mods = NULL;
1257
1258         if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1259                                "member", memberdn)) {
1260                 TALLOC_FREE(frame);
1261                 return NT_STATUS_NO_MEMORY;
1262         }
1263
1264         rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
1265         TALLOC_FREE(frame);
1266         if (rc != TLDAP_SUCCESS) {
1267                 DEBUG(10, ("ldap_modify failed: %s\n",
1268                            tldap_errstr(debug_ctx(), state->ld, rc)));
1269                 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1270                         return NT_STATUS_MEMBER_IN_ALIAS;
1271                 }
1272                 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1273                         return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1274                 }
1275                 return NT_STATUS_LDAP(rc);
1276         }
1277
1278         return NT_STATUS_OK;
1279 }
1280
1281 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1282                                      const DOM_SID *alias,
1283                                      const DOM_SID *member)
1284 {
1285         return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1286 }
1287
1288 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1289                                      const DOM_SID *alias,
1290                                      const DOM_SID *member)
1291 {
1292         return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1293 }
1294
1295 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1296                                struct dom_sid *psid)
1297 {
1298         const char *attrs[1] = { "objectSid" };
1299         struct tldap_message **msg;
1300         char *dn;
1301         size_t len;
1302         int rc;
1303         bool ret;
1304
1305         if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1306                                    dnblob->data, dnblob->length, &dn, &len,
1307                                    false)) {
1308                 return false;
1309         }
1310         rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1311                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1312                               &msg, "(objectclass=*)");
1313         TALLOC_FREE(dn);
1314         if (talloc_array_length(msg) != 1) {
1315                 DEBUG(10, ("Got %d objects, expected one\n",
1316                            (int)talloc_array_length(msg)));
1317                 TALLOC_FREE(msg);
1318                 return false;
1319         }
1320
1321         ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1322         TALLOC_FREE(msg);
1323         return ret;
1324 }
1325
1326 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1327                                       const DOM_SID *alias,
1328                                       TALLOC_CTX *mem_ctx,
1329                                       DOM_SID **pmembers,
1330                                       size_t *pnum_members)
1331 {
1332         struct pdb_ads_state *state = talloc_get_type_abort(
1333                 m->private_data, struct pdb_ads_state);
1334         const char *attrs[1] = { "member" };
1335         char *sidstr;
1336         struct tldap_message **msg;
1337         int i, rc, num_members;
1338         DATA_BLOB *blobs;
1339         struct dom_sid *members;
1340
1341         sidstr = sid_binstring(talloc_tos(), alias);
1342         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1343
1344         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1345                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1346                               "(objectsid=%s)", sidstr);
1347         TALLOC_FREE(sidstr);
1348         if (rc != TLDAP_SUCCESS) {
1349                 DEBUG(10, ("ldap_search failed %s\n",
1350                            tldap_errstr(debug_ctx(), state->ld, rc)));
1351                 return NT_STATUS_LDAP(rc);
1352         }
1353         switch talloc_array_length(msg) {
1354         case 0:
1355                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1356                 break;
1357         case 1:
1358                 break;
1359         default:
1360                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1361                 break;
1362         }
1363
1364         if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1365                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1366         }
1367
1368         members = talloc_array(mem_ctx, struct dom_sid, num_members);
1369         if (members == NULL) {
1370                 return NT_STATUS_NO_MEMORY;
1371         }
1372
1373         for (i=0; i<num_members; i++) {
1374                 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1375                         TALLOC_FREE(members);
1376                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1377                 }
1378         }
1379
1380         *pmembers = members;
1381         *pnum_members = num_members;
1382         return NT_STATUS_OK;
1383 }
1384
1385 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1386                                                TALLOC_CTX *mem_ctx,
1387                                                const DOM_SID *domain_sid,
1388                                                const DOM_SID *members,
1389                                                size_t num_members,
1390                                                uint32_t **palias_rids,
1391                                                size_t *pnum_alias_rids)
1392 {
1393         struct pdb_ads_state *state = talloc_get_type_abort(
1394                 m->private_data, struct pdb_ads_state);
1395         const char *attrs[1] = { "objectSid" };
1396         struct tldap_message **msg;
1397         uint32_t *alias_rids = NULL;
1398         size_t num_alias_rids = 0;
1399         int i, rc, count;
1400         bool got_members = false;
1401         char *filter;
1402         NTSTATUS status;
1403
1404         /*
1405          * TODO: Get the filter right so that we only get the aliases from
1406          * either the SAM or BUILTIN
1407          */
1408
1409         filter = talloc_asprintf(talloc_tos(),
1410                                  "(&(|(grouptype=%d)(grouptype=%d))"
1411                                  "(objectclass=group)(|",
1412                                  GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1413                                  GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1414         if (filter == NULL) {
1415                 return NT_STATUS_NO_MEMORY;
1416         }
1417
1418         for (i=0; i<num_members; i++) {
1419                 char *dn;
1420
1421                 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1422                 if (!NT_STATUS_IS_OK(status)) {
1423                         DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1424                                    sid_string_dbg(&members[i]),
1425                                    nt_errstr(status)));
1426                         continue;
1427                 }
1428                 filter = talloc_asprintf_append_buffer(
1429                         filter, "(member=%s)", dn);
1430                 TALLOC_FREE(dn);
1431                 if (filter == NULL) {
1432                         return NT_STATUS_NO_MEMORY;
1433                 }
1434                 got_members = true;
1435         }
1436
1437         if (!got_members) {
1438                 goto done;
1439         }
1440
1441         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1442                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1443                               &msg, "%s))", filter);
1444         TALLOC_FREE(filter);
1445         if (rc != TLDAP_SUCCESS) {
1446                 DEBUG(10, ("tldap_search failed %s\n",
1447                            tldap_errstr(debug_ctx(), state->ld, rc)));
1448                 return NT_STATUS_LDAP(rc);
1449         }
1450
1451         count = talloc_array_length(msg);
1452         if (count == 0) {
1453                 goto done;
1454         }
1455
1456         alias_rids = talloc_array(mem_ctx, uint32_t, count);
1457         if (alias_rids == NULL) {
1458                 TALLOC_FREE(msg);
1459                 return NT_STATUS_NO_MEMORY;
1460         }
1461
1462         for (i=0; i<count; i++) {
1463                 struct dom_sid sid;
1464
1465                 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1466                         DEBUG(10, ("Could not pull SID for member %d\n", i));
1467                         continue;
1468                 }
1469                 if (sid_peek_check_rid(domain_sid, &sid,
1470                                        &alias_rids[num_alias_rids])) {
1471                         num_alias_rids += 1;
1472                 }
1473         }
1474 done:
1475         TALLOC_FREE(msg);
1476         *palias_rids = alias_rids;
1477         *pnum_alias_rids = 0;
1478         return NT_STATUS_OK;
1479 }
1480
1481 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1482                                     const DOM_SID *domain_sid,
1483                                     int num_rids,
1484                                     uint32 *rids,
1485                                     const char **names,
1486                                     enum lsa_SidType *lsa_attrs)
1487 {
1488         struct pdb_ads_state *state = talloc_get_type_abort(
1489                 m->private_data, struct pdb_ads_state);
1490         const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1491         int i, num_mapped;
1492
1493         if (num_rids == 0) {
1494                 return NT_STATUS_NONE_MAPPED;
1495         }
1496
1497         num_mapped = 0;
1498
1499         for (i=0; i<num_rids; i++) {
1500                 struct dom_sid sid;
1501                 struct tldap_message **msg;
1502                 char *sidstr;
1503                 uint32_t attr;
1504                 int rc;
1505
1506                 lsa_attrs[i] = SID_NAME_UNKNOWN;
1507
1508                 sid_compose(&sid, domain_sid, rids[i]);
1509
1510                 sidstr = sid_binstring(talloc_tos(), &sid);
1511                 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1512
1513                 rc = tldap_search_fmt(state->ld, state->domaindn,
1514                                       TLDAP_SCOPE_SUB, attrs,
1515                                       ARRAY_SIZE(attrs), 0, talloc_tos(),
1516                                       &msg, "(objectsid=%s)", sidstr);
1517                 TALLOC_FREE(sidstr);
1518                 if (rc != TLDAP_SUCCESS) {
1519                         DEBUG(10, ("ldap_search failed %s\n",
1520                                    tldap_errstr(debug_ctx(), state->ld, rc)));
1521                         continue;
1522                 }
1523
1524                 switch talloc_array_length(msg) {
1525                 case 0:
1526                         DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1527                         continue;
1528                 case 1:
1529                         break;
1530                 default:
1531                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1532                 }
1533
1534                 names[i] = tldap_talloc_single_attribute(
1535                         msg[0], "samAccountName", talloc_tos());
1536                 if (names[i] == NULL) {
1537                         DEBUG(10, ("no samAccountName\n"));
1538                         continue;
1539                 }
1540                 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1541                         DEBUG(10, ("no samAccountType"));
1542                         continue;
1543                 }
1544                 lsa_attrs[i] = ads_atype_map(attr);
1545                 num_mapped += 1;
1546         }
1547
1548         if (num_mapped == 0) {
1549                 return NT_STATUS_NONE_MAPPED;
1550         }
1551         if (num_mapped < num_rids) {
1552                 return STATUS_SOME_UNMAPPED;
1553         }
1554         return NT_STATUS_OK;
1555 }
1556
1557 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1558                                      const DOM_SID *domain_sid,
1559                                      int num_names,
1560                                      const char **pp_names,
1561                                      uint32 *rids,
1562                                      enum lsa_SidType *attrs)
1563 {
1564         return NT_STATUS_NOT_IMPLEMENTED;
1565 }
1566
1567 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1568                                            int policy_index, uint32 *value)
1569 {
1570         return account_policy_get(policy_index, value)
1571                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1572 }
1573
1574 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1575                                            int policy_index, uint32 value)
1576 {
1577         return account_policy_set(policy_index, value)
1578                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1579 }
1580
1581 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1582                                     time_t *seq_num)
1583 {
1584         return NT_STATUS_NOT_IMPLEMENTED;
1585 }
1586
1587 struct pdb_ads_search_state {
1588         uint32_t acct_flags;
1589         struct samr_displayentry *entries;
1590         uint32_t num_entries;
1591         ssize_t array_size;
1592         uint32_t current;
1593 };
1594
1595 static bool pdb_ads_next_entry(struct pdb_search *search,
1596                                struct samr_displayentry *entry)
1597 {
1598         struct pdb_ads_search_state *state = talloc_get_type_abort(
1599                 search->private_data, struct pdb_ads_search_state);
1600
1601         if (state->current == state->num_entries) {
1602                 return false;
1603         }
1604
1605         entry->idx = state->entries[state->current].idx;
1606         entry->rid = state->entries[state->current].rid;
1607         entry->acct_flags = state->entries[state->current].acct_flags;
1608
1609         entry->account_name = talloc_strdup(
1610                 search, state->entries[state->current].account_name);
1611         entry->fullname = talloc_strdup(
1612                 search, state->entries[state->current].fullname);
1613         entry->description = talloc_strdup(
1614                 search, state->entries[state->current].description);
1615
1616         if ((entry->account_name == NULL) || (entry->fullname == NULL)
1617             || (entry->description == NULL)) {
1618                 DEBUG(0, ("talloc_strdup failed\n"));
1619                 return false;
1620         }
1621
1622         state->current += 1;
1623         return true;
1624 }
1625
1626 static void pdb_ads_search_end(struct pdb_search *search)
1627 {
1628         struct pdb_ads_search_state *state = talloc_get_type_abort(
1629                 search->private_data, struct pdb_ads_search_state);
1630         TALLOC_FREE(state);
1631 }
1632
1633 static bool pdb_ads_search_filter(struct pdb_methods *m,
1634                                   struct pdb_search *search,
1635                                   const char *filter,
1636                                   struct pdb_ads_search_state **pstate)
1637 {
1638         struct pdb_ads_state *state = talloc_get_type_abort(
1639                 m->private_data, struct pdb_ads_state);
1640         struct pdb_ads_search_state *sstate;
1641         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1642                                  "userAccountControl", "description" };
1643         struct tldap_message **users;
1644         int i, rc, num_users;
1645
1646         sstate = talloc_zero(search, struct pdb_ads_search_state);
1647         if (sstate == NULL) {
1648                 return false;
1649         }
1650
1651         rc = tldap_search_fmt(
1652                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1653                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1654                 "%s", filter);
1655         if (rc != TLDAP_SUCCESS) {
1656                 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1657                            tldap_errstr(debug_ctx(), state->ld, rc)));
1658                 return false;
1659         }
1660
1661         num_users = talloc_array_length(users);
1662
1663         sstate->entries = talloc_array(sstate, struct samr_displayentry,
1664                                        num_users);
1665         if (sstate->entries == NULL) {
1666                 DEBUG(10, ("talloc failed\n"));
1667                 return false;
1668         }
1669
1670         sstate->num_entries = 0;
1671
1672         for (i=0; i<num_users; i++) {
1673                 struct samr_displayentry *e;
1674                 struct dom_sid sid;
1675
1676                 e = &sstate->entries[sstate->num_entries];
1677
1678                 e->idx = sstate->num_entries;
1679                 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1680                         DEBUG(10, ("Could not pull sid\n"));
1681                         continue;
1682                 }
1683                 sid_peek_rid(&sid, &e->rid);
1684                 e->acct_flags = ACB_NORMAL;
1685                 e->account_name = tldap_talloc_single_attribute(
1686                         users[i], "samAccountName", sstate->entries);
1687                 if (e->account_name == NULL) {
1688                         return false;
1689                 }
1690                 e->fullname = tldap_talloc_single_attribute(
1691                         users[i], "displayName", sstate->entries);
1692                 if (e->fullname == NULL) {
1693                         e->fullname = "";
1694                 }
1695                 e->description = tldap_talloc_single_attribute(
1696                         users[i], "description", sstate->entries);
1697                 if (e->description == NULL) {
1698                         e->description = "";
1699                 }
1700
1701                 sstate->num_entries += 1;
1702                 if (sstate->num_entries >= num_users) {
1703                         break;
1704                 }
1705         }
1706
1707         search->private_data = sstate;
1708         search->next_entry = pdb_ads_next_entry;
1709         search->search_end = pdb_ads_search_end;
1710         *pstate = sstate;
1711         return true;
1712 }
1713
1714 static bool pdb_ads_search_users(struct pdb_methods *m,
1715                                  struct pdb_search *search,
1716                                  uint32 acct_flags)
1717 {
1718         struct pdb_ads_search_state *sstate;
1719         bool ret;
1720
1721         ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1722         if (!ret) {
1723                 return false;
1724         }
1725         sstate->acct_flags = acct_flags;
1726         return true;
1727 }
1728
1729 static bool pdb_ads_search_groups(struct pdb_methods *m,
1730                                   struct pdb_search *search)
1731 {
1732         struct pdb_ads_search_state *sstate;
1733         char *filter;
1734         bool ret;
1735
1736         filter = talloc_asprintf(talloc_tos(),
1737                                  "(&(grouptype=%d)(objectclass=group))",
1738                                  GTYPE_SECURITY_GLOBAL_GROUP);
1739         if (filter == NULL) {
1740                 return false;
1741         }
1742         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1743         TALLOC_FREE(filter);
1744         if (!ret) {
1745                 return false;
1746         }
1747         sstate->acct_flags = 0;
1748         return true;
1749 }
1750
1751 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1752                                    struct pdb_search *search,
1753                                    const DOM_SID *sid)
1754 {
1755         struct pdb_ads_search_state *sstate;
1756         char *filter;
1757         bool ret;
1758
1759         filter = talloc_asprintf(
1760                 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1761                 sid_check_is_builtin(sid)
1762                 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1763                 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1764
1765         if (filter == NULL) {
1766                 return false;
1767         }
1768         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1769         TALLOC_FREE(filter);
1770         if (!ret) {
1771                 return false;
1772         }
1773         sstate->acct_flags = 0;
1774         return true;
1775 }
1776
1777 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1778                                uint32 *rid)
1779 {
1780         return false;
1781 }
1782
1783 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1784                                DOM_SID *sid)
1785 {
1786         struct pdb_ads_state *state = talloc_get_type_abort(
1787                 m->private_data, struct pdb_ads_state);
1788         sid_compose(sid, &state->domainsid, uid);
1789         return true;
1790 }
1791
1792 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1793                                DOM_SID *sid)
1794 {
1795         struct pdb_ads_state *state = talloc_get_type_abort(
1796                 m->private_data, struct pdb_ads_state);
1797         sid_compose(sid, &state->domainsid, gid);
1798         return true;
1799 }
1800
1801 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1802                               union unid_t *id, enum lsa_SidType *type)
1803 {
1804         struct pdb_ads_state *state = talloc_get_type_abort(
1805                 m->private_data, struct pdb_ads_state);
1806         struct tldap_message **msg;
1807         char *sidstr;
1808         uint32_t rid;
1809         int rc;
1810
1811         /*
1812          * This is a big, big hack: Just hard-code the rid as uid/gid.
1813          */
1814
1815         sid_peek_rid(sid, &rid);
1816
1817         sidstr = sid_binstring(talloc_tos(), sid);
1818         if (sidstr == NULL) {
1819                 return false;
1820         }
1821
1822         rc = tldap_search_fmt(
1823                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1824                 NULL, 0, 0, talloc_tos(), &msg,
1825                 "(&(objectsid=%s)(objectclass=user))", sidstr);
1826         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1827                 id->uid = rid;
1828                 *type = SID_NAME_USER;
1829                 TALLOC_FREE(sidstr);
1830                 return true;
1831         }
1832
1833         rc = tldap_search_fmt(
1834                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1835                 NULL, 0, 0, talloc_tos(), &msg,
1836                 "(&(objectsid=%s)(objectclass=group))", sidstr);
1837         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1838                 id->gid = rid;
1839                 *type = SID_NAME_DOM_GRP;
1840                 TALLOC_FREE(sidstr);
1841                 return true;
1842         }
1843
1844         TALLOC_FREE(sidstr);
1845         return false;
1846 }
1847
1848 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1849 {
1850         return false;
1851 }
1852
1853 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1854 {
1855         return false;
1856 }
1857
1858 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1859                                       const char *domain, char** pwd,
1860                                       DOM_SID *sid,
1861                                       time_t *pass_last_set_time)
1862 {
1863         return false;
1864 }
1865
1866 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1867                                       const char* domain, const char* pwd,
1868                                       const DOM_SID *sid)
1869 {
1870         return false;
1871 }
1872
1873 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1874                                       const char *domain)
1875 {
1876         return false;
1877 }
1878
1879 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1880                                          TALLOC_CTX *mem_ctx,
1881                                          uint32 *num_domains,
1882                                          struct trustdom_info ***domains)
1883 {
1884         return NT_STATUS_NOT_IMPLEMENTED;
1885 }
1886
1887 static void pdb_ads_init_methods(struct pdb_methods *m)
1888 {
1889         m->name = "ads";
1890         m->getsampwnam = pdb_ads_getsampwnam;
1891         m->getsampwsid = pdb_ads_getsampwsid;
1892         m->create_user = pdb_ads_create_user;
1893         m->delete_user = pdb_ads_delete_user;
1894         m->add_sam_account = pdb_ads_add_sam_account;
1895         m->update_sam_account = pdb_ads_update_sam_account;
1896         m->delete_sam_account = pdb_ads_delete_sam_account;
1897         m->rename_sam_account = pdb_ads_rename_sam_account;
1898         m->update_login_attempts = pdb_ads_update_login_attempts;
1899         m->getgrsid = pdb_ads_getgrsid;
1900         m->getgrgid = pdb_ads_getgrgid;
1901         m->getgrnam = pdb_ads_getgrnam;
1902         m->create_dom_group = pdb_ads_create_dom_group;
1903         m->delete_dom_group = pdb_ads_delete_dom_group;
1904         m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1905         m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1906         m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1907         m->enum_group_mapping = pdb_ads_enum_group_mapping;
1908         m->enum_group_members = pdb_ads_enum_group_members;
1909         m->enum_group_memberships = pdb_ads_enum_group_memberships;
1910         m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1911         m->add_groupmem = pdb_ads_add_groupmem;
1912         m->del_groupmem = pdb_ads_del_groupmem;
1913         m->create_alias = pdb_ads_create_alias;
1914         m->delete_alias = pdb_ads_delete_alias;
1915         m->get_aliasinfo = pdb_default_get_aliasinfo;
1916         m->set_aliasinfo = pdb_ads_set_aliasinfo;
1917         m->add_aliasmem = pdb_ads_add_aliasmem;
1918         m->del_aliasmem = pdb_ads_del_aliasmem;
1919         m->enum_aliasmem = pdb_ads_enum_aliasmem;
1920         m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1921         m->lookup_rids = pdb_ads_lookup_rids;
1922         m->lookup_names = pdb_ads_lookup_names;
1923         m->get_account_policy = pdb_ads_get_account_policy;
1924         m->set_account_policy = pdb_ads_set_account_policy;
1925         m->get_seq_num = pdb_ads_get_seq_num;
1926         m->search_users = pdb_ads_search_users;
1927         m->search_groups = pdb_ads_search_groups;
1928         m->search_aliases = pdb_ads_search_aliases;
1929         m->uid_to_rid = pdb_ads_uid_to_rid;
1930         m->uid_to_sid = pdb_ads_uid_to_sid;
1931         m->gid_to_sid = pdb_ads_gid_to_sid;
1932         m->sid_to_id = pdb_ads_sid_to_id;
1933         m->rid_algorithm = pdb_ads_rid_algorithm;
1934         m->new_rid = pdb_ads_new_rid;
1935         m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1936         m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1937         m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1938         m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1939 }
1940
1941 static void free_private_data(void **vp)
1942 {
1943         struct pdb_ads_state *state = talloc_get_type_abort(
1944                 *vp, struct pdb_ads_state);
1945
1946         TALLOC_FREE(state->ld);
1947         return;
1948 }
1949
1950 /*
1951   this is used to catch debug messages from events
1952 */
1953 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
1954                            const char *fmt, va_list ap)  PRINTF_ATTRIBUTE(3,0);
1955
1956 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
1957                            const char *fmt, va_list ap)
1958 {
1959         int samba_level = -1;
1960         char *s = NULL;
1961         switch (level) {
1962         case TLDAP_DEBUG_FATAL:
1963                 samba_level = 0;
1964                 break;
1965         case TLDAP_DEBUG_ERROR:
1966                 samba_level = 1;
1967                 break;
1968         case TLDAP_DEBUG_WARNING:
1969                 samba_level = 2;
1970                 break;
1971         case TLDAP_DEBUG_TRACE:
1972                 samba_level = 10;
1973                 break;
1974
1975         };
1976         if (vasprintf(&s, fmt, ap) == -1) {
1977                 return;
1978         }
1979         DEBUG(samba_level, ("tldap: %s", s));
1980         free(s);
1981 }
1982
1983 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1984                                 const char *location)
1985 {
1986         const char *rootdse_attrs[2] = {
1987                 "defaultNamingContext", "configurationNamingContext" };
1988         const char *domain_attrs[1] = { "objectSid" };
1989         const char *ncname_attrs[1] = { "netbiosname" };
1990         struct tldap_message **rootdse, **domain, **ncname;
1991         TALLOC_CTX *frame = talloc_stackframe();
1992         struct sockaddr_un sunaddr;
1993         NTSTATUS status;
1994         int num_domains;
1995         int fd, rc;
1996
1997         ZERO_STRUCT(sunaddr);
1998         sunaddr.sun_family = AF_UNIX;
1999         strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
2000
2001         status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
2002                                  0, 0, &fd);
2003         if (!NT_STATUS_IS_OK(status)) {
2004                 DEBUG(10, ("Could not connect to %s: %s\n", location,
2005                            nt_errstr(status)));
2006                 goto done;
2007         }
2008
2009         state->ld = tldap_context_create(state, fd);
2010         if (state->ld == NULL) {
2011                 close(fd);
2012                 status = NT_STATUS_NO_MEMORY;
2013                 goto done;
2014         }
2015         tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2016
2017         rc = tldap_search_fmt(
2018                 state->ld, "", TLDAP_SCOPE_BASE,
2019                 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
2020                 talloc_tos(), &rootdse, "(objectclass=*)");
2021         if (rc != TLDAP_SUCCESS) {
2022                 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2023                            tldap_errstr(debug_ctx(), state->ld, rc)));
2024                 status = NT_STATUS_LDAP(rc);
2025                 goto done;
2026         }
2027         if (talloc_array_length(rootdse) != 1) {
2028                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2029                 goto done;
2030         }
2031
2032         state->domaindn = tldap_talloc_single_attribute(
2033                 rootdse[0], "defaultNamingContext", state);
2034         if (state->domaindn == NULL) {
2035                 DEBUG(10, ("Could not get defaultNamingContext\n"));
2036                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2037                 goto done;
2038         }
2039         DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2040
2041         state->configdn = tldap_talloc_single_attribute(
2042                 rootdse[0], "configurationNamingContext", state);
2043         if (state->domaindn == NULL) {
2044                 DEBUG(10, ("Could not get configurationNamingContext\n"));
2045                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2046                 goto done;
2047         }
2048         DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2049
2050         /*
2051          * Figure out our domain's SID
2052          */
2053         rc = tldap_search_fmt(
2054                 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
2055                 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2056                 talloc_tos(), &domain, "(objectclass=*)");
2057         if (rc != TLDAP_SUCCESS) {
2058                 DEBUG(10, ("Could not retrieve domain: %s\n",
2059                            tldap_errstr(debug_ctx(), state->ld, rc)));
2060                 status = NT_STATUS_LDAP(rc);
2061                 goto done;
2062         }
2063
2064         num_domains = talloc_array_length(domain);
2065         if (num_domains != 1) {
2066                 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2067                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2068                 goto done;
2069         }
2070         if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2071                 DEBUG(10, ("Could not retrieve domain SID\n"));
2072                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2073                 goto done;
2074         }
2075         DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2076
2077         /*
2078          * Figure out our domain's short name
2079          */
2080         rc = tldap_search_fmt(
2081                 state->ld, state->configdn, TLDAP_SCOPE_SUB,
2082                 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2083                 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2084         if (rc != TLDAP_SUCCESS) {
2085                 DEBUG(10, ("Could not retrieve ncname: %s\n",
2086                            tldap_errstr(debug_ctx(), state->ld, rc)));
2087                 status = NT_STATUS_LDAP(rc);
2088                 goto done;
2089         }
2090         if (talloc_array_length(ncname) != 1) {
2091                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2092                 goto done;
2093         }
2094
2095         state->netbiosname = tldap_talloc_single_attribute(
2096                 ncname[0], "netbiosname", state);
2097         if (state->netbiosname == NULL) {
2098                 DEBUG(10, ("Could not get netbiosname\n"));
2099                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2100                 goto done;
2101         }
2102         DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2103
2104         if (!strequal(lp_workgroup(), state->netbiosname)) {
2105                 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2106                           state->netbiosname, lp_workgroup()));
2107                 status = NT_STATUS_NO_SUCH_DOMAIN;
2108                 goto done;
2109         }
2110
2111         secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2112
2113         status = NT_STATUS_OK;
2114 done:
2115         TALLOC_FREE(frame);
2116         return status;
2117 }
2118
2119 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2120                              const char *location)
2121 {
2122         struct pdb_methods *m;
2123         struct pdb_ads_state *state;
2124         char *tmp = NULL;
2125         NTSTATUS status;
2126
2127         m = talloc(talloc_autofree_context(), struct pdb_methods);
2128         if (m == NULL) {
2129                 return NT_STATUS_NO_MEMORY;
2130         }
2131         state = talloc(m, struct pdb_ads_state);
2132         if (state == NULL) {
2133                 goto nomem;
2134         }
2135         m->private_data = state;
2136         m->free_private_data = free_private_data;
2137         pdb_ads_init_methods(m);
2138
2139         if (location == NULL) {
2140                 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2141                                       lp_private_dir());
2142                 location = tmp;
2143         }
2144         if (location == NULL) {
2145                 goto nomem;
2146         }
2147
2148         status = pdb_ads_connect(state, location);
2149         if (!NT_STATUS_IS_OK(status)) {
2150                 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2151                 goto fail;
2152         }
2153
2154         *pdb_method = m;
2155         return NT_STATUS_OK;
2156 nomem:
2157         status = NT_STATUS_NO_MEMORY;
2158 fail:
2159         TALLOC_FREE(m);
2160         return status;
2161 }
2162
2163 NTSTATUS pdb_ads_init(void);
2164 NTSTATUS pdb_ads_init(void)
2165 {
2166         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
2167                                    pdb_init_ads);
2168 }