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