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