s3-secrets: only include secrets.h when needed.
[nivanova/samba-autobuild/.git] / source3 / passdb / pdb_ads.c
1 /*
2    Unix SMB/CIFS implementation.
3    pdb_ldap with ads schema
4    Copyright (C) Volker Lendecke 2009
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #include "tldap.h"
22 #include "tldap_util.h"
23 #include "../libds/common/flags.h"
24 #include "secrets.h"
25
26 struct pdb_ads_state {
27         struct sockaddr_un socket_address;
28         struct tldap_context *ld;
29         struct dom_sid domainsid;
30         struct GUID domainguid;
31         char *domaindn;
32         char *configdn;
33         char *netbiosname;
34 };
35
36 struct pdb_ads_samu_private {
37         char *dn;
38         struct tldap_message *ldapmsg;
39 };
40
41 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
42                                     struct samu *sam_acct,
43                                     const struct dom_sid *sid);
44 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
45                                struct dom_sid *sid);
46 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
47                                struct dom_sid *psid);
48 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
49                                const struct dom_sid *sid,
50                                TALLOC_CTX *mem_ctx, char **pdn);
51 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state);
52 static int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
53                               int scope, const char *attrs[], int num_attrs,
54                               int attrsonly,
55                               TALLOC_CTX *mem_ctx, struct tldap_message ***res,
56                               const char *fmt, ...);
57 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
58                                     const char *filter,
59                                     TALLOC_CTX *mem_ctx,
60                                     struct pdb_ads_samu_private **presult);
61
62 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
63                               time_t *ptime)
64 {
65         uint64_t tmp;
66
67         if (!tldap_pull_uint64(msg, attr, &tmp)) {
68                 return false;
69         }
70         *ptime = uint64s_nt_time_to_unix_abs(&tmp);
71         return true;
72 }
73
74 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
75 {
76         uint32_t rid;
77         sid_peek_rid(sid, &rid);
78         return rid;
79 }
80
81 static char *pdb_ads_domaindn2dns(TALLOC_CTX *mem_ctx, char *dn)
82 {
83         char *result, *p;
84
85         result = talloc_string_sub2(mem_ctx, dn, "DC=", "", false, false,
86                                     true);
87         if (result == NULL) {
88                 return NULL;
89         }
90
91         while ((p = strchr_m(result, ',')) != NULL) {
92                 *p = '.';
93         }
94
95         return result;
96 }
97
98 static struct pdb_domain_info *pdb_ads_get_domain_info(
99         struct pdb_methods *m, TALLOC_CTX *mem_ctx)
100 {
101         struct pdb_ads_state *state = talloc_get_type_abort(
102                 m->private_data, struct pdb_ads_state);
103         struct pdb_domain_info *info;
104         struct tldap_message *rootdse;
105         char *tmp;
106
107         info = talloc(mem_ctx, struct pdb_domain_info);
108         if (info == NULL) {
109                 return NULL;
110         }
111         info->name = talloc_strdup(info, state->netbiosname);
112         if (info->name == NULL) {
113                 goto fail;
114         }
115         info->dns_domain = pdb_ads_domaindn2dns(info, state->domaindn);
116         if (info->dns_domain == NULL) {
117                 goto fail;
118         }
119
120         rootdse = tldap_rootdse(state->ld);
121         tmp = tldap_talloc_single_attribute(rootdse, "rootDomainNamingContext",
122                                             talloc_tos());
123         if (tmp == NULL) {
124                 goto fail;
125         }
126         info->dns_forest = pdb_ads_domaindn2dns(info, tmp);
127         TALLOC_FREE(tmp);
128         if (info->dns_forest == NULL) {
129                 goto fail;
130         }
131         info->sid = state->domainsid;
132         info->guid = state->domainguid;
133         return info;
134
135 fail:
136         TALLOC_FREE(info);
137         return NULL;
138 }
139
140 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
141         struct pdb_methods *m, struct samu *sam)
142 {
143         struct pdb_ads_state *state = talloc_get_type_abort(
144                 m->private_data, struct pdb_ads_state);
145         struct pdb_ads_samu_private *result;
146         char *sidstr, *filter;
147         NTSTATUS status;
148
149         result = (struct pdb_ads_samu_private *)
150                 pdb_get_backend_private_data(sam, m);
151
152         if (result != NULL) {
153                 return talloc_get_type_abort(
154                         result, struct pdb_ads_samu_private);
155         }
156
157         sidstr = sid_binstring(talloc_tos(), pdb_get_user_sid(sam));
158         if (sidstr == NULL) {
159                 return NULL;
160         }
161
162         filter = talloc_asprintf(
163                 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
164         TALLOC_FREE(sidstr);
165         if (filter == NULL) {
166                 return NULL;
167         }
168
169         status = pdb_ads_getsamupriv(state, filter, sam, &result);
170         TALLOC_FREE(filter);
171         if (!NT_STATUS_IS_OK(status)) {
172                 return NULL;
173         }
174
175         return result;
176 }
177
178 static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m,
179                                            struct samu *sam,
180                                            struct pdb_ads_samu_private *priv)
181 {
182         struct pdb_ads_state *state = talloc_get_type_abort(
183                 m->private_data, struct pdb_ads_state);
184         TALLOC_CTX *frame = talloc_stackframe();
185         NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
186         struct tldap_message *entry = priv->ldapmsg;
187         char *str;
188         time_t tmp_time;
189         struct dom_sid sid;
190         uint64_t n;
191         DATA_BLOB blob;
192
193         str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
194         if (str == NULL) {
195                 DEBUG(10, ("no samAccountName\n"));
196                 goto fail;
197         }
198         pdb_set_username(sam, str, PDB_SET);
199
200         if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
201                 pdb_set_logon_time(sam, tmp_time, PDB_SET);
202         }
203         if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
204                 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
205         }
206         if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
207                 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
208         }
209         if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
210                 pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
211         }
212
213         str = tldap_talloc_single_attribute(entry, "displayName",
214                                             talloc_tos());
215         if (str != NULL) {
216                 pdb_set_fullname(sam, str, PDB_SET);
217         }
218
219         str = tldap_talloc_single_attribute(entry, "homeDirectory",
220                                             talloc_tos());
221         if (str != NULL) {
222                 pdb_set_homedir(sam, str, PDB_SET);
223         }
224
225         str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
226         if (str != NULL) {
227                 pdb_set_dir_drive(sam, str, PDB_SET);
228         }
229
230         str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
231         if (str != NULL) {
232                 pdb_set_logon_script(sam, str, PDB_SET);
233         }
234
235         str = tldap_talloc_single_attribute(entry, "profilePath",
236                                             talloc_tos());
237         if (str != NULL) {
238                 pdb_set_profile_path(sam, str, PDB_SET);
239         }
240
241         str = tldap_talloc_single_attribute(entry, "profilePath",
242                                             talloc_tos());
243         if (str != NULL) {
244                 pdb_set_profile_path(sam, str, PDB_SET);
245         }
246
247         if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
248                 DEBUG(10, ("Could not pull SID\n"));
249                 goto fail;
250         }
251         pdb_set_user_sid(sam, &sid, PDB_SET);
252
253         if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
254                 DEBUG(10, ("Could not pull userAccountControl\n"));
255                 goto fail;
256         }
257         pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
258
259         if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
260                 if (blob.length != NT_HASH_LEN) {
261                         DEBUG(0, ("Got NT hash of length %d, expected %d\n",
262                                   (int)blob.length, NT_HASH_LEN));
263                         goto fail;
264                 }
265                 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
266         }
267
268         if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
269                 if (blob.length != LM_HASH_LEN) {
270                         DEBUG(0, ("Got LM hash of length %d, expected %d\n",
271                                   (int)blob.length, LM_HASH_LEN));
272                         goto fail;
273                 }
274                 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
275         }
276
277         if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
278                 sid_compose(&sid, &state->domainsid, n);
279                 pdb_set_group_sid(sam, &sid, PDB_SET);
280
281         }
282         status = NT_STATUS_OK;
283 fail:
284         TALLOC_FREE(frame);
285         return status;
286 }
287
288 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
289                                       struct tldap_message *existing,
290                                       TALLOC_CTX *mem_ctx,
291                                       int *pnum_mods, struct tldap_mod **pmods,
292                                       struct samu *sam)
293 {
294         bool ret = true;
295         DATA_BLOB blob;
296
297         /* TODO: All fields :-) */
298
299         ret &= tldap_make_mod_fmt(
300                 existing, mem_ctx, pnum_mods, pmods, "displayName",
301                 "%s", pdb_get_fullname(sam));
302
303         blob = data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN);
304         if (blob.data != NULL) {
305                 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
306                                            "unicodePwd", 1, &blob);
307         }
308
309         blob = data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN);
310         if (blob.data != NULL) {
311                 ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE,
312                                            "dBCSPwd", 1, &blob);
313         }
314
315         ret &= tldap_make_mod_fmt(
316                 existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
317                 "%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
318
319         ret &= tldap_make_mod_fmt(
320                 existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
321                 "%s", pdb_get_homedir(sam));
322
323         ret &= tldap_make_mod_fmt(
324                 existing, mem_ctx, pnum_mods, pmods, "homeDrive",
325                 "%s", pdb_get_dir_drive(sam));
326
327         ret &= tldap_make_mod_fmt(
328                 existing, mem_ctx, pnum_mods, pmods, "scriptPath",
329                 "%s", pdb_get_logon_script(sam));
330
331         ret &= tldap_make_mod_fmt(
332                 existing, mem_ctx, pnum_mods, pmods, "profilePath",
333                 "%s", pdb_get_profile_path(sam));
334
335         return ret;
336 }
337
338 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
339                                     const char *filter,
340                                     TALLOC_CTX *mem_ctx,
341                                     struct pdb_ads_samu_private **presult)
342 {
343         const char * attrs[] = {
344                 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
345                 "sAMAccountName", "displayName", "homeDirectory",
346                 "homeDrive", "scriptPath", "profilePath", "description",
347                 "userWorkstations", "comment", "userParameters", "objectSid",
348                 "primaryGroupID", "userAccountControl", "logonHours",
349                 "badPwdCount", "logonCount", "countryCode", "codePage",
350                 "unicodePwd", "dBCSPwd" };
351         struct tldap_message **users;
352         int rc, count;
353         struct pdb_ads_samu_private *result;
354
355         result = talloc(mem_ctx, struct pdb_ads_samu_private);
356         if (result == NULL) {
357                 return NT_STATUS_NO_MEMORY;
358         }
359
360         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
361                                 attrs, ARRAY_SIZE(attrs), 0, result,
362                                 &users, "%s", filter);
363         if (rc != TLDAP_SUCCESS) {
364                 DEBUG(10, ("ldap_search failed %s\n",
365                            tldap_errstr(talloc_tos(), state->ld, rc)));
366                 TALLOC_FREE(result);
367                 return NT_STATUS_LDAP(rc);
368         }
369
370         count = talloc_array_length(users);
371         if (count != 1) {
372                 DEBUG(10, ("Expected 1 user, got %d\n", count));
373                 TALLOC_FREE(result);
374                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
375         }
376
377         result->ldapmsg = users[0];
378         if (!tldap_entry_dn(result->ldapmsg, &result->dn)) {
379                 DEBUG(10, ("Could not extract dn\n"));
380                 TALLOC_FREE(result);
381                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
382         }
383
384         *presult = result;
385         return NT_STATUS_OK;
386 }
387
388 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
389                                        struct pdb_ads_state *state,
390                                        struct samu *sam_acct,
391                                        const char *filter)
392 {
393         struct pdb_ads_samu_private *priv;
394         NTSTATUS status;
395
396         status = pdb_ads_getsamupriv(state, filter, sam_acct, &priv);
397         if (!NT_STATUS_IS_OK(status)) {
398                 DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n",
399                            nt_errstr(status)));
400                 return status;
401         }
402
403         status = pdb_ads_init_sam_from_priv(m, sam_acct, priv);
404         if (!NT_STATUS_IS_OK(status)) {
405                 DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n",
406                            nt_errstr(status)));
407                 TALLOC_FREE(priv);
408                 return status;
409         }
410
411         pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
412         return NT_STATUS_OK;
413 }
414
415 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
416                                     struct samu *sam_acct,
417                                     const char *username)
418 {
419         struct pdb_ads_state *state = talloc_get_type_abort(
420                 m->private_data, struct pdb_ads_state);
421         char *filter;
422
423         filter = talloc_asprintf(
424                 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
425                 username);
426         NT_STATUS_HAVE_NO_MEMORY(filter);
427
428         return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
429 }
430
431 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
432                                     struct samu *sam_acct,
433                                     const struct dom_sid *sid)
434 {
435         struct pdb_ads_state *state = talloc_get_type_abort(
436                 m->private_data, struct pdb_ads_state);
437         char *sidstr, *filter;
438
439         sidstr = sid_binstring(talloc_tos(), sid);
440         NT_STATUS_HAVE_NO_MEMORY(sidstr);
441
442         filter = talloc_asprintf(
443                 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
444         TALLOC_FREE(sidstr);
445         NT_STATUS_HAVE_NO_MEMORY(filter);
446
447         return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
448 }
449
450 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
451                                     TALLOC_CTX *tmp_ctx,
452                                     const char *name, uint32 acct_flags,
453                                     uint32 *rid)
454 {
455         struct pdb_ads_state *state = talloc_get_type_abort(
456                 m->private_data, struct pdb_ads_state);
457         struct tldap_context *ld;
458         const char *attrs[1] = { "objectSid" };
459         struct tldap_mod *mods = NULL;
460         int num_mods = 0;
461         struct tldap_message **user;
462         struct dom_sid sid;
463         char *dn;
464         int rc;
465         bool ok;
466
467         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
468                              state->domaindn);
469         if (dn == NULL) {
470                 return NT_STATUS_NO_MEMORY;
471         }
472
473         ld = pdb_ads_ld(state);
474         if (ld == NULL) {
475                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
476         }
477
478         /* TODO: Create machines etc */
479
480         ok = true;
481         ok &= tldap_make_mod_fmt(
482                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
483         ok &= tldap_make_mod_fmt(
484                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
485                 name);
486         if (!ok) {
487                 return NT_STATUS_NO_MEMORY;
488         }
489
490
491         rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
492         if (rc != TLDAP_SUCCESS) {
493                 DEBUG(10, ("ldap_add failed %s\n",
494                            tldap_errstr(talloc_tos(), ld, rc)));
495                 TALLOC_FREE(dn);
496                 return NT_STATUS_LDAP(rc);
497         }
498
499         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
500                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
501                                 &user,
502                                 "(&(objectclass=user)(samaccountname=%s))",
503                                 name);
504         if (rc != TLDAP_SUCCESS) {
505                 DEBUG(10, ("Could not find just created user %s: %s\n",
506                            name, tldap_errstr(talloc_tos(), state->ld, rc)));
507                 TALLOC_FREE(dn);
508                 return NT_STATUS_LDAP(rc);
509         }
510
511         if (talloc_array_length(user) != 1) {
512                 DEBUG(10, ("Got %d users, expected one\n",
513                            (int)talloc_array_length(user)));
514                 TALLOC_FREE(dn);
515                 return NT_STATUS_LDAP(rc);
516         }
517
518         if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
519                 DEBUG(10, ("Could not fetch objectSid from user %s\n",
520                            name));
521                 TALLOC_FREE(dn);
522                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
523         }
524
525         sid_peek_rid(&sid, rid);
526         TALLOC_FREE(dn);
527         return NT_STATUS_OK;
528 }
529
530 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
531                                     TALLOC_CTX *tmp_ctx,
532                                     struct samu *sam)
533 {
534         struct pdb_ads_state *state = talloc_get_type_abort(
535                 m->private_data, struct pdb_ads_state);
536         NTSTATUS status;
537         struct tldap_context *ld;
538         char *dn;
539         int rc;
540
541         ld = pdb_ads_ld(state);
542         if (ld == NULL) {
543                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
544         }
545
546         status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
547                                 &dn);
548         if (!NT_STATUS_IS_OK(status)) {
549                 return status;
550         }
551
552         rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
553         TALLOC_FREE(dn);
554         if (rc != TLDAP_SUCCESS) {
555                 DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
556                            tldap_errstr(talloc_tos(), ld, rc)));
557                 return NT_STATUS_LDAP(rc);
558         }
559         return NT_STATUS_OK;
560 }
561
562 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
563                                         struct samu *sampass)
564 {
565         return NT_STATUS_NOT_IMPLEMENTED;
566 }
567
568 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
569                                            struct samu *sam)
570 {
571         struct pdb_ads_state *state = talloc_get_type_abort(
572                 m->private_data, struct pdb_ads_state);
573         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
574         struct tldap_context *ld;
575         struct tldap_mod *mods = NULL;
576         int rc, num_mods = 0;
577
578         ld = pdb_ads_ld(state);
579         if (ld == NULL) {
580                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
581         }
582
583         if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
584                                        &num_mods, &mods, sam)) {
585                 return NT_STATUS_NO_MEMORY;
586         }
587
588         if (num_mods == 0) {
589                 /* Nothing to do, just return success */
590                 return NT_STATUS_OK;
591         }
592
593         rc = tldap_modify(ld, priv->dn, num_mods, mods, NULL, 0,
594                           NULL, 0);
595         TALLOC_FREE(mods);
596         if (rc != TLDAP_SUCCESS) {
597                 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
598                            tldap_errstr(talloc_tos(), ld, rc)));
599                 return NT_STATUS_LDAP(rc);
600         }
601
602         return NT_STATUS_OK;
603 }
604
605 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
606                                            struct samu *username)
607 {
608         return NT_STATUS_NOT_IMPLEMENTED;
609 }
610
611 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
612                                            struct samu *oldname,
613                                            const char *newname)
614 {
615         return NT_STATUS_NOT_IMPLEMENTED;
616 }
617
618 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
619                                               struct samu *sam_acct,
620                                               bool success)
621 {
622         return NT_STATUS_NOT_IMPLEMENTED;
623 }
624
625 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
626                                     const char *filter)
627 {
628         struct pdb_ads_state *state = talloc_get_type_abort(
629                 m->private_data, struct pdb_ads_state);
630         const char *attrs[4] = { "objectSid", "description", "samAccountName",
631                                  "groupType" };
632         char *str;
633         struct tldap_message **group;
634         uint32_t grouptype;
635         int rc;
636
637         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
638                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
639                                 &group, "%s", filter);
640         if (rc != TLDAP_SUCCESS) {
641                 DEBUG(10, ("ldap_search failed %s\n",
642                            tldap_errstr(talloc_tos(), state->ld, rc)));
643                 return NT_STATUS_LDAP(rc);
644         }
645         if (talloc_array_length(group) != 1) {
646                 DEBUG(10, ("Expected 1 user, got %d\n",
647                            (int)talloc_array_length(group)));
648                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
649         }
650
651         if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
652                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
653         }
654         map->gid = pdb_ads_sid2gid(&map->sid);
655
656         if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
657                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
658         }
659         switch (grouptype) {
660         case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
661         case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
662                 map->sid_name_use = SID_NAME_ALIAS;
663                 break;
664         case GTYPE_SECURITY_GLOBAL_GROUP:
665                 map->sid_name_use = SID_NAME_DOM_GRP;
666                 break;
667         default:
668                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
669         }
670
671         str = tldap_talloc_single_attribute(group[0], "samAccountName",
672                                             talloc_tos());
673         if (str == NULL) {
674                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
675         }
676         fstrcpy(map->nt_name, str);
677         TALLOC_FREE(str);
678
679         str = tldap_talloc_single_attribute(group[0], "description",
680                                             talloc_tos());
681         if (str != NULL) {
682                 fstrcpy(map->comment, str);
683                 TALLOC_FREE(str);
684         } else {
685                 map->comment[0] = '\0';
686         }
687
688         TALLOC_FREE(group);
689         return NT_STATUS_OK;
690 }
691
692 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
693                                  struct dom_sid sid)
694 {
695         char *filter;
696         NTSTATUS status;
697
698         filter = talloc_asprintf(talloc_tos(),
699                                  "(&(objectsid=%s)(objectclass=group))",
700                                  sid_string_talloc(talloc_tos(), &sid));
701         if (filter == NULL) {
702                 return NT_STATUS_NO_MEMORY;
703         }
704
705         status = pdb_ads_getgrfilter(m, map, filter);
706         TALLOC_FREE(filter);
707         return status;
708 }
709
710 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
711                                  gid_t gid)
712 {
713         struct dom_sid sid;
714         pdb_ads_gid_to_sid(m, gid, &sid);
715         return pdb_ads_getgrsid(m, map, sid);
716 }
717
718 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
719                                  const char *name)
720 {
721         char *filter;
722         NTSTATUS status;
723
724         filter = talloc_asprintf(talloc_tos(),
725                                  "(&(samaccountname=%s)(objectclass=group))",
726                                  name);
727         if (filter == NULL) {
728                 return NT_STATUS_NO_MEMORY;
729         }
730
731         status = pdb_ads_getgrfilter(m, map, filter);
732         TALLOC_FREE(filter);
733         return status;
734 }
735
736 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
737                                          TALLOC_CTX *mem_ctx, const char *name,
738                                          uint32 *rid)
739 {
740         TALLOC_CTX *frame = talloc_stackframe();
741         struct pdb_ads_state *state = talloc_get_type_abort(
742                 m->private_data, struct pdb_ads_state);
743         struct tldap_context *ld;
744         const char *attrs[1] = { "objectSid" };
745         int num_mods = 0;
746         struct tldap_mod *mods = NULL;
747         struct tldap_message **alias;
748         struct dom_sid sid;
749         char *dn;
750         int rc;
751         bool ok = true;
752
753         ld = pdb_ads_ld(state);
754         if (ld == NULL) {
755                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
756         }
757
758         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
759                              state->domaindn);
760         if (dn == NULL) {
761                 TALLOC_FREE(frame);
762                 return NT_STATUS_NO_MEMORY;
763         }
764
765         ok &= tldap_make_mod_fmt(
766                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
767                 name);
768         ok &= tldap_make_mod_fmt(
769                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
770         ok &= tldap_make_mod_fmt(
771                 NULL, talloc_tos(), &num_mods, &mods, "groupType",
772                 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
773
774         if (!ok) {
775                 TALLOC_FREE(frame);
776                 return NT_STATUS_NO_MEMORY;
777         }
778
779         rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
780         if (rc != TLDAP_SUCCESS) {
781                 DEBUG(10, ("ldap_add failed %s\n",
782                            tldap_errstr(talloc_tos(), state->ld, rc)));
783                 TALLOC_FREE(frame);
784                 return NT_STATUS_LDAP(rc);
785         }
786
787         rc = pdb_ads_search_fmt(
788                 state, state->domaindn, TLDAP_SCOPE_SUB,
789                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
790                 "(&(objectclass=group)(samaccountname=%s))", name);
791         if (rc != TLDAP_SUCCESS) {
792                 DEBUG(10, ("Could not find just created alias %s: %s\n",
793                            name, tldap_errstr(talloc_tos(), state->ld, rc)));
794                 TALLOC_FREE(frame);
795                 return NT_STATUS_LDAP(rc);
796         }
797
798         if (talloc_array_length(alias) != 1) {
799                 DEBUG(10, ("Got %d alias, expected one\n",
800                            (int)talloc_array_length(alias)));
801                 TALLOC_FREE(frame);
802                 return NT_STATUS_LDAP(rc);
803         }
804
805         if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
806                 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
807                            name));
808                 TALLOC_FREE(frame);
809                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
810         }
811
812         sid_peek_rid(&sid, rid);
813         TALLOC_FREE(frame);
814         return NT_STATUS_OK;
815 }
816
817 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
818                                          TALLOC_CTX *mem_ctx, uint32 rid)
819 {
820         struct pdb_ads_state *state = talloc_get_type_abort(
821                 m->private_data, struct pdb_ads_state);
822         struct tldap_context *ld;
823         struct dom_sid sid;
824         char *sidstr;
825         struct tldap_message **msg;
826         char *dn;
827         int rc;
828
829         sid_compose(&sid, &state->domainsid, rid);
830
831         sidstr = sid_binstring(talloc_tos(), &sid);
832         NT_STATUS_HAVE_NO_MEMORY(sidstr);
833
834         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
835                                 NULL, 0, 0, talloc_tos(), &msg,
836                                 ("(&(objectSid=%s)(objectClass=group))"),
837                                 sidstr);
838         TALLOC_FREE(sidstr);
839         if (rc != TLDAP_SUCCESS) {
840                 DEBUG(10, ("ldap_search failed %s\n",
841                            tldap_errstr(talloc_tos(), state->ld, rc)));
842                 return NT_STATUS_LDAP(rc);
843         }
844
845         switch talloc_array_length(msg) {
846         case 0:
847                 return NT_STATUS_NO_SUCH_GROUP;
848         case 1:
849                 break;
850         default:
851                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
852         }
853
854         if (!tldap_entry_dn(msg[0], &dn)) {
855                 TALLOC_FREE(msg);
856                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
857         }
858
859         ld = pdb_ads_ld(state);
860         if (ld == NULL) {
861                 TALLOC_FREE(msg);
862                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
863         }
864
865         rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
866         TALLOC_FREE(msg);
867         if (rc != TLDAP_SUCCESS) {
868                 DEBUG(10, ("ldap_delete failed: %s\n",
869                            tldap_errstr(talloc_tos(), state->ld, rc)));
870                 return NT_STATUS_LDAP(rc);
871         }
872
873         return NT_STATUS_OK;
874 }
875
876 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
877                                                 GROUP_MAP *map)
878 {
879         return NT_STATUS_NOT_IMPLEMENTED;
880 }
881
882 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
883                                                    GROUP_MAP *map)
884 {
885         return NT_STATUS_NOT_IMPLEMENTED;
886 }
887
888 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
889                                                    struct dom_sid sid)
890 {
891         return NT_STATUS_NOT_IMPLEMENTED;
892 }
893
894 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
895                                            const struct dom_sid *sid,
896                                            enum lsa_SidType sid_name_use,
897                                            GROUP_MAP **pp_rmap,
898                                            size_t *p_num_entries,
899                                            bool unix_only)
900 {
901         return NT_STATUS_NOT_IMPLEMENTED;
902 }
903
904 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
905                                            TALLOC_CTX *mem_ctx,
906                                            const struct dom_sid *group,
907                                            uint32 **pmembers,
908                                            size_t *pnum_members)
909 {
910         struct pdb_ads_state *state = talloc_get_type_abort(
911                 m->private_data, struct pdb_ads_state);
912         const char *attrs[1] = { "member" };
913         char *sidstr;
914         struct tldap_message **msg;
915         int i, rc, num_members;
916         DATA_BLOB *blobs;
917         uint32_t *members;
918
919         sidstr = sid_binstring(talloc_tos(), group);
920         NT_STATUS_HAVE_NO_MEMORY(sidstr);
921
922         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
923                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
924                                 &msg, "(objectsid=%s)", sidstr);
925         TALLOC_FREE(sidstr);
926         if (rc != TLDAP_SUCCESS) {
927                 DEBUG(10, ("ldap_search failed %s\n",
928                            tldap_errstr(talloc_tos(), state->ld, rc)));
929                 return NT_STATUS_LDAP(rc);
930         }
931         switch talloc_array_length(msg) {
932         case 0:
933                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
934                 break;
935         case 1:
936                 break;
937         default:
938                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
939                 break;
940         }
941
942         if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
943                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
944         }
945
946         members = talloc_array(mem_ctx, uint32_t, num_members);
947         if (members == NULL) {
948                 return NT_STATUS_NO_MEMORY;
949         }
950
951         for (i=0; i<num_members; i++) {
952                 struct dom_sid sid;
953                 if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
954                     || !sid_peek_rid(&sid, &members[i])) {
955                         TALLOC_FREE(members);
956                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
957                 }
958         }
959
960         *pmembers = members;
961         *pnum_members = num_members;
962         return NT_STATUS_OK;
963 }
964
965 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
966                                                TALLOC_CTX *mem_ctx,
967                                                struct samu *user,
968                                                struct dom_sid **pp_sids,
969                                                gid_t **pp_gids,
970                                                size_t *p_num_groups)
971 {
972         struct pdb_ads_state *state = talloc_get_type_abort(
973                 m->private_data, struct pdb_ads_state);
974         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
975                 m, user);
976         const char *attrs[1] = { "objectSid" };
977         struct tldap_message **groups;
978         int i, rc, count;
979         size_t num_groups;
980         struct dom_sid *group_sids;
981         gid_t *gids;
982
983         rc = pdb_ads_search_fmt(
984                 state, state->domaindn, TLDAP_SCOPE_SUB,
985                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
986                 "(&(member=%s)(grouptype=%d)(objectclass=group))",
987                 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
988         if (rc != TLDAP_SUCCESS) {
989                 DEBUG(10, ("ldap_search failed %s\n",
990                            tldap_errstr(talloc_tos(), state->ld, rc)));
991                 return NT_STATUS_LDAP(rc);
992         }
993
994         count = talloc_array_length(groups);
995
996         group_sids = talloc_array(mem_ctx, struct dom_sid, count);
997         if (group_sids == NULL) {
998                 return NT_STATUS_NO_MEMORY;
999         }
1000         gids = talloc_array(mem_ctx, gid_t, count);
1001         if (gids == NULL) {
1002                 TALLOC_FREE(group_sids);
1003                 return NT_STATUS_NO_MEMORY;
1004         }
1005         num_groups = 0;
1006
1007         for (i=0; i<count; i++) {
1008                 if (!tldap_pull_binsid(groups[i], "objectSid",
1009                                        &group_sids[num_groups])) {
1010                         continue;
1011                 }
1012                 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
1013
1014                 num_groups += 1;
1015                 if (num_groups == count) {
1016                         break;
1017                 }
1018         }
1019
1020         *pp_sids = group_sids;
1021         *pp_gids = gids;
1022         *p_num_groups = num_groups;
1023         return NT_STATUS_OK;
1024 }
1025
1026 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
1027                                                TALLOC_CTX *mem_ctx,
1028                                                struct samu *user)
1029 {
1030         return NT_STATUS_NOT_IMPLEMENTED;
1031 }
1032
1033 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
1034                                      TALLOC_CTX *mem_ctx,
1035                                      uint32 grouprid, uint32 memberrid,
1036                                      int mod_op)
1037 {
1038         struct pdb_ads_state *state = talloc_get_type_abort(
1039                 m->private_data, struct pdb_ads_state);
1040         TALLOC_CTX *frame = talloc_stackframe();
1041         struct tldap_context *ld;
1042         struct dom_sid groupsid, membersid;
1043         char *groupdn, *memberdn;
1044         struct tldap_mod *mods;
1045         int rc;
1046         NTSTATUS status;
1047
1048         ld = pdb_ads_ld(state);
1049         if (ld == NULL) {
1050                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1051         }
1052
1053         sid_compose(&groupsid, &state->domainsid, grouprid);
1054         sid_compose(&membersid, &state->domainsid, memberrid);
1055
1056         status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
1057         if (!NT_STATUS_IS_OK(status)) {
1058                 TALLOC_FREE(frame);
1059                 return NT_STATUS_NO_SUCH_GROUP;
1060         }
1061         status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
1062         if (!NT_STATUS_IS_OK(status)) {
1063                 TALLOC_FREE(frame);
1064                 return NT_STATUS_NO_SUCH_USER;
1065         }
1066
1067         mods = NULL;
1068
1069         if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1070                                "member", memberdn)) {
1071                 TALLOC_FREE(frame);
1072                 return NT_STATUS_NO_MEMORY;
1073         }
1074
1075         rc = tldap_modify(ld, groupdn, 1, mods, NULL, 0, NULL, 0);
1076         TALLOC_FREE(frame);
1077         if (rc != TLDAP_SUCCESS) {
1078                 DEBUG(10, ("ldap_modify failed: %s\n",
1079                            tldap_errstr(talloc_tos(), state->ld, rc)));
1080                 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1081                         return NT_STATUS_MEMBER_IN_GROUP;
1082                 }
1083                 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1084                         return NT_STATUS_MEMBER_NOT_IN_GROUP;
1085                 }
1086                 return NT_STATUS_LDAP(rc);
1087         }
1088
1089         return NT_STATUS_OK;
1090 }
1091
1092 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
1093                                      TALLOC_CTX *mem_ctx,
1094                                      uint32 group_rid, uint32 member_rid)
1095 {
1096         return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1097                                     TLDAP_MOD_ADD);
1098 }
1099
1100 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
1101                                      TALLOC_CTX *mem_ctx,
1102                                      uint32 group_rid, uint32 member_rid)
1103 {
1104         return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1105                                     TLDAP_MOD_DELETE);
1106 }
1107
1108 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
1109                                      const char *name, uint32 *rid)
1110 {
1111         TALLOC_CTX *frame = talloc_stackframe();
1112         struct pdb_ads_state *state = talloc_get_type_abort(
1113                 m->private_data, struct pdb_ads_state);
1114         struct tldap_context *ld;
1115         const char *attrs[1] = { "objectSid" };
1116         int num_mods = 0;
1117         struct tldap_mod *mods = NULL;
1118         struct tldap_message **alias;
1119         struct dom_sid sid;
1120         char *dn;
1121         int rc;
1122         bool ok = true;
1123
1124         ld = pdb_ads_ld(state);
1125         if (ld == NULL) {
1126                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1127         }
1128
1129         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1130                              state->domaindn);
1131         if (dn == NULL) {
1132                 TALLOC_FREE(frame);
1133                 return NT_STATUS_NO_MEMORY;
1134         }
1135
1136         ok &= tldap_make_mod_fmt(
1137                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
1138                 name);
1139         ok &= tldap_make_mod_fmt(
1140                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
1141         ok &= tldap_make_mod_fmt(
1142                 NULL, talloc_tos(), &num_mods, &mods, "groupType",
1143                 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1144
1145         if (!ok) {
1146                 TALLOC_FREE(frame);
1147                 return NT_STATUS_NO_MEMORY;
1148         }
1149
1150         rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1151         if (rc != TLDAP_SUCCESS) {
1152                 DEBUG(10, ("ldap_add failed %s\n",
1153                            tldap_errstr(talloc_tos(), state->ld, rc)));
1154                 TALLOC_FREE(frame);
1155                 return NT_STATUS_LDAP(rc);
1156         }
1157
1158         rc = pdb_ads_search_fmt(
1159                 state, state->domaindn, TLDAP_SCOPE_SUB,
1160                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1161                 "(&(objectclass=group)(samaccountname=%s))", name);
1162         if (rc != TLDAP_SUCCESS) {
1163                 DEBUG(10, ("Could not find just created alias %s: %s\n",
1164                            name, tldap_errstr(talloc_tos(), state->ld, rc)));
1165                 TALLOC_FREE(frame);
1166                 return NT_STATUS_LDAP(rc);
1167         }
1168
1169         if (talloc_array_length(alias) != 1) {
1170                 DEBUG(10, ("Got %d alias, expected one\n",
1171                            (int)talloc_array_length(alias)));
1172                 TALLOC_FREE(frame);
1173                 return NT_STATUS_LDAP(rc);
1174         }
1175
1176         if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1177                 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1178                            name));
1179                 TALLOC_FREE(frame);
1180                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1181         }
1182
1183         sid_peek_rid(&sid, rid);
1184         TALLOC_FREE(frame);
1185         return NT_STATUS_OK;
1186 }
1187
1188 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1189                                      const struct dom_sid *sid)
1190 {
1191         struct pdb_ads_state *state = talloc_get_type_abort(
1192                 m->private_data, struct pdb_ads_state);
1193         struct tldap_context *ld;
1194         struct tldap_message **alias;
1195         char *sidstr, *dn = NULL;
1196         int rc;
1197
1198         ld = pdb_ads_ld(state);
1199         if (ld == NULL) {
1200                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1201         }
1202
1203         sidstr = sid_binstring(talloc_tos(), sid);
1204         if (sidstr == NULL) {
1205                 return NT_STATUS_NO_MEMORY;
1206         }
1207
1208         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1209                                 NULL, 0, 0, talloc_tos(), &alias,
1210                                 "(&(objectSid=%s)(objectclass=group)"
1211                                 "(|(grouptype=%d)(grouptype=%d)))",
1212                                 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1213                                 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1214         TALLOC_FREE(sidstr);
1215         if (rc != TLDAP_SUCCESS) {
1216                 DEBUG(10, ("ldap_search failed: %s\n",
1217                            tldap_errstr(talloc_tos(), state->ld, rc)));
1218                 return NT_STATUS_LDAP(rc);
1219         }
1220         if (talloc_array_length(alias) != 1) {
1221                 DEBUG(10, ("Expected 1 alias, got %d\n",
1222                            (int)talloc_array_length(alias)));
1223                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1224         }
1225         if (!tldap_entry_dn(alias[0], &dn)) {
1226                 DEBUG(10, ("Could not get DN for alias %s\n",
1227                            sid_string_dbg(sid)));
1228                 return NT_STATUS_INTERNAL_ERROR;
1229         }
1230
1231         rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
1232         if (rc != TLDAP_SUCCESS) {
1233                 DEBUG(10, ("ldap_delete failed: %s\n",
1234                            tldap_errstr(talloc_tos(), state->ld, rc)));
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 struct 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 struct dom_sid *alias,
1367                                      const struct 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 struct dom_sid *alias,
1426                                      const struct 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 struct dom_sid *alias,
1433                                      const struct 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 struct dom_sid *alias,
1471                                       TALLOC_CTX *mem_ctx,
1472                                       struct 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 struct dom_sid *domain_sid,
1531                                                const struct 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 = NULL;
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 struct 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 struct 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 struct 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                                struct 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                                struct 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 struct 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                                       struct 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 struct 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 }