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