Prepare control support
[kai/samba.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         DATA_BLOB blob;
262
263         /* TODO: All fields :-) */
264
265         ret &= tldap_make_mod_fmt(
266                 existing, mem_ctx, pnum_mods, pmods, "displayName",
267                 "%s", pdb_get_fullname(sam));
268
269         blob = data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN);
270         ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
271                                    "unicodePwd", 1, &blob);
272
273         blob = data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN);
274         ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
275                                    "dBCSPwd", 1, &blob);
276
277         ret &= tldap_make_mod_fmt(
278                 existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
279                 "%d", ads_acb2uf(pdb_get_acct_ctrl(sam)));
280
281         ret &= tldap_make_mod_fmt(
282                 existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
283                 "%s", pdb_get_homedir(sam));
284
285         ret &= tldap_make_mod_fmt(
286                 existing, mem_ctx, pnum_mods, pmods, "homeDrive",
287                 "%s", pdb_get_dir_drive(sam));
288
289         ret &= tldap_make_mod_fmt(
290                 existing, mem_ctx, pnum_mods, pmods, "scriptPath",
291                 "%s", pdb_get_logon_script(sam));
292
293         ret &= tldap_make_mod_fmt(
294                 existing, mem_ctx, pnum_mods, pmods, "profilePath",
295                 "%s", pdb_get_profile_path(sam));
296
297         return ret;
298 }
299
300 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
301                                        struct pdb_ads_state *state,
302                                        struct samu *sam_acct,
303                                        const char *filter)
304 {
305         const char * attrs[] = {
306                 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
307                 "sAMAccountName", "displayName", "homeDirectory",
308                 "homeDrive", "scriptPath", "profilePath", "description",
309                 "userWorkstations", "comment", "userParameters", "objectSid",
310                 "primaryGroupID", "userAccountControl", "logonHours",
311                 "badPwdCount", "logonCount", "countryCode", "codePage",
312                 "unicodePwd", "dBCSPwd" };
313         struct tldap_message **users;
314         int rc, count;
315
316         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
317                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
318                               &users, "%s", filter);
319         if (rc != TLDAP_SUCCESS) {
320                 DEBUG(10, ("ldap_search failed %s\n",
321                            tldap_errstr(debug_ctx(), state->ld, rc)));
322                 return NT_STATUS_LDAP(rc);
323         }
324
325         count = talloc_array_length(users);
326         if (count != 1) {
327                 DEBUG(10, ("Expected 1 user, got %d\n", count));
328                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
329         }
330
331         return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]);
332 }
333
334 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
335                                     struct samu *sam_acct,
336                                     const char *username)
337 {
338         struct pdb_ads_state *state = talloc_get_type_abort(
339                 m->private_data, struct pdb_ads_state);
340         char *filter;
341
342         filter = talloc_asprintf(
343                 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
344                 username);
345         NT_STATUS_HAVE_NO_MEMORY(filter);
346
347         return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
348 }
349
350 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
351                                     struct samu *sam_acct,
352                                     const DOM_SID *sid)
353 {
354         struct pdb_ads_state *state = talloc_get_type_abort(
355                 m->private_data, struct pdb_ads_state);
356         char *sidstr, *filter;
357
358         sidstr = sid_binstring(talloc_tos(), sid);
359         NT_STATUS_HAVE_NO_MEMORY(sidstr);
360
361         filter = talloc_asprintf(
362                 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
363         TALLOC_FREE(sidstr);
364         NT_STATUS_HAVE_NO_MEMORY(filter);
365
366         return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
367 }
368
369 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
370                                     TALLOC_CTX *tmp_ctx,
371                                     const char *name, uint32 acct_flags,
372                                     uint32 *rid)
373 {
374         struct pdb_ads_state *state = talloc_get_type_abort(
375                 m->private_data, struct pdb_ads_state);
376         const char *attrs[1] = { "objectSid" };
377         struct tldap_mod *mods = NULL;
378         int num_mods = 0;
379         struct tldap_message **user;
380         struct dom_sid sid;
381         char *dn;
382         int rc;
383         bool ok;
384
385         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
386                              state->domaindn);
387         if (dn == NULL) {
388                 return NT_STATUS_NO_MEMORY;
389         }
390
391         /* TODO: Create machines etc */
392
393         ok = true;
394         ok &= tldap_make_mod_fmt(
395                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
396         ok &= tldap_make_mod_fmt(
397                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
398                 name);
399         if (!ok) {
400                 return NT_STATUS_NO_MEMORY;
401         }
402
403         rc = tldap_add(state->ld, dn, num_mods, mods, NULL, 0, NULL, 0);
404         if (rc != TLDAP_SUCCESS) {
405                 DEBUG(10, ("ldap_add failed %s\n",
406                            tldap_errstr(debug_ctx(), state->ld, rc)));
407                 TALLOC_FREE(dn);
408                 return NT_STATUS_LDAP(rc);
409         }
410
411         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
412                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &user,
413                              "(&(objectclass=user)(samaccountname=%s))",
414                              name);
415         if (rc != TLDAP_SUCCESS) {
416                 DEBUG(10, ("Could not find just created user %s: %s\n",
417                            name, tldap_errstr(debug_ctx(), state->ld, rc)));
418                 TALLOC_FREE(dn);
419                 return NT_STATUS_LDAP(rc);
420         }
421
422         if (talloc_array_length(user) != 1) {
423                 DEBUG(10, ("Got %d users, expected one\n",
424                            (int)talloc_array_length(user)));
425                 TALLOC_FREE(dn);
426                 return NT_STATUS_LDAP(rc);
427         }
428
429         if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
430                 DEBUG(10, ("Could not fetch objectSid from user %s\n",
431                            name));
432                 TALLOC_FREE(dn);
433                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
434         }
435
436         sid_peek_rid(&sid, rid);
437         TALLOC_FREE(dn);
438         return NT_STATUS_OK;
439 }
440
441 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
442                                     TALLOC_CTX *tmp_ctx,
443                                     struct samu *sam)
444 {
445         struct pdb_ads_state *state = talloc_get_type_abort(
446                 m->private_data, struct pdb_ads_state);
447         NTSTATUS status;
448         char *dn;
449         int rc;
450
451         status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
452                                 &dn);
453         if (!NT_STATUS_IS_OK(status)) {
454                 return status;
455         }
456
457         rc = tldap_delete(state->ld, dn, NULL, 0, NULL, 0);
458         TALLOC_FREE(dn);
459         if (rc != TLDAP_SUCCESS) {
460                 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
461                            tldap_errstr(debug_ctx(), state->ld, rc)));
462                 return NT_STATUS_LDAP(rc);
463         }
464         return NT_STATUS_OK;
465 }
466
467 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
468                                         struct samu *sampass)
469 {
470         return NT_STATUS_NOT_IMPLEMENTED;
471 }
472
473 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
474                                            struct samu *sam)
475 {
476         struct pdb_ads_state *state = talloc_get_type_abort(
477                 m->private_data, struct pdb_ads_state);
478         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
479         struct tldap_mod *mods = NULL;
480         int rc, num_mods = 0;
481
482         if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
483                                        &num_mods, &mods, sam)) {
484                 return NT_STATUS_NO_MEMORY;
485         }
486
487         if (num_mods == 0) {
488                 /* Nothing to do, just return success */
489                 return NT_STATUS_OK;
490         }
491
492         rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, 0,
493                           NULL, 0);
494         if (rc != TLDAP_SUCCESS) {
495                 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
496                            tldap_errstr(debug_ctx(), state->ld, rc)));
497                 return NT_STATUS_LDAP(rc);
498         }
499
500         TALLOC_FREE(mods);
501
502         return NT_STATUS_OK;
503 }
504
505 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
506                                            struct samu *username)
507 {
508         return NT_STATUS_NOT_IMPLEMENTED;
509 }
510
511 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
512                                            struct samu *oldname,
513                                            const char *newname)
514 {
515         return NT_STATUS_NOT_IMPLEMENTED;
516 }
517
518 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
519                                               struct samu *sam_acct,
520                                               bool success)
521 {
522         return NT_STATUS_NOT_IMPLEMENTED;
523 }
524
525 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
526                                     const char *filter)
527 {
528         struct pdb_ads_state *state = talloc_get_type_abort(
529                 m->private_data, struct pdb_ads_state);
530         const char *attrs[4] = { "objectSid", "description", "samAccountName",
531                                  "groupType" };
532         char *str;
533         struct tldap_message **group;
534         uint32_t grouptype;
535         int rc;
536
537         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
538                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
539                               &group, "%s", filter);
540         if (rc != TLDAP_SUCCESS) {
541                 DEBUG(10, ("ldap_search failed %s\n",
542                            tldap_errstr(debug_ctx(), state->ld, rc)));
543                 return NT_STATUS_LDAP(rc);
544         }
545         if (talloc_array_length(group) != 1) {
546                 DEBUG(10, ("Expected 1 user, got %d\n",
547                            (int)talloc_array_length(group)));
548                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
549         }
550
551         if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
552                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
553         }
554         map->gid = pdb_ads_sid2gid(&map->sid);
555
556         if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
557                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
558         }
559         switch (grouptype) {
560         case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
561         case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
562                 map->sid_name_use = SID_NAME_ALIAS;
563                 break;
564         case GTYPE_SECURITY_GLOBAL_GROUP:
565                 map->sid_name_use = SID_NAME_DOM_GRP;
566                 break;
567         default:
568                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
569         }
570
571         str = tldap_talloc_single_attribute(group[0], "samAccountName",
572                                             talloc_tos());
573         if (str == NULL) {
574                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
575         }
576         fstrcpy(map->nt_name, str);
577         TALLOC_FREE(str);
578
579         str = tldap_talloc_single_attribute(group[0], "description",
580                                             talloc_tos());
581         if (str != NULL) {
582                 fstrcpy(map->comment, str);
583                 TALLOC_FREE(str);
584         } else {
585                 map->comment[0] = '\0';
586         }
587
588         TALLOC_FREE(group);
589         return NT_STATUS_OK;
590 }
591
592 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
593                                  DOM_SID sid)
594 {
595         char *filter;
596         NTSTATUS status;
597
598         filter = talloc_asprintf(talloc_tos(),
599                                  "(&(objectsid=%s)(objectclass=group))",
600                                  sid_string_talloc(talloc_tos(), &sid));
601         if (filter == NULL) {
602                 return NT_STATUS_NO_MEMORY;
603         }
604
605         status = pdb_ads_getgrfilter(m, map, filter);
606         TALLOC_FREE(filter);
607         return status;
608 }
609
610 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
611                                  gid_t gid)
612 {
613         struct dom_sid sid;
614         pdb_ads_gid_to_sid(m, gid, &sid);
615         return pdb_ads_getgrsid(m, map, sid);
616 }
617
618 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
619                                  const char *name)
620 {
621         char *filter;
622         NTSTATUS status;
623
624         filter = talloc_asprintf(talloc_tos(),
625                                  "(&(samaccountname=%s)(objectclass=group))",
626                                  name);
627         if (filter == NULL) {
628                 return NT_STATUS_NO_MEMORY;
629         }
630
631         status = pdb_ads_getgrfilter(m, map, filter);
632         TALLOC_FREE(filter);
633         return status;
634 }
635
636 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
637                                          TALLOC_CTX *mem_ctx, const char *name,
638                                          uint32 *rid)
639 {
640         TALLOC_CTX *frame = talloc_stackframe();
641         struct pdb_ads_state *state = talloc_get_type_abort(
642                 m->private_data, struct pdb_ads_state);
643         const char *attrs[1] = { "objectSid" };
644         int num_mods = 0;
645         struct tldap_mod *mods = NULL;
646         struct tldap_message **alias;
647         struct dom_sid sid;
648         char *dn;
649         int rc;
650         bool ok = true;
651
652         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
653                              state->domaindn);
654         if (dn == NULL) {
655                 TALLOC_FREE(frame);
656                 return NT_STATUS_NO_MEMORY;
657         }
658
659         ok &= tldap_make_mod_fmt(
660                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
661                 name);
662         ok &= tldap_make_mod_fmt(
663                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
664         ok &= tldap_make_mod_fmt(
665                 NULL, talloc_tos(), &num_mods, &mods, "groupType",
666                 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
667
668         if (!ok) {
669                 TALLOC_FREE(frame);
670                 return NT_STATUS_NO_MEMORY;
671         }
672
673         rc = tldap_add(state->ld, dn, num_mods, mods, NULL, 0, NULL, 0);
674         if (rc != TLDAP_SUCCESS) {
675                 DEBUG(10, ("ldap_add failed %s\n",
676                            tldap_errstr(debug_ctx(), state->ld, rc)));
677                 TALLOC_FREE(frame);
678                 return NT_STATUS_LDAP(rc);
679         }
680
681         rc = tldap_search_fmt(
682                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
683                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
684                 "(&(objectclass=group)(samaccountname=%s))", name);
685         if (rc != TLDAP_SUCCESS) {
686                 DEBUG(10, ("Could not find just created alias %s: %s\n",
687                            name, tldap_errstr(debug_ctx(), state->ld, rc)));
688                 TALLOC_FREE(frame);
689                 return NT_STATUS_LDAP(rc);
690         }
691
692         if (talloc_array_length(alias) != 1) {
693                 DEBUG(10, ("Got %d alias, expected one\n",
694                            (int)talloc_array_length(alias)));
695                 TALLOC_FREE(frame);
696                 return NT_STATUS_LDAP(rc);
697         }
698
699         if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
700                 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
701                            name));
702                 TALLOC_FREE(frame);
703                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
704         }
705
706         sid_peek_rid(&sid, rid);
707         TALLOC_FREE(frame);
708         return NT_STATUS_OK;
709 }
710
711 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
712                                          TALLOC_CTX *mem_ctx, uint32 rid)
713 {
714         struct pdb_ads_state *state = talloc_get_type_abort(
715                 m->private_data, struct pdb_ads_state);
716         struct dom_sid sid;
717         char *sidstr;
718         struct tldap_message **msg;
719         char *dn;
720         int rc;
721
722         sid_compose(&sid, &state->domainsid, rid);
723
724         sidstr = sid_binstring(talloc_tos(), &sid);
725         NT_STATUS_HAVE_NO_MEMORY(sidstr);
726
727         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
728                               NULL, 0, 0, talloc_tos(), &msg,
729                               ("(&(objectSid=%s)(objectClass=group))"),
730                               sidstr);
731         TALLOC_FREE(sidstr);
732         if (rc != TLDAP_SUCCESS) {
733                 DEBUG(10, ("ldap_search failed %s\n",
734                            tldap_errstr(debug_ctx(), state->ld, rc)));
735                 return NT_STATUS_LDAP(rc);
736         }
737
738         switch talloc_array_length(msg) {
739         case 0:
740                 return NT_STATUS_NO_SUCH_GROUP;
741         case 1:
742                 break;
743         default:
744                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
745         }
746
747         if (!tldap_entry_dn(msg[0], &dn)) {
748                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
749         }
750
751         rc = tldap_delete(state->ld, dn, NULL, 0, NULL, 0);
752         if (rc != TLDAP_SUCCESS) {
753                 DEBUG(10, ("ldap_delete failed: %s\n",
754                            tldap_errstr(debug_ctx(), state->ld, rc)));
755                 TALLOC_FREE(dn);
756                 return NT_STATUS_LDAP(rc);
757         }
758
759         TALLOC_FREE(msg);
760         return NT_STATUS_OK;
761 }
762
763 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
764                                                 GROUP_MAP *map)
765 {
766         return NT_STATUS_NOT_IMPLEMENTED;
767 }
768
769 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
770                                                    GROUP_MAP *map)
771 {
772         return NT_STATUS_NOT_IMPLEMENTED;
773 }
774
775 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
776                                                    DOM_SID sid)
777 {
778         return NT_STATUS_NOT_IMPLEMENTED;
779 }
780
781 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
782                                            const DOM_SID *sid,
783                                            enum lsa_SidType sid_name_use,
784                                            GROUP_MAP **pp_rmap,
785                                            size_t *p_num_entries,
786                                            bool unix_only)
787 {
788         return NT_STATUS_NOT_IMPLEMENTED;
789 }
790
791 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
792                                            TALLOC_CTX *mem_ctx,
793                                            const DOM_SID *group,
794                                            uint32 **pmembers,
795                                            size_t *pnum_members)
796 {
797         struct pdb_ads_state *state = talloc_get_type_abort(
798                 m->private_data, struct pdb_ads_state);
799         const char *attrs[1] = { "member" };
800         char *sidstr;
801         struct tldap_message **msg;
802         int i, rc, num_members;
803         DATA_BLOB *blobs;
804         uint32_t *members;
805
806         sidstr = sid_binstring(talloc_tos(), group);
807         NT_STATUS_HAVE_NO_MEMORY(sidstr);
808
809         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
810                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
811                               "(objectsid=%s)", sidstr);
812         TALLOC_FREE(sidstr);
813         if (rc != TLDAP_SUCCESS) {
814                 DEBUG(10, ("ldap_search failed %s\n",
815                            tldap_errstr(debug_ctx(), state->ld, rc)));
816                 return NT_STATUS_LDAP(rc);
817         }
818         switch talloc_array_length(msg) {
819         case 0:
820                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
821                 break;
822         case 1:
823                 break;
824         default:
825                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
826                 break;
827         }
828
829         if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
830                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
831         }
832
833         members = talloc_array(mem_ctx, uint32_t, num_members);
834         if (members == NULL) {
835                 return NT_STATUS_NO_MEMORY;
836         }
837
838         for (i=0; i<num_members; i++) {
839                 struct dom_sid sid;
840                 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &sid)
841                     || !sid_peek_rid(&sid, &members[i])) {
842                         TALLOC_FREE(members);
843                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
844                 }
845         }
846
847         *pmembers = members;
848         *pnum_members = num_members;
849         return NT_STATUS_OK;
850 }
851
852 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
853                                                TALLOC_CTX *mem_ctx,
854                                                struct samu *user,
855                                                DOM_SID **pp_sids,
856                                                gid_t **pp_gids,
857                                                size_t *p_num_groups)
858 {
859         struct pdb_ads_state *state = talloc_get_type_abort(
860                 m->private_data, struct pdb_ads_state);
861         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
862                 m, user);
863         const char *attrs[1] = { "objectSid" };
864         struct tldap_message **groups;
865         int i, rc, count;
866         size_t num_groups;
867         struct dom_sid *group_sids;
868         gid_t *gids;
869
870         rc = tldap_search_fmt(
871                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
872                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
873                 "(&(member=%s)(grouptype=%d)(objectclass=group))",
874                 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
875         if (rc != TLDAP_SUCCESS) {
876                 DEBUG(10, ("ldap_search failed %s\n",
877                            tldap_errstr(debug_ctx(), state->ld, rc)));
878                 return NT_STATUS_LDAP(rc);
879         }
880
881         count = talloc_array_length(groups);
882
883         group_sids = talloc_array(mem_ctx, struct dom_sid, count);
884         if (group_sids == NULL) {
885                 return NT_STATUS_NO_MEMORY;
886         }
887         gids = talloc_array(mem_ctx, gid_t, count);
888         if (gids == NULL) {
889                 TALLOC_FREE(group_sids);
890                 return NT_STATUS_NO_MEMORY;
891         }
892         num_groups = 0;
893
894         for (i=0; i<count; i++) {
895                 if (!tldap_pull_binsid(groups[i], "objectSid",
896                                        &group_sids[num_groups])) {
897                         continue;
898                 }
899                 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
900
901                 num_groups += 1;
902                 if (num_groups == count) {
903                         break;
904                 }
905         }
906
907         *pp_sids = group_sids;
908         *pp_gids = gids;
909         *p_num_groups = num_groups;
910         return NT_STATUS_OK;
911 }
912
913 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
914                                                TALLOC_CTX *mem_ctx,
915                                                struct samu *user)
916 {
917         return NT_STATUS_NOT_IMPLEMENTED;
918 }
919
920 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
921                                      TALLOC_CTX *mem_ctx,
922                                      uint32 grouprid, uint32 memberrid,
923                                      int mod_op)
924 {
925         struct pdb_ads_state *state = talloc_get_type_abort(
926                 m->private_data, struct pdb_ads_state);
927         TALLOC_CTX *frame = talloc_stackframe();
928         struct dom_sid groupsid, membersid;
929         char *groupdn, *memberdn;
930         struct tldap_mod *mods;
931         int rc;
932         NTSTATUS status;
933
934         sid_compose(&groupsid, &state->domainsid, grouprid);
935         sid_compose(&membersid, &state->domainsid, memberrid);
936
937         status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
938         if (!NT_STATUS_IS_OK(status)) {
939                 TALLOC_FREE(frame);
940                 return NT_STATUS_NO_SUCH_GROUP;
941         }
942         status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
943         if (!NT_STATUS_IS_OK(status)) {
944                 TALLOC_FREE(frame);
945                 return NT_STATUS_NO_SUCH_USER;
946         }
947
948         mods = NULL;
949
950         if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
951                                "member", memberdn)) {
952                 TALLOC_FREE(frame);
953                 return NT_STATUS_NO_MEMORY;
954         }
955
956         rc = tldap_modify(state->ld, groupdn, 1, mods, NULL, 0, NULL, 0);
957         TALLOC_FREE(frame);
958         if (rc != TLDAP_SUCCESS) {
959                 DEBUG(10, ("ldap_modify failed: %s\n",
960                            tldap_errstr(debug_ctx(), state->ld, rc)));
961                 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
962                         return NT_STATUS_MEMBER_IN_GROUP;
963                 }
964                 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
965                         return NT_STATUS_MEMBER_NOT_IN_GROUP;
966                 }
967                 return NT_STATUS_LDAP(rc);
968         }
969
970         return NT_STATUS_OK;
971 }
972
973 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
974                                      TALLOC_CTX *mem_ctx,
975                                      uint32 group_rid, uint32 member_rid)
976 {
977         return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
978                                     TLDAP_MOD_ADD);
979 }
980
981 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
982                                      TALLOC_CTX *mem_ctx,
983                                      uint32 group_rid, uint32 member_rid)
984 {
985         return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
986                                     TLDAP_MOD_DELETE);
987 }
988
989 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
990                                      const char *name, uint32 *rid)
991 {
992         TALLOC_CTX *frame = talloc_stackframe();
993         struct pdb_ads_state *state = talloc_get_type_abort(
994                 m->private_data, struct pdb_ads_state);
995         const char *attrs[1] = { "objectSid" };
996         int num_mods = 0;
997         struct tldap_mod *mods = NULL;
998         struct tldap_message **alias;
999         struct dom_sid sid;
1000         char *dn;
1001         int rc;
1002         bool ok = true;
1003
1004         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1005                              state->domaindn);
1006         if (dn == NULL) {
1007                 TALLOC_FREE(frame);
1008                 return NT_STATUS_NO_MEMORY;
1009         }
1010
1011         ok &= tldap_make_mod_fmt(
1012                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
1013                 name);
1014         ok &= tldap_make_mod_fmt(
1015                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
1016         ok &= tldap_make_mod_fmt(
1017                 NULL, talloc_tos(), &num_mods, &mods, "groupType",
1018                 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1019
1020         if (!ok) {
1021                 TALLOC_FREE(frame);
1022                 return NT_STATUS_NO_MEMORY;
1023         }
1024
1025         rc = tldap_add(state->ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1026         if (rc != TLDAP_SUCCESS) {
1027                 DEBUG(10, ("ldap_add failed %s\n",
1028                            tldap_errstr(debug_ctx(), state->ld, rc)));
1029                 TALLOC_FREE(frame);
1030                 return NT_STATUS_LDAP(rc);
1031         }
1032
1033         rc = tldap_search_fmt(
1034                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1035                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1036                 "(&(objectclass=group)(samaccountname=%s))", name);
1037         if (rc != TLDAP_SUCCESS) {
1038                 DEBUG(10, ("Could not find just created alias %s: %s\n",
1039                            name, tldap_errstr(debug_ctx(), state->ld, rc)));
1040                 TALLOC_FREE(frame);
1041                 return NT_STATUS_LDAP(rc);
1042         }
1043
1044         if (talloc_array_length(alias) != 1) {
1045                 DEBUG(10, ("Got %d alias, expected one\n",
1046                            (int)talloc_array_length(alias)));
1047                 TALLOC_FREE(frame);
1048                 return NT_STATUS_LDAP(rc);
1049         }
1050
1051         if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1052                 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1053                            name));
1054                 TALLOC_FREE(frame);
1055                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1056         }
1057
1058         sid_peek_rid(&sid, rid);
1059         TALLOC_FREE(frame);
1060         return NT_STATUS_OK;
1061 }
1062
1063 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1064                                      const DOM_SID *sid)
1065 {
1066         struct pdb_ads_state *state = talloc_get_type_abort(
1067                 m->private_data, struct pdb_ads_state);
1068         struct tldap_message **alias;
1069         char *sidstr, *dn;
1070         int rc;
1071
1072         sidstr = sid_binstring(talloc_tos(), sid);
1073         if (sidstr == NULL) {
1074                 return NT_STATUS_NO_MEMORY;
1075         }
1076
1077         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1078                               NULL, 0, 0, talloc_tos(), &alias,
1079                               "(&(objectSid=%s)(objectclass=group)"
1080                               "(|(grouptype=%d)(grouptype=%d)))",
1081                               sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1082                               GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1083         TALLOC_FREE(sidstr);
1084         if (rc != TLDAP_SUCCESS) {
1085                 DEBUG(10, ("ldap_search failed: %s\n",
1086                            tldap_errstr(debug_ctx(), state->ld, rc)));
1087                 TALLOC_FREE(dn);
1088                 return NT_STATUS_LDAP(rc);
1089         }
1090         if (talloc_array_length(alias) != 1) {
1091                 DEBUG(10, ("Expected 1 alias, got %d\n",
1092                            (int)talloc_array_length(alias)));
1093                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1094         }
1095         if (!tldap_entry_dn(alias[0], &dn)) {
1096                 DEBUG(10, ("Could not get DN for alias %s\n",
1097                            sid_string_dbg(sid)));
1098                 return NT_STATUS_INTERNAL_ERROR;
1099         }
1100
1101         rc = tldap_delete(state->ld, dn, NULL, 0, NULL, 0);
1102         if (rc != TLDAP_SUCCESS) {
1103                 DEBUG(10, ("ldap_delete failed: %s\n",
1104                            tldap_errstr(debug_ctx(), state->ld, rc)));
1105                 TALLOC_FREE(dn);
1106                 return NT_STATUS_LDAP(rc);
1107         }
1108
1109         return NT_STATUS_OK;
1110 }
1111
1112 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1113                                       const DOM_SID *sid,
1114                                       struct acct_info *info)
1115 {
1116         struct pdb_ads_state *state = talloc_get_type_abort(
1117                 m->private_data, struct pdb_ads_state);
1118         const char *attrs[3] = { "objectSid", "description",
1119                                  "samAccountName" };
1120         struct tldap_message **msg;
1121         char *sidstr, *dn;
1122         int rc;
1123         struct tldap_mod *mods;
1124         int num_mods;
1125         bool ok;
1126
1127         sidstr = sid_binstring(talloc_tos(), sid);
1128         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1129
1130         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1131                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1132                               &msg, "(&(objectSid=%s)(objectclass=group)"
1133                               "(|(grouptype=%d)(grouptype=%d)))",
1134                               sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1135                               GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1136         TALLOC_FREE(sidstr);
1137         if (rc != TLDAP_SUCCESS) {
1138                 DEBUG(10, ("ldap_search failed %s\n",
1139                            tldap_errstr(debug_ctx(), state->ld, rc)));
1140                 return NT_STATUS_LDAP(rc);
1141         }
1142         switch talloc_array_length(msg) {
1143         case 0:
1144                 return NT_STATUS_NO_SUCH_ALIAS;
1145         case 1:
1146                 break;
1147         default:
1148                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1149         }
1150
1151         if (!tldap_entry_dn(msg[0], &dn)) {
1152                 TALLOC_FREE(msg);
1153                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1154         }
1155
1156         mods = NULL;
1157         num_mods = 0;
1158         ok = true;
1159
1160         ok &= tldap_make_mod_fmt(
1161                 msg[0], msg, &num_mods, &mods, "description",
1162                 "%s", info->acct_desc);
1163         ok &= tldap_make_mod_fmt(
1164                 msg[0], msg, &num_mods, &mods, "samAccountName",
1165                 "%s", info->acct_name);
1166         if (!ok) {
1167                 TALLOC_FREE(msg);
1168                 return NT_STATUS_NO_MEMORY;
1169         }
1170         if (num_mods == 0) {
1171                 /* no change */
1172                 TALLOC_FREE(msg);
1173                 return NT_STATUS_OK;
1174         }
1175
1176         rc = tldap_modify(state->ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1177         TALLOC_FREE(msg);
1178         if (rc != TLDAP_SUCCESS) {
1179                 DEBUG(10, ("ldap_modify failed: %s\n",
1180                            tldap_errstr(debug_ctx(), state->ld, rc)));
1181                 return NT_STATUS_LDAP(rc);
1182         }
1183         return NT_STATUS_OK;
1184 }
1185
1186 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1187                                const struct dom_sid *sid,
1188                                TALLOC_CTX *mem_ctx, char **pdn)
1189 {
1190         struct tldap_message **msg;
1191         char *sidstr, *dn;
1192         int rc;
1193
1194         sidstr = sid_binstring(talloc_tos(), sid);
1195         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1196
1197         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1198                               NULL, 0, 0, talloc_tos(), &msg,
1199                               "(objectsid=%s)", sidstr);
1200         TALLOC_FREE(sidstr);
1201         if (rc != TLDAP_SUCCESS) {
1202                 DEBUG(10, ("ldap_search failed %s\n",
1203                            tldap_errstr(debug_ctx(), state->ld, rc)));
1204                 return NT_STATUS_LDAP(rc);
1205         }
1206
1207         switch talloc_array_length(msg) {
1208         case 0:
1209                 return NT_STATUS_NOT_FOUND;
1210         case 1:
1211                 break;
1212         default:
1213                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1214         }
1215
1216         if (!tldap_entry_dn(msg[0], &dn)) {
1217                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1218         }
1219
1220         dn = talloc_strdup(mem_ctx, dn);
1221         if (dn == NULL) {
1222                 return NT_STATUS_NO_MEMORY;
1223         }
1224         TALLOC_FREE(msg);
1225
1226         *pdn = dn;
1227         return NT_STATUS_OK;
1228 }
1229
1230 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1231                                      const DOM_SID *alias,
1232                                      const DOM_SID *member,
1233                                      int mod_op)
1234 {
1235         struct pdb_ads_state *state = talloc_get_type_abort(
1236                 m->private_data, struct pdb_ads_state);
1237         TALLOC_CTX *frame = talloc_stackframe();
1238         struct tldap_mod *mods;
1239         int rc;
1240         char *aliasdn, *memberdn;
1241         NTSTATUS status;
1242
1243         status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1244         if (!NT_STATUS_IS_OK(status)) {
1245                 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1246                            sid_string_dbg(alias), nt_errstr(status)));
1247                 TALLOC_FREE(frame);
1248                 return NT_STATUS_NO_SUCH_ALIAS;
1249         }
1250         status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1251         if (!NT_STATUS_IS_OK(status)) {
1252                 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1253                            sid_string_dbg(member), nt_errstr(status)));
1254                 TALLOC_FREE(frame);
1255                 return status;
1256         }
1257
1258         mods = NULL;
1259
1260         if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1261                                "member", memberdn)) {
1262                 TALLOC_FREE(frame);
1263                 return NT_STATUS_NO_MEMORY;
1264         }
1265
1266         rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, 0, NULL, 0);
1267         TALLOC_FREE(frame);
1268         if (rc != TLDAP_SUCCESS) {
1269                 DEBUG(10, ("ldap_modify failed: %s\n",
1270                            tldap_errstr(debug_ctx(), state->ld, rc)));
1271                 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1272                         return NT_STATUS_MEMBER_IN_ALIAS;
1273                 }
1274                 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1275                         return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1276                 }
1277                 return NT_STATUS_LDAP(rc);
1278         }
1279
1280         return NT_STATUS_OK;
1281 }
1282
1283 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1284                                      const DOM_SID *alias,
1285                                      const DOM_SID *member)
1286 {
1287         return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1288 }
1289
1290 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1291                                      const DOM_SID *alias,
1292                                      const DOM_SID *member)
1293 {
1294         return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1295 }
1296
1297 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1298                                struct dom_sid *psid)
1299 {
1300         const char *attrs[1] = { "objectSid" };
1301         struct tldap_message **msg;
1302         char *dn;
1303         size_t len;
1304         int rc;
1305         bool ret;
1306
1307         if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1308                                    dnblob->data, dnblob->length, &dn, &len,
1309                                    false)) {
1310                 return false;
1311         }
1312         rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1313                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1314                               &msg, "(objectclass=*)");
1315         TALLOC_FREE(dn);
1316         if (talloc_array_length(msg) != 1) {
1317                 DEBUG(10, ("Got %d objects, expected one\n",
1318                            (int)talloc_array_length(msg)));
1319                 TALLOC_FREE(msg);
1320                 return false;
1321         }
1322
1323         ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1324         TALLOC_FREE(msg);
1325         return ret;
1326 }
1327
1328 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1329                                       const DOM_SID *alias,
1330                                       TALLOC_CTX *mem_ctx,
1331                                       DOM_SID **pmembers,
1332                                       size_t *pnum_members)
1333 {
1334         struct pdb_ads_state *state = talloc_get_type_abort(
1335                 m->private_data, struct pdb_ads_state);
1336         const char *attrs[1] = { "member" };
1337         char *sidstr;
1338         struct tldap_message **msg;
1339         int i, rc, num_members;
1340         DATA_BLOB *blobs;
1341         struct dom_sid *members;
1342
1343         sidstr = sid_binstring(talloc_tos(), alias);
1344         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1345
1346         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1347                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1348                               "(objectsid=%s)", sidstr);
1349         TALLOC_FREE(sidstr);
1350         if (rc != TLDAP_SUCCESS) {
1351                 DEBUG(10, ("ldap_search failed %s\n",
1352                            tldap_errstr(debug_ctx(), state->ld, rc)));
1353                 return NT_STATUS_LDAP(rc);
1354         }
1355         switch talloc_array_length(msg) {
1356         case 0:
1357                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1358                 break;
1359         case 1:
1360                 break;
1361         default:
1362                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1363                 break;
1364         }
1365
1366         if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1367                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1368         }
1369
1370         members = talloc_array(mem_ctx, struct dom_sid, num_members);
1371         if (members == NULL) {
1372                 return NT_STATUS_NO_MEMORY;
1373         }
1374
1375         for (i=0; i<num_members; i++) {
1376                 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1377                         TALLOC_FREE(members);
1378                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1379                 }
1380         }
1381
1382         *pmembers = members;
1383         *pnum_members = num_members;
1384         return NT_STATUS_OK;
1385 }
1386
1387 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1388                                                TALLOC_CTX *mem_ctx,
1389                                                const DOM_SID *domain_sid,
1390                                                const DOM_SID *members,
1391                                                size_t num_members,
1392                                                uint32_t **palias_rids,
1393                                                size_t *pnum_alias_rids)
1394 {
1395         struct pdb_ads_state *state = talloc_get_type_abort(
1396                 m->private_data, struct pdb_ads_state);
1397         const char *attrs[1] = { "objectSid" };
1398         struct tldap_message **msg;
1399         uint32_t *alias_rids = NULL;
1400         size_t num_alias_rids = 0;
1401         int i, rc, count;
1402         bool got_members = false;
1403         char *filter;
1404         NTSTATUS status;
1405
1406         /*
1407          * TODO: Get the filter right so that we only get the aliases from
1408          * either the SAM or BUILTIN
1409          */
1410
1411         filter = talloc_asprintf(talloc_tos(),
1412                                  "(&(|(grouptype=%d)(grouptype=%d))"
1413                                  "(objectclass=group)(|",
1414                                  GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1415                                  GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1416         if (filter == NULL) {
1417                 return NT_STATUS_NO_MEMORY;
1418         }
1419
1420         for (i=0; i<num_members; i++) {
1421                 char *dn;
1422
1423                 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1424                 if (!NT_STATUS_IS_OK(status)) {
1425                         DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1426                                    sid_string_dbg(&members[i]),
1427                                    nt_errstr(status)));
1428                         continue;
1429                 }
1430                 filter = talloc_asprintf_append_buffer(
1431                         filter, "(member=%s)", dn);
1432                 TALLOC_FREE(dn);
1433                 if (filter == NULL) {
1434                         return NT_STATUS_NO_MEMORY;
1435                 }
1436                 got_members = true;
1437         }
1438
1439         if (!got_members) {
1440                 goto done;
1441         }
1442
1443         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1444                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1445                               &msg, "%s))", filter);
1446         TALLOC_FREE(filter);
1447         if (rc != TLDAP_SUCCESS) {
1448                 DEBUG(10, ("tldap_search failed %s\n",
1449                            tldap_errstr(debug_ctx(), state->ld, rc)));
1450                 return NT_STATUS_LDAP(rc);
1451         }
1452
1453         count = talloc_array_length(msg);
1454         if (count == 0) {
1455                 goto done;
1456         }
1457
1458         alias_rids = talloc_array(mem_ctx, uint32_t, count);
1459         if (alias_rids == NULL) {
1460                 TALLOC_FREE(msg);
1461                 return NT_STATUS_NO_MEMORY;
1462         }
1463
1464         for (i=0; i<count; i++) {
1465                 struct dom_sid sid;
1466
1467                 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1468                         DEBUG(10, ("Could not pull SID for member %d\n", i));
1469                         continue;
1470                 }
1471                 if (sid_peek_check_rid(domain_sid, &sid,
1472                                        &alias_rids[num_alias_rids])) {
1473                         num_alias_rids += 1;
1474                 }
1475         }
1476 done:
1477         TALLOC_FREE(msg);
1478         *palias_rids = alias_rids;
1479         *pnum_alias_rids = 0;
1480         return NT_STATUS_OK;
1481 }
1482
1483 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1484                                     const DOM_SID *domain_sid,
1485                                     int num_rids,
1486                                     uint32 *rids,
1487                                     const char **names,
1488                                     enum lsa_SidType *lsa_attrs)
1489 {
1490         struct pdb_ads_state *state = talloc_get_type_abort(
1491                 m->private_data, struct pdb_ads_state);
1492         const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1493         int i, num_mapped;
1494
1495         if (num_rids == 0) {
1496                 return NT_STATUS_NONE_MAPPED;
1497         }
1498
1499         num_mapped = 0;
1500
1501         for (i=0; i<num_rids; i++) {
1502                 struct dom_sid sid;
1503                 struct tldap_message **msg;
1504                 char *sidstr;
1505                 uint32_t attr;
1506                 int rc;
1507
1508                 lsa_attrs[i] = SID_NAME_UNKNOWN;
1509
1510                 sid_compose(&sid, domain_sid, rids[i]);
1511
1512                 sidstr = sid_binstring(talloc_tos(), &sid);
1513                 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1514
1515                 rc = tldap_search_fmt(state->ld, state->domaindn,
1516                                       TLDAP_SCOPE_SUB, attrs,
1517                                       ARRAY_SIZE(attrs), 0, talloc_tos(),
1518                                       &msg, "(objectsid=%s)", sidstr);
1519                 TALLOC_FREE(sidstr);
1520                 if (rc != TLDAP_SUCCESS) {
1521                         DEBUG(10, ("ldap_search failed %s\n",
1522                                    tldap_errstr(debug_ctx(), state->ld, rc)));
1523                         continue;
1524                 }
1525
1526                 switch talloc_array_length(msg) {
1527                 case 0:
1528                         DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1529                         continue;
1530                 case 1:
1531                         break;
1532                 default:
1533                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1534                 }
1535
1536                 names[i] = tldap_talloc_single_attribute(
1537                         msg[0], "samAccountName", talloc_tos());
1538                 if (names[i] == NULL) {
1539                         DEBUG(10, ("no samAccountName\n"));
1540                         continue;
1541                 }
1542                 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1543                         DEBUG(10, ("no samAccountType"));
1544                         continue;
1545                 }
1546                 lsa_attrs[i] = ads_atype_map(attr);
1547                 num_mapped += 1;
1548         }
1549
1550         if (num_mapped == 0) {
1551                 return NT_STATUS_NONE_MAPPED;
1552         }
1553         if (num_mapped < num_rids) {
1554                 return STATUS_SOME_UNMAPPED;
1555         }
1556         return NT_STATUS_OK;
1557 }
1558
1559 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1560                                      const DOM_SID *domain_sid,
1561                                      int num_names,
1562                                      const char **pp_names,
1563                                      uint32 *rids,
1564                                      enum lsa_SidType *attrs)
1565 {
1566         return NT_STATUS_NOT_IMPLEMENTED;
1567 }
1568
1569 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1570                                            int policy_index, uint32 *value)
1571 {
1572         return account_policy_get(policy_index, value)
1573                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1574 }
1575
1576 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1577                                            int policy_index, uint32 value)
1578 {
1579         return account_policy_set(policy_index, value)
1580                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1581 }
1582
1583 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1584                                     time_t *seq_num)
1585 {
1586         return NT_STATUS_NOT_IMPLEMENTED;
1587 }
1588
1589 struct pdb_ads_search_state {
1590         uint32_t acct_flags;
1591         struct samr_displayentry *entries;
1592         uint32_t num_entries;
1593         ssize_t array_size;
1594         uint32_t current;
1595 };
1596
1597 static bool pdb_ads_next_entry(struct pdb_search *search,
1598                                struct samr_displayentry *entry)
1599 {
1600         struct pdb_ads_search_state *state = talloc_get_type_abort(
1601                 search->private_data, struct pdb_ads_search_state);
1602
1603         if (state->current == state->num_entries) {
1604                 return false;
1605         }
1606
1607         entry->idx = state->entries[state->current].idx;
1608         entry->rid = state->entries[state->current].rid;
1609         entry->acct_flags = state->entries[state->current].acct_flags;
1610
1611         entry->account_name = talloc_strdup(
1612                 search, state->entries[state->current].account_name);
1613         entry->fullname = talloc_strdup(
1614                 search, state->entries[state->current].fullname);
1615         entry->description = talloc_strdup(
1616                 search, state->entries[state->current].description);
1617
1618         if ((entry->account_name == NULL) || (entry->fullname == NULL)
1619             || (entry->description == NULL)) {
1620                 DEBUG(0, ("talloc_strdup failed\n"));
1621                 return false;
1622         }
1623
1624         state->current += 1;
1625         return true;
1626 }
1627
1628 static void pdb_ads_search_end(struct pdb_search *search)
1629 {
1630         struct pdb_ads_search_state *state = talloc_get_type_abort(
1631                 search->private_data, struct pdb_ads_search_state);
1632         TALLOC_FREE(state);
1633 }
1634
1635 static bool pdb_ads_search_filter(struct pdb_methods *m,
1636                                   struct pdb_search *search,
1637                                   const char *filter,
1638                                   struct pdb_ads_search_state **pstate)
1639 {
1640         struct pdb_ads_state *state = talloc_get_type_abort(
1641                 m->private_data, struct pdb_ads_state);
1642         struct pdb_ads_search_state *sstate;
1643         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1644                                  "userAccountControl", "description" };
1645         struct tldap_message **users;
1646         int i, rc, num_users;
1647
1648         sstate = talloc_zero(search, struct pdb_ads_search_state);
1649         if (sstate == NULL) {
1650                 return false;
1651         }
1652
1653         rc = tldap_search_fmt(
1654                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1655                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1656                 "%s", filter);
1657         if (rc != TLDAP_SUCCESS) {
1658                 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1659                            tldap_errstr(debug_ctx(), state->ld, rc)));
1660                 return false;
1661         }
1662
1663         num_users = talloc_array_length(users);
1664
1665         sstate->entries = talloc_array(sstate, struct samr_displayentry,
1666                                        num_users);
1667         if (sstate->entries == NULL) {
1668                 DEBUG(10, ("talloc failed\n"));
1669                 return false;
1670         }
1671
1672         sstate->num_entries = 0;
1673
1674         for (i=0; i<num_users; i++) {
1675                 struct samr_displayentry *e;
1676                 struct dom_sid sid;
1677
1678                 e = &sstate->entries[sstate->num_entries];
1679
1680                 e->idx = sstate->num_entries;
1681                 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1682                         DEBUG(10, ("Could not pull sid\n"));
1683                         continue;
1684                 }
1685                 sid_peek_rid(&sid, &e->rid);
1686                 e->acct_flags = ACB_NORMAL;
1687                 e->account_name = tldap_talloc_single_attribute(
1688                         users[i], "samAccountName", sstate->entries);
1689                 if (e->account_name == NULL) {
1690                         return false;
1691                 }
1692                 e->fullname = tldap_talloc_single_attribute(
1693                         users[i], "displayName", sstate->entries);
1694                 if (e->fullname == NULL) {
1695                         e->fullname = "";
1696                 }
1697                 e->description = tldap_talloc_single_attribute(
1698                         users[i], "description", sstate->entries);
1699                 if (e->description == NULL) {
1700                         e->description = "";
1701                 }
1702
1703                 sstate->num_entries += 1;
1704                 if (sstate->num_entries >= num_users) {
1705                         break;
1706                 }
1707         }
1708
1709         search->private_data = sstate;
1710         search->next_entry = pdb_ads_next_entry;
1711         search->search_end = pdb_ads_search_end;
1712         *pstate = sstate;
1713         return true;
1714 }
1715
1716 static bool pdb_ads_search_users(struct pdb_methods *m,
1717                                  struct pdb_search *search,
1718                                  uint32 acct_flags)
1719 {
1720         struct pdb_ads_search_state *sstate;
1721         bool ret;
1722
1723         ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1724         if (!ret) {
1725                 return false;
1726         }
1727         sstate->acct_flags = acct_flags;
1728         return true;
1729 }
1730
1731 static bool pdb_ads_search_groups(struct pdb_methods *m,
1732                                   struct pdb_search *search)
1733 {
1734         struct pdb_ads_search_state *sstate;
1735         char *filter;
1736         bool ret;
1737
1738         filter = talloc_asprintf(talloc_tos(),
1739                                  "(&(grouptype=%d)(objectclass=group))",
1740                                  GTYPE_SECURITY_GLOBAL_GROUP);
1741         if (filter == NULL) {
1742                 return false;
1743         }
1744         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1745         TALLOC_FREE(filter);
1746         if (!ret) {
1747                 return false;
1748         }
1749         sstate->acct_flags = 0;
1750         return true;
1751 }
1752
1753 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1754                                    struct pdb_search *search,
1755                                    const DOM_SID *sid)
1756 {
1757         struct pdb_ads_search_state *sstate;
1758         char *filter;
1759         bool ret;
1760
1761         filter = talloc_asprintf(
1762                 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1763                 sid_check_is_builtin(sid)
1764                 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1765                 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1766
1767         if (filter == NULL) {
1768                 return false;
1769         }
1770         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1771         TALLOC_FREE(filter);
1772         if (!ret) {
1773                 return false;
1774         }
1775         sstate->acct_flags = 0;
1776         return true;
1777 }
1778
1779 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1780                                uint32 *rid)
1781 {
1782         return false;
1783 }
1784
1785 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1786                                DOM_SID *sid)
1787 {
1788         struct pdb_ads_state *state = talloc_get_type_abort(
1789                 m->private_data, struct pdb_ads_state);
1790         sid_compose(sid, &state->domainsid, uid);
1791         return true;
1792 }
1793
1794 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1795                                DOM_SID *sid)
1796 {
1797         struct pdb_ads_state *state = talloc_get_type_abort(
1798                 m->private_data, struct pdb_ads_state);
1799         sid_compose(sid, &state->domainsid, gid);
1800         return true;
1801 }
1802
1803 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1804                               union unid_t *id, enum lsa_SidType *type)
1805 {
1806         struct pdb_ads_state *state = talloc_get_type_abort(
1807                 m->private_data, struct pdb_ads_state);
1808         struct tldap_message **msg;
1809         char *sidstr;
1810         uint32_t rid;
1811         int rc;
1812
1813         /*
1814          * This is a big, big hack: Just hard-code the rid as uid/gid.
1815          */
1816
1817         sid_peek_rid(sid, &rid);
1818
1819         sidstr = sid_binstring(talloc_tos(), sid);
1820         if (sidstr == NULL) {
1821                 return false;
1822         }
1823
1824         rc = tldap_search_fmt(
1825                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1826                 NULL, 0, 0, talloc_tos(), &msg,
1827                 "(&(objectsid=%s)(objectclass=user))", sidstr);
1828         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1829                 id->uid = rid;
1830                 *type = SID_NAME_USER;
1831                 TALLOC_FREE(sidstr);
1832                 return true;
1833         }
1834
1835         rc = tldap_search_fmt(
1836                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1837                 NULL, 0, 0, talloc_tos(), &msg,
1838                 "(&(objectsid=%s)(objectclass=group))", sidstr);
1839         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1840                 id->gid = rid;
1841                 *type = SID_NAME_DOM_GRP;
1842                 TALLOC_FREE(sidstr);
1843                 return true;
1844         }
1845
1846         TALLOC_FREE(sidstr);
1847         return false;
1848 }
1849
1850 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1851 {
1852         return false;
1853 }
1854
1855 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1856 {
1857         return false;
1858 }
1859
1860 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1861                                       const char *domain, char** pwd,
1862                                       DOM_SID *sid,
1863                                       time_t *pass_last_set_time)
1864 {
1865         return false;
1866 }
1867
1868 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1869                                       const char* domain, const char* pwd,
1870                                       const DOM_SID *sid)
1871 {
1872         return false;
1873 }
1874
1875 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1876                                       const char *domain)
1877 {
1878         return false;
1879 }
1880
1881 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1882                                          TALLOC_CTX *mem_ctx,
1883                                          uint32 *num_domains,
1884                                          struct trustdom_info ***domains)
1885 {
1886         return NT_STATUS_NOT_IMPLEMENTED;
1887 }
1888
1889 static void pdb_ads_init_methods(struct pdb_methods *m)
1890 {
1891         m->name = "ads";
1892         m->getsampwnam = pdb_ads_getsampwnam;
1893         m->getsampwsid = pdb_ads_getsampwsid;
1894         m->create_user = pdb_ads_create_user;
1895         m->delete_user = pdb_ads_delete_user;
1896         m->add_sam_account = pdb_ads_add_sam_account;
1897         m->update_sam_account = pdb_ads_update_sam_account;
1898         m->delete_sam_account = pdb_ads_delete_sam_account;
1899         m->rename_sam_account = pdb_ads_rename_sam_account;
1900         m->update_login_attempts = pdb_ads_update_login_attempts;
1901         m->getgrsid = pdb_ads_getgrsid;
1902         m->getgrgid = pdb_ads_getgrgid;
1903         m->getgrnam = pdb_ads_getgrnam;
1904         m->create_dom_group = pdb_ads_create_dom_group;
1905         m->delete_dom_group = pdb_ads_delete_dom_group;
1906         m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1907         m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1908         m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1909         m->enum_group_mapping = pdb_ads_enum_group_mapping;
1910         m->enum_group_members = pdb_ads_enum_group_members;
1911         m->enum_group_memberships = pdb_ads_enum_group_memberships;
1912         m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1913         m->add_groupmem = pdb_ads_add_groupmem;
1914         m->del_groupmem = pdb_ads_del_groupmem;
1915         m->create_alias = pdb_ads_create_alias;
1916         m->delete_alias = pdb_ads_delete_alias;
1917         m->get_aliasinfo = pdb_default_get_aliasinfo;
1918         m->set_aliasinfo = pdb_ads_set_aliasinfo;
1919         m->add_aliasmem = pdb_ads_add_aliasmem;
1920         m->del_aliasmem = pdb_ads_del_aliasmem;
1921         m->enum_aliasmem = pdb_ads_enum_aliasmem;
1922         m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1923         m->lookup_rids = pdb_ads_lookup_rids;
1924         m->lookup_names = pdb_ads_lookup_names;
1925         m->get_account_policy = pdb_ads_get_account_policy;
1926         m->set_account_policy = pdb_ads_set_account_policy;
1927         m->get_seq_num = pdb_ads_get_seq_num;
1928         m->search_users = pdb_ads_search_users;
1929         m->search_groups = pdb_ads_search_groups;
1930         m->search_aliases = pdb_ads_search_aliases;
1931         m->uid_to_rid = pdb_ads_uid_to_rid;
1932         m->uid_to_sid = pdb_ads_uid_to_sid;
1933         m->gid_to_sid = pdb_ads_gid_to_sid;
1934         m->sid_to_id = pdb_ads_sid_to_id;
1935         m->rid_algorithm = pdb_ads_rid_algorithm;
1936         m->new_rid = pdb_ads_new_rid;
1937         m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1938         m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1939         m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1940         m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1941 }
1942
1943 static void free_private_data(void **vp)
1944 {
1945         struct pdb_ads_state *state = talloc_get_type_abort(
1946                 *vp, struct pdb_ads_state);
1947
1948         TALLOC_FREE(state->ld);
1949         return;
1950 }
1951
1952 /*
1953   this is used to catch debug messages from events
1954 */
1955 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
1956                            const char *fmt, va_list ap)  PRINTF_ATTRIBUTE(3,0);
1957
1958 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
1959                            const char *fmt, va_list ap)
1960 {
1961         int samba_level = -1;
1962         char *s = NULL;
1963         switch (level) {
1964         case TLDAP_DEBUG_FATAL:
1965                 samba_level = 0;
1966                 break;
1967         case TLDAP_DEBUG_ERROR:
1968                 samba_level = 1;
1969                 break;
1970         case TLDAP_DEBUG_WARNING:
1971                 samba_level = 2;
1972                 break;
1973         case TLDAP_DEBUG_TRACE:
1974                 samba_level = 10;
1975                 break;
1976
1977         };
1978         if (vasprintf(&s, fmt, ap) == -1) {
1979                 return;
1980         }
1981         DEBUG(samba_level, ("tldap: %s", s));
1982         free(s);
1983 }
1984
1985 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1986                                 const char *location)
1987 {
1988         const char *rootdse_attrs[2] = {
1989                 "defaultNamingContext", "configurationNamingContext" };
1990         const char *domain_attrs[1] = { "objectSid" };
1991         const char *ncname_attrs[1] = { "netbiosname" };
1992         struct tldap_message **rootdse, **domain, **ncname;
1993         TALLOC_CTX *frame = talloc_stackframe();
1994         struct sockaddr_un sunaddr;
1995         NTSTATUS status;
1996         int num_domains;
1997         int fd, rc;
1998
1999         ZERO_STRUCT(sunaddr);
2000         sunaddr.sun_family = AF_UNIX;
2001         strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
2002
2003         status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
2004                                  0, 0, &fd);
2005         if (!NT_STATUS_IS_OK(status)) {
2006                 DEBUG(10, ("Could not connect to %s: %s\n", location,
2007                            nt_errstr(status)));
2008                 goto done;
2009         }
2010
2011         state->ld = tldap_context_create(state, fd);
2012         if (state->ld == NULL) {
2013                 close(fd);
2014                 status = NT_STATUS_NO_MEMORY;
2015                 goto done;
2016         }
2017         tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2018
2019         rc = tldap_search_fmt(
2020                 state->ld, "", TLDAP_SCOPE_BASE,
2021                 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
2022                 talloc_tos(), &rootdse, "(objectclass=*)");
2023         if (rc != TLDAP_SUCCESS) {
2024                 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2025                            tldap_errstr(debug_ctx(), state->ld, rc)));
2026                 status = NT_STATUS_LDAP(rc);
2027                 goto done;
2028         }
2029         if (talloc_array_length(rootdse) != 1) {
2030                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2031                 goto done;
2032         }
2033
2034         state->domaindn = tldap_talloc_single_attribute(
2035                 rootdse[0], "defaultNamingContext", state);
2036         if (state->domaindn == NULL) {
2037                 DEBUG(10, ("Could not get defaultNamingContext\n"));
2038                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2039                 goto done;
2040         }
2041         DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2042
2043         state->configdn = tldap_talloc_single_attribute(
2044                 rootdse[0], "configurationNamingContext", state);
2045         if (state->domaindn == NULL) {
2046                 DEBUG(10, ("Could not get configurationNamingContext\n"));
2047                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2048                 goto done;
2049         }
2050         DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2051
2052         /*
2053          * Figure out our domain's SID
2054          */
2055         rc = tldap_search_fmt(
2056                 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
2057                 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2058                 talloc_tos(), &domain, "(objectclass=*)");
2059         if (rc != TLDAP_SUCCESS) {
2060                 DEBUG(10, ("Could not retrieve domain: %s\n",
2061                            tldap_errstr(debug_ctx(), state->ld, rc)));
2062                 status = NT_STATUS_LDAP(rc);
2063                 goto done;
2064         }
2065
2066         num_domains = talloc_array_length(domain);
2067         if (num_domains != 1) {
2068                 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2069                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2070                 goto done;
2071         }
2072         if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2073                 DEBUG(10, ("Could not retrieve domain SID\n"));
2074                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2075                 goto done;
2076         }
2077         DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2078
2079         /*
2080          * Figure out our domain's short name
2081          */
2082         rc = tldap_search_fmt(
2083                 state->ld, state->configdn, TLDAP_SCOPE_SUB,
2084                 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2085                 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2086         if (rc != TLDAP_SUCCESS) {
2087                 DEBUG(10, ("Could not retrieve ncname: %s\n",
2088                            tldap_errstr(debug_ctx(), state->ld, rc)));
2089                 status = NT_STATUS_LDAP(rc);
2090                 goto done;
2091         }
2092         if (talloc_array_length(ncname) != 1) {
2093                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2094                 goto done;
2095         }
2096
2097         state->netbiosname = tldap_talloc_single_attribute(
2098                 ncname[0], "netbiosname", state);
2099         if (state->netbiosname == NULL) {
2100                 DEBUG(10, ("Could not get netbiosname\n"));
2101                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2102                 goto done;
2103         }
2104         DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2105
2106         if (!strequal(lp_workgroup(), state->netbiosname)) {
2107                 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2108                           state->netbiosname, lp_workgroup()));
2109                 status = NT_STATUS_NO_SUCH_DOMAIN;
2110                 goto done;
2111         }
2112
2113         secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2114
2115         status = NT_STATUS_OK;
2116 done:
2117         TALLOC_FREE(frame);
2118         return status;
2119 }
2120
2121 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2122                              const char *location)
2123 {
2124         struct pdb_methods *m;
2125         struct pdb_ads_state *state;
2126         char *tmp = NULL;
2127         NTSTATUS status;
2128
2129         m = talloc(talloc_autofree_context(), struct pdb_methods);
2130         if (m == NULL) {
2131                 return NT_STATUS_NO_MEMORY;
2132         }
2133         state = talloc(m, struct pdb_ads_state);
2134         if (state == NULL) {
2135                 goto nomem;
2136         }
2137         m->private_data = state;
2138         m->free_private_data = free_private_data;
2139         pdb_ads_init_methods(m);
2140
2141         if (location == NULL) {
2142                 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2143                                       lp_private_dir());
2144                 location = tmp;
2145         }
2146         if (location == NULL) {
2147                 goto nomem;
2148         }
2149
2150         status = pdb_ads_connect(state, location);
2151         if (!NT_STATUS_IS_OK(status)) {
2152                 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2153                 goto fail;
2154         }
2155
2156         *pdb_method = m;
2157         return NT_STATUS_OK;
2158 nomem:
2159         status = NT_STATUS_NO_MEMORY;
2160 fail:
2161         TALLOC_FREE(m);
2162         return status;
2163 }
2164
2165 NTSTATUS pdb_ads_init(void);
2166 NTSTATUS pdb_ads_init(void)
2167 {
2168         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
2169                                    pdb_init_ads);
2170 }