]> git.samba.org - ira/wip.git/blob - source3/passdb/pdb_ads.c
s3-tldap: only include tldap when actually needed.
[ira/wip.git] / source3 / passdb / pdb_ads.c
1 /*
2    Unix SMB/CIFS implementation.
3    pdb_ldap with ads schema
4    Copyright (C) Volker Lendecke 2009
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #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 DOM_SID *sid);
42 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
43                                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 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                                  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                                                    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 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 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                                                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 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;
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                 TALLOC_FREE(dn);
1217                 return NT_STATUS_LDAP(rc);
1218         }
1219         if (talloc_array_length(alias) != 1) {
1220                 DEBUG(10, ("Expected 1 alias, got %d\n",
1221                            (int)talloc_array_length(alias)));
1222                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1223         }
1224         if (!tldap_entry_dn(alias[0], &dn)) {
1225                 DEBUG(10, ("Could not get DN for alias %s\n",
1226                            sid_string_dbg(sid)));
1227                 return NT_STATUS_INTERNAL_ERROR;
1228         }
1229
1230         rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
1231         if (rc != TLDAP_SUCCESS) {
1232                 DEBUG(10, ("ldap_delete failed: %s\n",
1233                            tldap_errstr(talloc_tos(), state->ld, rc)));
1234                 TALLOC_FREE(dn);
1235                 return NT_STATUS_LDAP(rc);
1236         }
1237
1238         return NT_STATUS_OK;
1239 }
1240
1241 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1242                                       const DOM_SID *sid,
1243                                       struct acct_info *info)
1244 {
1245         struct pdb_ads_state *state = talloc_get_type_abort(
1246                 m->private_data, struct pdb_ads_state);
1247         struct tldap_context *ld;
1248         const char *attrs[3] = { "objectSid", "description",
1249                                  "samAccountName" };
1250         struct tldap_message **msg;
1251         char *sidstr, *dn;
1252         int rc;
1253         struct tldap_mod *mods;
1254         int num_mods;
1255         bool ok;
1256
1257         ld = pdb_ads_ld(state);
1258         if (ld == NULL) {
1259                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1260         }
1261
1262         sidstr = sid_binstring(talloc_tos(), sid);
1263         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1264
1265         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1266                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1267                                 &msg, "(&(objectSid=%s)(objectclass=group)"
1268                                 "(|(grouptype=%d)(grouptype=%d)))",
1269                                 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1270                                 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1271         TALLOC_FREE(sidstr);
1272         if (rc != TLDAP_SUCCESS) {
1273                 DEBUG(10, ("ldap_search failed %s\n",
1274                            tldap_errstr(talloc_tos(), state->ld, rc)));
1275                 return NT_STATUS_LDAP(rc);
1276         }
1277         switch talloc_array_length(msg) {
1278         case 0:
1279                 return NT_STATUS_NO_SUCH_ALIAS;
1280         case 1:
1281                 break;
1282         default:
1283                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1284         }
1285
1286         if (!tldap_entry_dn(msg[0], &dn)) {
1287                 TALLOC_FREE(msg);
1288                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1289         }
1290
1291         mods = NULL;
1292         num_mods = 0;
1293         ok = true;
1294
1295         ok &= tldap_make_mod_fmt(
1296                 msg[0], msg, &num_mods, &mods, "description",
1297                 "%s", info->acct_desc);
1298         ok &= tldap_make_mod_fmt(
1299                 msg[0], msg, &num_mods, &mods, "samAccountName",
1300                 "%s", info->acct_name);
1301         if (!ok) {
1302                 TALLOC_FREE(msg);
1303                 return NT_STATUS_NO_MEMORY;
1304         }
1305         if (num_mods == 0) {
1306                 /* no change */
1307                 TALLOC_FREE(msg);
1308                 return NT_STATUS_OK;
1309         }
1310
1311         rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1312         TALLOC_FREE(msg);
1313         if (rc != TLDAP_SUCCESS) {
1314                 DEBUG(10, ("ldap_modify failed: %s\n",
1315                            tldap_errstr(talloc_tos(), state->ld, rc)));
1316                 return NT_STATUS_LDAP(rc);
1317         }
1318         return NT_STATUS_OK;
1319 }
1320
1321 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1322                                const struct dom_sid *sid,
1323                                TALLOC_CTX *mem_ctx, char **pdn)
1324 {
1325         struct tldap_message **msg;
1326         char *sidstr, *dn;
1327         int rc;
1328
1329         sidstr = sid_binstring(talloc_tos(), sid);
1330         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1331
1332         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1333                                 NULL, 0, 0, talloc_tos(), &msg,
1334                                 "(objectsid=%s)", sidstr);
1335         TALLOC_FREE(sidstr);
1336         if (rc != TLDAP_SUCCESS) {
1337                 DEBUG(10, ("ldap_search failed %s\n",
1338                            tldap_errstr(talloc_tos(), state->ld, rc)));
1339                 return NT_STATUS_LDAP(rc);
1340         }
1341
1342         switch talloc_array_length(msg) {
1343         case 0:
1344                 return NT_STATUS_NOT_FOUND;
1345         case 1:
1346                 break;
1347         default:
1348                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1349         }
1350
1351         if (!tldap_entry_dn(msg[0], &dn)) {
1352                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1353         }
1354
1355         dn = talloc_strdup(mem_ctx, dn);
1356         if (dn == NULL) {
1357                 return NT_STATUS_NO_MEMORY;
1358         }
1359         TALLOC_FREE(msg);
1360
1361         *pdn = dn;
1362         return NT_STATUS_OK;
1363 }
1364
1365 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1366                                      const DOM_SID *alias,
1367                                      const DOM_SID *member,
1368                                      int mod_op)
1369 {
1370         struct pdb_ads_state *state = talloc_get_type_abort(
1371                 m->private_data, struct pdb_ads_state);
1372         struct tldap_context *ld;
1373         TALLOC_CTX *frame = talloc_stackframe();
1374         struct tldap_mod *mods;
1375         int rc;
1376         char *aliasdn, *memberdn;
1377         NTSTATUS status;
1378
1379         ld = pdb_ads_ld(state);
1380         if (ld == NULL) {
1381                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1382         }
1383
1384         status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1385         if (!NT_STATUS_IS_OK(status)) {
1386                 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1387                            sid_string_dbg(alias), nt_errstr(status)));
1388                 TALLOC_FREE(frame);
1389                 return NT_STATUS_NO_SUCH_ALIAS;
1390         }
1391         status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1392         if (!NT_STATUS_IS_OK(status)) {
1393                 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1394                            sid_string_dbg(member), nt_errstr(status)));
1395                 TALLOC_FREE(frame);
1396                 return status;
1397         }
1398
1399         mods = NULL;
1400
1401         if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1402                                "member", memberdn)) {
1403                 TALLOC_FREE(frame);
1404                 return NT_STATUS_NO_MEMORY;
1405         }
1406
1407         rc = tldap_modify(ld, aliasdn, 1, mods, NULL, 0, NULL, 0);
1408         TALLOC_FREE(frame);
1409         if (rc != TLDAP_SUCCESS) {
1410                 DEBUG(10, ("ldap_modify failed: %s\n",
1411                            tldap_errstr(talloc_tos(), state->ld, rc)));
1412                 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1413                         return NT_STATUS_MEMBER_IN_ALIAS;
1414                 }
1415                 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1416                         return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1417                 }
1418                 return NT_STATUS_LDAP(rc);
1419         }
1420
1421         return NT_STATUS_OK;
1422 }
1423
1424 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1425                                      const DOM_SID *alias,
1426                                      const DOM_SID *member)
1427 {
1428         return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1429 }
1430
1431 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1432                                      const DOM_SID *alias,
1433                                      const DOM_SID *member)
1434 {
1435         return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1436 }
1437
1438 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
1439                                struct dom_sid *psid)
1440 {
1441         const char *attrs[1] = { "objectSid" };
1442         struct tldap_message **msg;
1443         char *dn;
1444         size_t len;
1445         int rc;
1446         bool ret;
1447
1448         if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1449                                    dnblob->data, dnblob->length, &dn, &len,
1450                                    false)) {
1451                 return false;
1452         }
1453         rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
1454                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1455                                 &msg, "(objectclass=*)");
1456         TALLOC_FREE(dn);
1457         if (talloc_array_length(msg) != 1) {
1458                 DEBUG(10, ("Got %d objects, expected one\n",
1459                            (int)talloc_array_length(msg)));
1460                 TALLOC_FREE(msg);
1461                 return false;
1462         }
1463
1464         ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1465         TALLOC_FREE(msg);
1466         return ret;
1467 }
1468
1469 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1470                                       const DOM_SID *alias,
1471                                       TALLOC_CTX *mem_ctx,
1472                                       DOM_SID **pmembers,
1473                                       size_t *pnum_members)
1474 {
1475         struct pdb_ads_state *state = talloc_get_type_abort(
1476                 m->private_data, struct pdb_ads_state);
1477         const char *attrs[1] = { "member" };
1478         char *sidstr;
1479         struct tldap_message **msg;
1480         int i, rc, num_members;
1481         DATA_BLOB *blobs;
1482         struct dom_sid *members;
1483
1484         sidstr = sid_binstring(talloc_tos(), alias);
1485         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1486
1487         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1488                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1489                                 &msg, "(objectsid=%s)", sidstr);
1490         TALLOC_FREE(sidstr);
1491         if (rc != TLDAP_SUCCESS) {
1492                 DEBUG(10, ("ldap_search failed %s\n",
1493                            tldap_errstr(talloc_tos(), state->ld, rc)));
1494                 return NT_STATUS_LDAP(rc);
1495         }
1496         switch talloc_array_length(msg) {
1497         case 0:
1498                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1499                 break;
1500         case 1:
1501                 break;
1502         default:
1503                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1504                 break;
1505         }
1506
1507         if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1508                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1509         }
1510
1511         members = talloc_array(mem_ctx, struct dom_sid, num_members);
1512         if (members == NULL) {
1513                 return NT_STATUS_NO_MEMORY;
1514         }
1515
1516         for (i=0; i<num_members; i++) {
1517                 if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
1518                         TALLOC_FREE(members);
1519                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1520                 }
1521         }
1522
1523         *pmembers = members;
1524         *pnum_members = num_members;
1525         return NT_STATUS_OK;
1526 }
1527
1528 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1529                                                TALLOC_CTX *mem_ctx,
1530                                                const DOM_SID *domain_sid,
1531                                                const DOM_SID *members,
1532                                                size_t num_members,
1533                                                uint32_t **palias_rids,
1534                                                size_t *pnum_alias_rids)
1535 {
1536         struct pdb_ads_state *state = talloc_get_type_abort(
1537                 m->private_data, struct pdb_ads_state);
1538         const char *attrs[1] = { "objectSid" };
1539         struct tldap_message **msg;
1540         uint32_t *alias_rids = NULL;
1541         size_t num_alias_rids = 0;
1542         int i, rc, count;
1543         bool got_members = false;
1544         char *filter;
1545         NTSTATUS status;
1546
1547         /*
1548          * TODO: Get the filter right so that we only get the aliases from
1549          * either the SAM or BUILTIN
1550          */
1551
1552         filter = talloc_asprintf(talloc_tos(),
1553                                  "(&(|(grouptype=%d)(grouptype=%d))"
1554                                  "(objectclass=group)(|",
1555                                  GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1556                                  GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1557         if (filter == NULL) {
1558                 return NT_STATUS_NO_MEMORY;
1559         }
1560
1561         for (i=0; i<num_members; i++) {
1562                 char *dn;
1563
1564                 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1565                 if (!NT_STATUS_IS_OK(status)) {
1566                         DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1567                                    sid_string_dbg(&members[i]),
1568                                    nt_errstr(status)));
1569                         continue;
1570                 }
1571                 filter = talloc_asprintf_append_buffer(
1572                         filter, "(member=%s)", dn);
1573                 TALLOC_FREE(dn);
1574                 if (filter == NULL) {
1575                         return NT_STATUS_NO_MEMORY;
1576                 }
1577                 got_members = true;
1578         }
1579
1580         if (!got_members) {
1581                 goto done;
1582         }
1583
1584         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1585                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1586                                 &msg, "%s))", filter);
1587         TALLOC_FREE(filter);
1588         if (rc != TLDAP_SUCCESS) {
1589                 DEBUG(10, ("tldap_search failed %s\n",
1590                            tldap_errstr(talloc_tos(), state->ld, rc)));
1591                 return NT_STATUS_LDAP(rc);
1592         }
1593
1594         count = talloc_array_length(msg);
1595         if (count == 0) {
1596                 goto done;
1597         }
1598
1599         alias_rids = talloc_array(mem_ctx, uint32_t, count);
1600         if (alias_rids == NULL) {
1601                 TALLOC_FREE(msg);
1602                 return NT_STATUS_NO_MEMORY;
1603         }
1604
1605         for (i=0; i<count; i++) {
1606                 struct dom_sid sid;
1607
1608                 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1609                         DEBUG(10, ("Could not pull SID for member %d\n", i));
1610                         continue;
1611                 }
1612                 if (sid_peek_check_rid(domain_sid, &sid,
1613                                        &alias_rids[num_alias_rids])) {
1614                         num_alias_rids += 1;
1615                 }
1616         }
1617 done:
1618         TALLOC_FREE(msg);
1619         *palias_rids = alias_rids;
1620         *pnum_alias_rids = 0;
1621         return NT_STATUS_OK;
1622 }
1623
1624 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1625                                     const DOM_SID *domain_sid,
1626                                     int num_rids,
1627                                     uint32 *rids,
1628                                     const char **names,
1629                                     enum lsa_SidType *lsa_attrs)
1630 {
1631         struct pdb_ads_state *state = talloc_get_type_abort(
1632                 m->private_data, struct pdb_ads_state);
1633         const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1634         int i, num_mapped;
1635
1636         if (num_rids == 0) {
1637                 return NT_STATUS_NONE_MAPPED;
1638         }
1639
1640         num_mapped = 0;
1641
1642         for (i=0; i<num_rids; i++) {
1643                 struct dom_sid sid;
1644                 struct tldap_message **msg;
1645                 char *sidstr;
1646                 uint32_t attr;
1647                 int rc;
1648
1649                 lsa_attrs[i] = SID_NAME_UNKNOWN;
1650
1651                 sid_compose(&sid, domain_sid, rids[i]);
1652
1653                 sidstr = sid_binstring(talloc_tos(), &sid);
1654                 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1655
1656                 rc = pdb_ads_search_fmt(state, state->domaindn,
1657                                         TLDAP_SCOPE_SUB, attrs,
1658                                         ARRAY_SIZE(attrs), 0, talloc_tos(),
1659                                         &msg, "(objectsid=%s)", sidstr);
1660                 TALLOC_FREE(sidstr);
1661                 if (rc != TLDAP_SUCCESS) {
1662                         DEBUG(10, ("ldap_search failed %s\n",
1663                                    tldap_errstr(talloc_tos(), state->ld, rc)));
1664                         continue;
1665                 }
1666
1667                 switch talloc_array_length(msg) {
1668                 case 0:
1669                         DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1670                         continue;
1671                 case 1:
1672                         break;
1673                 default:
1674                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1675                 }
1676
1677                 names[i] = tldap_talloc_single_attribute(
1678                         msg[0], "samAccountName", talloc_tos());
1679                 if (names[i] == NULL) {
1680                         DEBUG(10, ("no samAccountName\n"));
1681                         continue;
1682                 }
1683                 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1684                         DEBUG(10, ("no samAccountType"));
1685                         continue;
1686                 }
1687                 lsa_attrs[i] = ds_atype_map(attr);
1688                 num_mapped += 1;
1689         }
1690
1691         if (num_mapped == 0) {
1692                 return NT_STATUS_NONE_MAPPED;
1693         }
1694         if (num_mapped < num_rids) {
1695                 return STATUS_SOME_UNMAPPED;
1696         }
1697         return NT_STATUS_OK;
1698 }
1699
1700 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1701                                      const DOM_SID *domain_sid,
1702                                      int num_names,
1703                                      const char **pp_names,
1704                                      uint32 *rids,
1705                                      enum lsa_SidType *attrs)
1706 {
1707         return NT_STATUS_NOT_IMPLEMENTED;
1708 }
1709
1710 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1711                                            enum pdb_policy_type type,
1712                                            uint32_t *value)
1713 {
1714         return account_policy_get(type, value)
1715                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1716 }
1717
1718 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1719                                            enum pdb_policy_type type,
1720                                            uint32_t value)
1721 {
1722         return account_policy_set(type, value)
1723                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1724 }
1725
1726 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1727                                     time_t *seq_num)
1728 {
1729         return NT_STATUS_NOT_IMPLEMENTED;
1730 }
1731
1732 struct pdb_ads_search_state {
1733         uint32_t acct_flags;
1734         struct samr_displayentry *entries;
1735         uint32_t num_entries;
1736         ssize_t array_size;
1737         uint32_t current;
1738 };
1739
1740 static bool pdb_ads_next_entry(struct pdb_search *search,
1741                                struct samr_displayentry *entry)
1742 {
1743         struct pdb_ads_search_state *state = talloc_get_type_abort(
1744                 search->private_data, struct pdb_ads_search_state);
1745
1746         if (state->current == state->num_entries) {
1747                 return false;
1748         }
1749
1750         entry->idx = state->entries[state->current].idx;
1751         entry->rid = state->entries[state->current].rid;
1752         entry->acct_flags = state->entries[state->current].acct_flags;
1753
1754         entry->account_name = talloc_strdup(
1755                 search, state->entries[state->current].account_name);
1756         entry->fullname = talloc_strdup(
1757                 search, state->entries[state->current].fullname);
1758         entry->description = talloc_strdup(
1759                 search, state->entries[state->current].description);
1760
1761         if ((entry->account_name == NULL) || (entry->fullname == NULL)
1762             || (entry->description == NULL)) {
1763                 DEBUG(0, ("talloc_strdup failed\n"));
1764                 return false;
1765         }
1766
1767         state->current += 1;
1768         return true;
1769 }
1770
1771 static void pdb_ads_search_end(struct pdb_search *search)
1772 {
1773         struct pdb_ads_search_state *state = talloc_get_type_abort(
1774                 search->private_data, struct pdb_ads_search_state);
1775         TALLOC_FREE(state);
1776 }
1777
1778 static bool pdb_ads_search_filter(struct pdb_methods *m,
1779                                   struct pdb_search *search,
1780                                   const char *filter,
1781                                   struct pdb_ads_search_state **pstate)
1782 {
1783         struct pdb_ads_state *state = talloc_get_type_abort(
1784                 m->private_data, struct pdb_ads_state);
1785         struct pdb_ads_search_state *sstate;
1786         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1787                                  "userAccountControl", "description" };
1788         struct tldap_message **users;
1789         int i, rc, num_users;
1790
1791         sstate = talloc_zero(search, struct pdb_ads_search_state);
1792         if (sstate == NULL) {
1793                 return false;
1794         }
1795
1796         rc = pdb_ads_search_fmt(
1797                 state, state->domaindn, TLDAP_SCOPE_SUB,
1798                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1799                 "%s", filter);
1800         if (rc != TLDAP_SUCCESS) {
1801                 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1802                            tldap_errstr(talloc_tos(), state->ld, rc)));
1803                 return false;
1804         }
1805
1806         num_users = talloc_array_length(users);
1807
1808         sstate->entries = talloc_array(sstate, struct samr_displayentry,
1809                                        num_users);
1810         if (sstate->entries == NULL) {
1811                 DEBUG(10, ("talloc failed\n"));
1812                 return false;
1813         }
1814
1815         sstate->num_entries = 0;
1816
1817         for (i=0; i<num_users; i++) {
1818                 struct samr_displayentry *e;
1819                 struct dom_sid sid;
1820
1821                 e = &sstate->entries[sstate->num_entries];
1822
1823                 e->idx = sstate->num_entries;
1824                 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1825                         DEBUG(10, ("Could not pull sid\n"));
1826                         continue;
1827                 }
1828                 sid_peek_rid(&sid, &e->rid);
1829                 e->acct_flags = ACB_NORMAL;
1830                 e->account_name = tldap_talloc_single_attribute(
1831                         users[i], "samAccountName", sstate->entries);
1832                 if (e->account_name == NULL) {
1833                         return false;
1834                 }
1835                 e->fullname = tldap_talloc_single_attribute(
1836                         users[i], "displayName", sstate->entries);
1837                 if (e->fullname == NULL) {
1838                         e->fullname = "";
1839                 }
1840                 e->description = tldap_talloc_single_attribute(
1841                         users[i], "description", sstate->entries);
1842                 if (e->description == NULL) {
1843                         e->description = "";
1844                 }
1845
1846                 sstate->num_entries += 1;
1847                 if (sstate->num_entries >= num_users) {
1848                         break;
1849                 }
1850         }
1851
1852         search->private_data = sstate;
1853         search->next_entry = pdb_ads_next_entry;
1854         search->search_end = pdb_ads_search_end;
1855         *pstate = sstate;
1856         return true;
1857 }
1858
1859 static bool pdb_ads_search_users(struct pdb_methods *m,
1860                                  struct pdb_search *search,
1861                                  uint32 acct_flags)
1862 {
1863         struct pdb_ads_search_state *sstate;
1864         bool ret;
1865
1866         ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1867         if (!ret) {
1868                 return false;
1869         }
1870         sstate->acct_flags = acct_flags;
1871         return true;
1872 }
1873
1874 static bool pdb_ads_search_groups(struct pdb_methods *m,
1875                                   struct pdb_search *search)
1876 {
1877         struct pdb_ads_search_state *sstate;
1878         char *filter;
1879         bool ret;
1880
1881         filter = talloc_asprintf(talloc_tos(),
1882                                  "(&(grouptype=%d)(objectclass=group))",
1883                                  GTYPE_SECURITY_GLOBAL_GROUP);
1884         if (filter == NULL) {
1885                 return false;
1886         }
1887         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1888         TALLOC_FREE(filter);
1889         if (!ret) {
1890                 return false;
1891         }
1892         sstate->acct_flags = 0;
1893         return true;
1894 }
1895
1896 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1897                                    struct pdb_search *search,
1898                                    const DOM_SID *sid)
1899 {
1900         struct pdb_ads_search_state *sstate;
1901         char *filter;
1902         bool ret;
1903
1904         filter = talloc_asprintf(
1905                 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1906                 sid_check_is_builtin(sid)
1907                 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1908                 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1909
1910         if (filter == NULL) {
1911                 return false;
1912         }
1913         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1914         TALLOC_FREE(filter);
1915         if (!ret) {
1916                 return false;
1917         }
1918         sstate->acct_flags = 0;
1919         return true;
1920 }
1921
1922 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1923                                DOM_SID *sid)
1924 {
1925         struct pdb_ads_state *state = talloc_get_type_abort(
1926                 m->private_data, struct pdb_ads_state);
1927         sid_compose(sid, &state->domainsid, uid);
1928         return true;
1929 }
1930
1931 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1932                                DOM_SID *sid)
1933 {
1934         struct pdb_ads_state *state = talloc_get_type_abort(
1935                 m->private_data, struct pdb_ads_state);
1936         sid_compose(sid, &state->domainsid, gid);
1937         return true;
1938 }
1939
1940 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1941                               union unid_t *id, enum lsa_SidType *type)
1942 {
1943         struct pdb_ads_state *state = talloc_get_type_abort(
1944                 m->private_data, struct pdb_ads_state);
1945         struct tldap_message **msg;
1946         char *sidstr;
1947         uint32_t rid;
1948         int rc;
1949
1950         /*
1951          * This is a big, big hack: Just hard-code the rid as uid/gid.
1952          */
1953
1954         sid_peek_rid(sid, &rid);
1955
1956         sidstr = sid_binstring(talloc_tos(), sid);
1957         if (sidstr == NULL) {
1958                 return false;
1959         }
1960
1961         rc = pdb_ads_search_fmt(
1962                 state, state->domaindn, TLDAP_SCOPE_SUB,
1963                 NULL, 0, 0, talloc_tos(), &msg,
1964                 "(&(objectsid=%s)(objectclass=user))", sidstr);
1965         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1966                 id->uid = rid;
1967                 *type = SID_NAME_USER;
1968                 TALLOC_FREE(sidstr);
1969                 return true;
1970         }
1971
1972         rc = pdb_ads_search_fmt(
1973                 state, state->domaindn, TLDAP_SCOPE_SUB,
1974                 NULL, 0, 0, talloc_tos(), &msg,
1975                 "(&(objectsid=%s)(objectclass=group))", sidstr);
1976         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1977                 id->gid = rid;
1978                 *type = SID_NAME_DOM_GRP;
1979                 TALLOC_FREE(sidstr);
1980                 return true;
1981         }
1982
1983         TALLOC_FREE(sidstr);
1984         return false;
1985 }
1986
1987 static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
1988 {
1989         return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
1990 }
1991
1992 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1993 {
1994         return false;
1995 }
1996
1997 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1998                                       const char *domain, char** pwd,
1999                                       DOM_SID *sid,
2000                                       time_t *pass_last_set_time)
2001 {
2002         return false;
2003 }
2004
2005 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
2006                                       const char* domain, const char* pwd,
2007                                       const DOM_SID *sid)
2008 {
2009         return false;
2010 }
2011
2012 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
2013                                       const char *domain)
2014 {
2015         return false;
2016 }
2017
2018 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
2019                                          TALLOC_CTX *mem_ctx,
2020                                          uint32 *num_domains,
2021                                          struct trustdom_info ***domains)
2022 {
2023         *num_domains = 0;
2024         *domains = NULL;
2025         return NT_STATUS_OK;
2026 }
2027
2028 static void pdb_ads_init_methods(struct pdb_methods *m)
2029 {
2030         m->name = "ads";
2031         m->get_domain_info = pdb_ads_get_domain_info;
2032         m->getsampwnam = pdb_ads_getsampwnam;
2033         m->getsampwsid = pdb_ads_getsampwsid;
2034         m->create_user = pdb_ads_create_user;
2035         m->delete_user = pdb_ads_delete_user;
2036         m->add_sam_account = pdb_ads_add_sam_account;
2037         m->update_sam_account = pdb_ads_update_sam_account;
2038         m->delete_sam_account = pdb_ads_delete_sam_account;
2039         m->rename_sam_account = pdb_ads_rename_sam_account;
2040         m->update_login_attempts = pdb_ads_update_login_attempts;
2041         m->getgrsid = pdb_ads_getgrsid;
2042         m->getgrgid = pdb_ads_getgrgid;
2043         m->getgrnam = pdb_ads_getgrnam;
2044         m->create_dom_group = pdb_ads_create_dom_group;
2045         m->delete_dom_group = pdb_ads_delete_dom_group;
2046         m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
2047         m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
2048         m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
2049         m->enum_group_mapping = pdb_ads_enum_group_mapping;
2050         m->enum_group_members = pdb_ads_enum_group_members;
2051         m->enum_group_memberships = pdb_ads_enum_group_memberships;
2052         m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
2053         m->add_groupmem = pdb_ads_add_groupmem;
2054         m->del_groupmem = pdb_ads_del_groupmem;
2055         m->create_alias = pdb_ads_create_alias;
2056         m->delete_alias = pdb_ads_delete_alias;
2057         m->get_aliasinfo = pdb_default_get_aliasinfo;
2058         m->set_aliasinfo = pdb_ads_set_aliasinfo;
2059         m->add_aliasmem = pdb_ads_add_aliasmem;
2060         m->del_aliasmem = pdb_ads_del_aliasmem;
2061         m->enum_aliasmem = pdb_ads_enum_aliasmem;
2062         m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
2063         m->lookup_rids = pdb_ads_lookup_rids;
2064         m->lookup_names = pdb_ads_lookup_names;
2065         m->get_account_policy = pdb_ads_get_account_policy;
2066         m->set_account_policy = pdb_ads_set_account_policy;
2067         m->get_seq_num = pdb_ads_get_seq_num;
2068         m->search_users = pdb_ads_search_users;
2069         m->search_groups = pdb_ads_search_groups;
2070         m->search_aliases = pdb_ads_search_aliases;
2071         m->uid_to_sid = pdb_ads_uid_to_sid;
2072         m->gid_to_sid = pdb_ads_gid_to_sid;
2073         m->sid_to_id = pdb_ads_sid_to_id;
2074         m->capabilities = pdb_ads_capabilities;
2075         m->new_rid = pdb_ads_new_rid;
2076         m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2077         m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2078         m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2079         m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2080 }
2081
2082 static void free_private_data(void **vp)
2083 {
2084         struct pdb_ads_state *state = talloc_get_type_abort(
2085                 *vp, struct pdb_ads_state);
2086
2087         TALLOC_FREE(state->ld);
2088         return;
2089 }
2090
2091 /*
2092   this is used to catch debug messages from events
2093 */
2094 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2095                            const char *fmt, va_list ap)  PRINTF_ATTRIBUTE(3,0);
2096
2097 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2098                            const char *fmt, va_list ap)
2099 {
2100         int samba_level = -1;
2101         char *s = NULL;
2102         switch (level) {
2103         case TLDAP_DEBUG_FATAL:
2104                 samba_level = 0;
2105                 break;
2106         case TLDAP_DEBUG_ERROR:
2107                 samba_level = 1;
2108                 break;
2109         case TLDAP_DEBUG_WARNING:
2110                 samba_level = 2;
2111                 break;
2112         case TLDAP_DEBUG_TRACE:
2113                 samba_level = 11;
2114                 break;
2115
2116         };
2117         if (vasprintf(&s, fmt, ap) == -1) {
2118                 return;
2119         }
2120         DEBUG(samba_level, ("tldap: %s", s));
2121         free(s);
2122 }
2123
2124 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2125 {
2126         NTSTATUS status;
2127         int fd;
2128
2129         if (tldap_connection_ok(state->ld)) {
2130                 return state->ld;
2131         }
2132         TALLOC_FREE(state->ld);
2133
2134         status = open_socket_out(
2135                 (struct sockaddr_storage *)(void *)&state->socket_address,
2136                 0, 0, &fd);
2137         if (!NT_STATUS_IS_OK(status)) {
2138                 DEBUG(10, ("Could not connect to %s: %s\n",
2139                            state->socket_address.sun_path, nt_errstr(status)));
2140                 return NULL;
2141         }
2142
2143         set_blocking(fd, false);
2144
2145         state->ld = tldap_context_create(state, fd);
2146         if (state->ld == NULL) {
2147                 close(fd);
2148                 return NULL;
2149         }
2150         tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2151
2152         return state->ld;
2153 }
2154
2155 int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2156                        int scope, const char *attrs[], int num_attrs,
2157                        int attrsonly,
2158                        TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2159                        const char *fmt, ...)
2160 {
2161         struct tldap_context *ld;
2162         va_list ap;
2163         int ret;
2164
2165         ld = pdb_ads_ld(state);
2166         if (ld == NULL) {
2167                 return TLDAP_SERVER_DOWN;
2168         }
2169
2170         va_start(ap, fmt);
2171         ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2172                               mem_ctx, res, fmt, ap);
2173         va_end(ap);
2174
2175         if (ret != TLDAP_SERVER_DOWN) {
2176                 return ret;
2177         }
2178
2179         /* retry once */
2180         ld = pdb_ads_ld(state);
2181         if (ld == NULL) {
2182                 return TLDAP_SERVER_DOWN;
2183         }
2184
2185         va_start(ap, fmt);
2186         ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2187                               mem_ctx, res, fmt, ap);
2188         va_end(ap);
2189         return ret;
2190 }
2191
2192 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2193                                 const char *location)
2194 {
2195         const char *domain_attrs[2] = { "objectSid", "objectGUID" };
2196         const char *ncname_attrs[1] = { "netbiosname" };
2197         struct tldap_context *ld;
2198         struct tldap_message *rootdse, **domain, **ncname;
2199         TALLOC_CTX *frame = talloc_stackframe();
2200         NTSTATUS status;
2201         int num_domains;
2202         int rc;
2203
2204         ZERO_STRUCT(state->socket_address);
2205         state->socket_address.sun_family = AF_UNIX;
2206         strncpy(state->socket_address.sun_path, location,
2207                 sizeof(state->socket_address.sun_path) - 1);
2208
2209         ld = pdb_ads_ld(state);
2210         if (ld == NULL) {
2211                 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2212                 goto done;
2213         }
2214
2215         rc = tldap_fetch_rootdse(ld);
2216         if (rc != TLDAP_SUCCESS) {
2217                 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2218                            tldap_errstr(talloc_tos(), state->ld, rc)));
2219                 status = NT_STATUS_LDAP(rc);
2220                 goto done;
2221         }
2222         rootdse = tldap_rootdse(state->ld);
2223
2224         state->domaindn = tldap_talloc_single_attribute(
2225                 rootdse, "defaultNamingContext", state);
2226         if (state->domaindn == NULL) {
2227                 DEBUG(10, ("Could not get defaultNamingContext\n"));
2228                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2229                 goto done;
2230         }
2231         DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2232
2233         state->configdn = tldap_talloc_single_attribute(
2234                 rootdse, "configurationNamingContext", state);
2235         if (state->domaindn == NULL) {
2236                 DEBUG(10, ("Could not get configurationNamingContext\n"));
2237                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2238                 goto done;
2239         }
2240         DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2241
2242         /*
2243          * Figure out our domain's SID
2244          */
2245         rc = pdb_ads_search_fmt(
2246                 state, state->domaindn, TLDAP_SCOPE_BASE,
2247                 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2248                 talloc_tos(), &domain, "(objectclass=*)");
2249         if (rc != TLDAP_SUCCESS) {
2250                 DEBUG(10, ("Could not retrieve domain: %s\n",
2251                            tldap_errstr(talloc_tos(), state->ld, rc)));
2252                 status = NT_STATUS_LDAP(rc);
2253                 goto done;
2254         }
2255
2256         num_domains = talloc_array_length(domain);
2257         if (num_domains != 1) {
2258                 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2259                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2260                 goto done;
2261         }
2262         if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2263                 DEBUG(10, ("Could not retrieve domain SID\n"));
2264                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2265                 goto done;
2266         }
2267         if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) {
2268                 DEBUG(10, ("Could not retrieve domain GUID\n"));
2269                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2270                 goto done;
2271         }
2272         DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2273
2274         /*
2275          * Figure out our domain's short name
2276          */
2277         rc = pdb_ads_search_fmt(
2278                 state, state->configdn, TLDAP_SCOPE_SUB,
2279                 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2280                 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2281         if (rc != TLDAP_SUCCESS) {
2282                 DEBUG(10, ("Could not retrieve ncname: %s\n",
2283                            tldap_errstr(talloc_tos(), state->ld, rc)));
2284                 status = NT_STATUS_LDAP(rc);
2285                 goto done;
2286         }
2287         if (talloc_array_length(ncname) != 1) {
2288                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2289                 goto done;
2290         }
2291
2292         state->netbiosname = tldap_talloc_single_attribute(
2293                 ncname[0], "netbiosname", state);
2294         if (state->netbiosname == NULL) {
2295                 DEBUG(10, ("Could not get netbiosname\n"));
2296                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2297                 goto done;
2298         }
2299         DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2300
2301         if (!strequal(lp_workgroup(), state->netbiosname)) {
2302                 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2303                           state->netbiosname, lp_workgroup()));
2304                 status = NT_STATUS_NO_SUCH_DOMAIN;
2305                 goto done;
2306         }
2307
2308         secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2309
2310         status = NT_STATUS_OK;
2311 done:
2312         TALLOC_FREE(frame);
2313         return status;
2314 }
2315
2316 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2317                              const char *location)
2318 {
2319         struct pdb_methods *m;
2320         struct pdb_ads_state *state;
2321         char *tmp = NULL;
2322         NTSTATUS status;
2323
2324         m = talloc(talloc_autofree_context(), struct pdb_methods);
2325         if (m == NULL) {
2326                 return NT_STATUS_NO_MEMORY;
2327         }
2328         state = talloc_zero(m, struct pdb_ads_state);
2329         if (state == NULL) {
2330                 goto nomem;
2331         }
2332         m->private_data = state;
2333         m->free_private_data = free_private_data;
2334         pdb_ads_init_methods(m);
2335
2336         if (location == NULL) {
2337                 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2338                                       lp_private_dir());
2339                 location = tmp;
2340         }
2341         if (location == NULL) {
2342                 goto nomem;
2343         }
2344
2345         status = pdb_ads_connect(state, location);
2346         if (!NT_STATUS_IS_OK(status)) {
2347                 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2348                 goto fail;
2349         }
2350
2351         *pdb_method = m;
2352         return NT_STATUS_OK;
2353 nomem:
2354         status = NT_STATUS_NO_MEMORY;
2355 fail:
2356         TALLOC_FREE(m);
2357         return status;
2358 }
2359
2360 NTSTATUS pdb_ads_init(void);
2361 NTSTATUS pdb_ads_init(void)
2362 {
2363         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
2364                                    pdb_init_ads);
2365 }