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