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