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