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