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