s3: Fix pdb_ads_enum_group_members for empty groups
[kai/samba.git] / source3 / passdb / pdb_ads.c
1 /*
2    Unix SMB/CIFS implementation.
3    pdb_ldap with ads schema
4    Copyright (C) Volker Lendecke 2009
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #include "tldap.h"
22 #include "tldap_util.h"
23 #include "../libds/common/flags.h"
24 #include "secrets.h"
25 #include "../librpc/gen_ndr/samr.h"
26 #include "../libcli/ldap/ldap_ndr.h"
27 #include "../libcli/security/security.h"
28
29 struct pdb_ads_state {
30         struct sockaddr_un socket_address;
31         struct tldap_context *ld;
32         struct dom_sid domainsid;
33         struct GUID domainguid;
34         char *domaindn;
35         char *configdn;
36         char *netbiosname;
37 };
38
39 struct pdb_ads_samu_private {
40         char *dn;
41         struct tldap_message *ldapmsg;
42 };
43
44 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
45                                struct dom_sid *sid);
46 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
47                                struct dom_sid *psid);
48 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
49                                const struct dom_sid *sid,
50                                TALLOC_CTX *mem_ctx, char **pdn);
51 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state);
52 static int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
53                               int scope, const char *attrs[], int num_attrs,
54                               int attrsonly,
55                               TALLOC_CTX *mem_ctx, struct tldap_message ***res,
56                               const char *fmt, ...);
57 static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
58                                     const char *filter,
59                                     TALLOC_CTX *mem_ctx,
60                                     struct pdb_ads_samu_private **presult);
61
62 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
63                               time_t *ptime)
64 {
65         uint64_t tmp;
66
67         if (!tldap_pull_uint64(msg, attr, &tmp)) {
68                 return false;
69         }
70         *ptime = 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 {
749         struct pdb_ads_state *state = talloc_get_type_abort(
750                 m->private_data, struct pdb_ads_state);
751         const char *attrs[4] = { "objectSid", "description", "samAccountName",
752                                  "groupType" };
753         char *str;
754         struct tldap_message **group;
755         uint32_t grouptype;
756         int rc;
757
758         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
759                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
760                                 &group, "%s", filter);
761         if (rc != TLDAP_SUCCESS) {
762                 DEBUG(10, ("ldap_search failed %s\n",
763                            tldap_errstr(talloc_tos(), state->ld, rc)));
764                 return NT_STATUS_LDAP(rc);
765         }
766         if (talloc_array_length(group) != 1) {
767                 DEBUG(10, ("Expected 1 user, got %d\n",
768                            (int)talloc_array_length(group)));
769                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
770         }
771
772         if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
773                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
774         }
775         map->gid = pdb_ads_sid2gid(&map->sid);
776
777         if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
778                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
779         }
780         switch (grouptype) {
781         case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
782         case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
783                 map->sid_name_use = SID_NAME_ALIAS;
784                 break;
785         case GTYPE_SECURITY_GLOBAL_GROUP:
786                 map->sid_name_use = SID_NAME_DOM_GRP;
787                 break;
788         default:
789                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
790         }
791
792         str = tldap_talloc_single_attribute(group[0], "samAccountName",
793                                             talloc_tos());
794         if (str == NULL) {
795                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
796         }
797         fstrcpy(map->nt_name, str);
798         TALLOC_FREE(str);
799
800         str = tldap_talloc_single_attribute(group[0], "description",
801                                             talloc_tos());
802         if (str != NULL) {
803                 fstrcpy(map->comment, str);
804                 TALLOC_FREE(str);
805         } else {
806                 map->comment[0] = '\0';
807         }
808
809         TALLOC_FREE(group);
810         return NT_STATUS_OK;
811 }
812
813 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
814                                  struct dom_sid sid)
815 {
816         char *filter;
817         NTSTATUS status;
818
819         filter = talloc_asprintf(talloc_tos(),
820                                  "(&(objectsid=%s)(objectclass=group))",
821                                  sid_string_talloc(talloc_tos(), &sid));
822         if (filter == NULL) {
823                 return NT_STATUS_NO_MEMORY;
824         }
825
826         status = pdb_ads_getgrfilter(m, map, filter);
827         TALLOC_FREE(filter);
828         return status;
829 }
830
831 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
832                                  gid_t gid)
833 {
834         struct dom_sid sid;
835         pdb_ads_gid_to_sid(m, gid, &sid);
836         return pdb_ads_getgrsid(m, map, sid);
837 }
838
839 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
840                                  const char *name)
841 {
842         char *filter;
843         NTSTATUS status;
844
845         filter = talloc_asprintf(talloc_tos(),
846                                  "(&(samaccountname=%s)(objectclass=group))",
847                                  name);
848         if (filter == NULL) {
849                 return NT_STATUS_NO_MEMORY;
850         }
851
852         status = pdb_ads_getgrfilter(m, map, filter);
853         TALLOC_FREE(filter);
854         return status;
855 }
856
857 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
858                                          TALLOC_CTX *mem_ctx, const char *name,
859                                          uint32 *rid)
860 {
861         TALLOC_CTX *frame = talloc_stackframe();
862         struct pdb_ads_state *state = talloc_get_type_abort(
863                 m->private_data, struct pdb_ads_state);
864         struct tldap_context *ld;
865         const char *attrs[1] = { "objectSid" };
866         int num_mods = 0;
867         struct tldap_mod *mods = NULL;
868         struct tldap_message **alias;
869         struct dom_sid sid;
870         char *dn;
871         int rc;
872         bool ok = true;
873
874         ld = pdb_ads_ld(state);
875         if (ld == NULL) {
876                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
877         }
878
879         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
880                              state->domaindn);
881         if (dn == NULL) {
882                 TALLOC_FREE(frame);
883                 return NT_STATUS_NO_MEMORY;
884         }
885
886         ok &= tldap_make_mod_fmt(
887                 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
888                 name);
889         ok &= tldap_make_mod_fmt(
890                 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group");
891         ok &= tldap_make_mod_fmt(
892                 NULL, talloc_tos(), &mods, &num_mods, "groupType",
893                 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
894
895         if (!ok) {
896                 TALLOC_FREE(frame);
897                 return NT_STATUS_NO_MEMORY;
898         }
899
900         rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
901         if (rc != TLDAP_SUCCESS) {
902                 DEBUG(10, ("ldap_add failed %s\n",
903                            tldap_errstr(talloc_tos(), state->ld, rc)));
904                 TALLOC_FREE(frame);
905                 return NT_STATUS_LDAP(rc);
906         }
907
908         rc = pdb_ads_search_fmt(
909                 state, state->domaindn, TLDAP_SCOPE_SUB,
910                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
911                 "(&(objectclass=group)(samaccountname=%s))", name);
912         if (rc != TLDAP_SUCCESS) {
913                 DEBUG(10, ("Could not find just created alias %s: %s\n",
914                            name, tldap_errstr(talloc_tos(), state->ld, rc)));
915                 TALLOC_FREE(frame);
916                 return NT_STATUS_LDAP(rc);
917         }
918
919         if (talloc_array_length(alias) != 1) {
920                 DEBUG(10, ("Got %d alias, expected one\n",
921                            (int)talloc_array_length(alias)));
922                 TALLOC_FREE(frame);
923                 return NT_STATUS_LDAP(rc);
924         }
925
926         if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
927                 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
928                            name));
929                 TALLOC_FREE(frame);
930                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
931         }
932
933         sid_peek_rid(&sid, rid);
934         TALLOC_FREE(frame);
935         return NT_STATUS_OK;
936 }
937
938 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
939                                          TALLOC_CTX *mem_ctx, uint32 rid)
940 {
941         struct pdb_ads_state *state = talloc_get_type_abort(
942                 m->private_data, struct pdb_ads_state);
943         struct tldap_context *ld;
944         struct dom_sid sid;
945         char *sidstr;
946         struct tldap_message **msg;
947         char *dn;
948         int rc;
949
950         sid_compose(&sid, &state->domainsid, rid);
951
952         sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
953         NT_STATUS_HAVE_NO_MEMORY(sidstr);
954
955         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
956                                 NULL, 0, 0, talloc_tos(), &msg,
957                                 ("(&(objectSid=%s)(objectClass=group))"),
958                                 sidstr);
959         TALLOC_FREE(sidstr);
960         if (rc != TLDAP_SUCCESS) {
961                 DEBUG(10, ("ldap_search failed %s\n",
962                            tldap_errstr(talloc_tos(), state->ld, rc)));
963                 return NT_STATUS_LDAP(rc);
964         }
965
966         switch talloc_array_length(msg) {
967         case 0:
968                 return NT_STATUS_NO_SUCH_GROUP;
969         case 1:
970                 break;
971         default:
972                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
973         }
974
975         if (!tldap_entry_dn(msg[0], &dn)) {
976                 TALLOC_FREE(msg);
977                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
978         }
979
980         ld = pdb_ads_ld(state);
981         if (ld == NULL) {
982                 TALLOC_FREE(msg);
983                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
984         }
985
986         rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
987         TALLOC_FREE(msg);
988         if (rc != TLDAP_SUCCESS) {
989                 DEBUG(10, ("ldap_delete failed: %s\n",
990                            tldap_errstr(talloc_tos(), state->ld, rc)));
991                 return NT_STATUS_LDAP(rc);
992         }
993
994         return NT_STATUS_OK;
995 }
996
997 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
998                                                 GROUP_MAP *map)
999 {
1000         return NT_STATUS_NOT_IMPLEMENTED;
1001 }
1002
1003 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
1004                                                    GROUP_MAP *map)
1005 {
1006         return NT_STATUS_NOT_IMPLEMENTED;
1007 }
1008
1009 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
1010                                                    struct dom_sid sid)
1011 {
1012         return NT_STATUS_NOT_IMPLEMENTED;
1013 }
1014
1015 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
1016                                            const struct dom_sid *sid,
1017                                            enum lsa_SidType sid_name_use,
1018                                            GROUP_MAP **pp_rmap,
1019                                            size_t *p_num_entries,
1020                                            bool unix_only)
1021 {
1022         return NT_STATUS_NOT_IMPLEMENTED;
1023 }
1024
1025 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
1026                                            TALLOC_CTX *mem_ctx,
1027                                            const struct dom_sid *group,
1028                                            uint32 **pmembers,
1029                                            size_t *pnum_members)
1030 {
1031         struct pdb_ads_state *state = talloc_get_type_abort(
1032                 m->private_data, struct pdb_ads_state);
1033         const char *attrs[1] = { "member" };
1034         char *sidstr;
1035         struct tldap_message **msg;
1036         int i, rc, num_members;
1037         DATA_BLOB *blobs;
1038         uint32_t *members;
1039
1040         sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), group);
1041         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1042
1043         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1044                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1045                                 &msg, "(objectsid=%s)", sidstr);
1046         TALLOC_FREE(sidstr);
1047         if (rc != TLDAP_SUCCESS) {
1048                 DEBUG(10, ("ldap_search failed %s\n",
1049                            tldap_errstr(talloc_tos(), state->ld, rc)));
1050                 return NT_STATUS_LDAP(rc);
1051         }
1052         switch talloc_array_length(msg) {
1053         case 0:
1054                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1055                 break;
1056         case 1:
1057                 break;
1058         default:
1059                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1060                 break;
1061         }
1062
1063         if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
1064                 *pmembers = NULL;
1065                 *pnum_members = 0;
1066                 return NT_STATUS_OK;
1067         }
1068
1069         members = talloc_array(mem_ctx, uint32_t, num_members);
1070         if (members == NULL) {
1071                 return NT_STATUS_NO_MEMORY;
1072         }
1073
1074         for (i=0; i<num_members; i++) {
1075                 struct dom_sid sid;
1076                 if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
1077                     || !sid_peek_rid(&sid, &members[i])) {
1078                         TALLOC_FREE(members);
1079                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1080                 }
1081         }
1082
1083         *pmembers = members;
1084         *pnum_members = num_members;
1085         return NT_STATUS_OK;
1086 }
1087
1088 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
1089                                                TALLOC_CTX *mem_ctx,
1090                                                struct samu *user,
1091                                                struct dom_sid **pp_sids,
1092                                                gid_t **pp_gids,
1093                                                size_t *p_num_groups)
1094 {
1095         struct pdb_ads_state *state = talloc_get_type_abort(
1096                 m->private_data, struct pdb_ads_state);
1097         struct pdb_ads_samu_private *priv;
1098         const char *attrs[1] = { "objectSid" };
1099         struct tldap_message **groups;
1100         int i, rc, count;
1101         size_t num_groups;
1102         struct dom_sid *group_sids;
1103         gid_t *gids;
1104
1105         priv = pdb_ads_get_samu_private(m, user);
1106         if (priv != NULL) {
1107                 rc = pdb_ads_search_fmt(
1108                         state, state->domaindn, TLDAP_SCOPE_SUB,
1109                         attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
1110                         "(&(member=%s)(grouptype=%d)(objectclass=group))",
1111                         priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
1112                 if (rc != TLDAP_SUCCESS) {
1113                         DEBUG(10, ("ldap_search failed %s\n",
1114                                    tldap_errstr(talloc_tos(), state->ld, rc)));
1115                         return NT_STATUS_LDAP(rc);
1116                 }
1117                 count = talloc_array_length(groups);
1118         } else {
1119                 /*
1120                  * This happens for artificial samu users
1121                  */
1122                 DEBUG(10, ("Could not get pdb_ads_samu_private\n"));
1123                 count = 0;
1124         }
1125
1126         group_sids = talloc_array(mem_ctx, struct dom_sid, count+1);
1127         if (group_sids == NULL) {
1128                 return NT_STATUS_NO_MEMORY;
1129         }
1130         gids = talloc_array(mem_ctx, gid_t, count+1);
1131         if (gids == NULL) {
1132                 TALLOC_FREE(group_sids);
1133                 return NT_STATUS_NO_MEMORY;
1134         }
1135
1136         sid_copy(&group_sids[0], pdb_get_group_sid(user));
1137         if (!sid_to_gid(&group_sids[0], &gids[0])) {
1138                 TALLOC_FREE(gids);
1139                 TALLOC_FREE(group_sids);
1140                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1141         }
1142         num_groups = 1;
1143
1144         for (i=0; i<count; i++) {
1145                 if (!tldap_pull_binsid(groups[i], "objectSid",
1146                                        &group_sids[num_groups])) {
1147                         continue;
1148                 }
1149                 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
1150
1151                 num_groups += 1;
1152                 if (num_groups == count) {
1153                         break;
1154                 }
1155         }
1156
1157         *pp_sids = group_sids;
1158         *pp_gids = gids;
1159         *p_num_groups = num_groups;
1160         return NT_STATUS_OK;
1161 }
1162
1163 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
1164                                                TALLOC_CTX *mem_ctx,
1165                                                struct samu *user)
1166 {
1167         return NT_STATUS_NOT_IMPLEMENTED;
1168 }
1169
1170 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
1171                                      TALLOC_CTX *mem_ctx,
1172                                      uint32 grouprid, uint32 memberrid,
1173                                      int mod_op)
1174 {
1175         struct pdb_ads_state *state = talloc_get_type_abort(
1176                 m->private_data, struct pdb_ads_state);
1177         TALLOC_CTX *frame = talloc_stackframe();
1178         struct tldap_context *ld;
1179         struct dom_sid groupsid, membersid;
1180         char *groupdn, *memberdn;
1181         struct tldap_mod *mods;
1182         int num_mods;
1183         int rc;
1184         NTSTATUS status;
1185
1186         ld = pdb_ads_ld(state);
1187         if (ld == NULL) {
1188                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1189         }
1190
1191         sid_compose(&groupsid, &state->domainsid, grouprid);
1192         sid_compose(&membersid, &state->domainsid, memberrid);
1193
1194         status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
1195         if (!NT_STATUS_IS_OK(status)) {
1196                 TALLOC_FREE(frame);
1197                 return NT_STATUS_NO_SUCH_GROUP;
1198         }
1199         status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
1200         if (!NT_STATUS_IS_OK(status)) {
1201                 TALLOC_FREE(frame);
1202                 return NT_STATUS_NO_SUCH_USER;
1203         }
1204
1205         mods = NULL;
1206         num_mods = 0;
1207
1208         if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op,
1209                                "member", memberdn)) {
1210                 TALLOC_FREE(frame);
1211                 return NT_STATUS_NO_MEMORY;
1212         }
1213
1214         rc = tldap_modify(ld, groupdn, mods, num_mods, NULL, 0, NULL, 0);
1215         TALLOC_FREE(frame);
1216         if (rc != TLDAP_SUCCESS) {
1217                 DEBUG(10, ("ldap_modify failed: %s\n",
1218                            tldap_errstr(talloc_tos(), state->ld, rc)));
1219                 if ((mod_op == TLDAP_MOD_ADD) &&
1220                     (rc == TLDAP_ALREADY_EXISTS)) {
1221                         return NT_STATUS_MEMBER_IN_GROUP;
1222                 }
1223                 if ((mod_op == TLDAP_MOD_DELETE) &&
1224                     (rc == TLDAP_UNWILLING_TO_PERFORM)) {
1225                         return NT_STATUS_MEMBER_NOT_IN_GROUP;
1226                 }
1227                 return NT_STATUS_LDAP(rc);
1228         }
1229
1230         return NT_STATUS_OK;
1231 }
1232
1233 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
1234                                      TALLOC_CTX *mem_ctx,
1235                                      uint32 group_rid, uint32 member_rid)
1236 {
1237         return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1238                                     TLDAP_MOD_ADD);
1239 }
1240
1241 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
1242                                      TALLOC_CTX *mem_ctx,
1243                                      uint32 group_rid, uint32 member_rid)
1244 {
1245         return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1246                                     TLDAP_MOD_DELETE);
1247 }
1248
1249 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
1250                                      const char *name, uint32 *rid)
1251 {
1252         TALLOC_CTX *frame = talloc_stackframe();
1253         struct pdb_ads_state *state = talloc_get_type_abort(
1254                 m->private_data, struct pdb_ads_state);
1255         struct tldap_context *ld;
1256         const char *attrs[1] = { "objectSid" };
1257         int num_mods = 0;
1258         struct tldap_mod *mods = NULL;
1259         struct tldap_message **alias;
1260         struct dom_sid sid;
1261         char *dn;
1262         int rc;
1263         bool ok = true;
1264
1265         ld = pdb_ads_ld(state);
1266         if (ld == NULL) {
1267                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1268         }
1269
1270         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
1271                              state->domaindn);
1272         if (dn == NULL) {
1273                 TALLOC_FREE(frame);
1274                 return NT_STATUS_NO_MEMORY;
1275         }
1276
1277         ok &= tldap_make_mod_fmt(
1278                 NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
1279                 name);
1280         ok &= tldap_make_mod_fmt(
1281                 NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group");
1282         ok &= tldap_make_mod_fmt(
1283                 NULL, talloc_tos(), &mods, &num_mods, "groupType",
1284                 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1285
1286         if (!ok) {
1287                 TALLOC_FREE(frame);
1288                 return NT_STATUS_NO_MEMORY;
1289         }
1290
1291         rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1292         if (rc != TLDAP_SUCCESS) {
1293                 DEBUG(10, ("ldap_add failed %s\n",
1294                            tldap_errstr(talloc_tos(), state->ld, rc)));
1295                 TALLOC_FREE(frame);
1296                 return NT_STATUS_LDAP(rc);
1297         }
1298
1299         rc = pdb_ads_search_fmt(
1300                 state, state->domaindn, TLDAP_SCOPE_SUB,
1301                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1302                 "(&(objectclass=group)(samaccountname=%s))", name);
1303         if (rc != TLDAP_SUCCESS) {
1304                 DEBUG(10, ("Could not find just created alias %s: %s\n",
1305                            name, tldap_errstr(talloc_tos(), state->ld, rc)));
1306                 TALLOC_FREE(frame);
1307                 return NT_STATUS_LDAP(rc);
1308         }
1309
1310         if (talloc_array_length(alias) != 1) {
1311                 DEBUG(10, ("Got %d alias, expected one\n",
1312                            (int)talloc_array_length(alias)));
1313                 TALLOC_FREE(frame);
1314                 return NT_STATUS_LDAP(rc);
1315         }
1316
1317         if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1318                 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1319                            name));
1320                 TALLOC_FREE(frame);
1321                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1322         }
1323
1324         sid_peek_rid(&sid, rid);
1325         TALLOC_FREE(frame);
1326         return NT_STATUS_OK;
1327 }
1328
1329 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1330                                      const struct dom_sid *sid)
1331 {
1332         struct pdb_ads_state *state = talloc_get_type_abort(
1333                 m->private_data, struct pdb_ads_state);
1334         struct tldap_context *ld;
1335         struct tldap_message **alias;
1336         char *sidstr, *dn = NULL;
1337         int rc;
1338
1339         ld = pdb_ads_ld(state);
1340         if (ld == NULL) {
1341                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1342         }
1343
1344         sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1345         if (sidstr == NULL) {
1346                 return NT_STATUS_NO_MEMORY;
1347         }
1348
1349         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1350                                 NULL, 0, 0, talloc_tos(), &alias,
1351                                 "(&(objectSid=%s)(objectclass=group)"
1352                                 "(|(grouptype=%d)(grouptype=%d)))",
1353                                 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1354                                 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1355         TALLOC_FREE(sidstr);
1356         if (rc != TLDAP_SUCCESS) {
1357                 DEBUG(10, ("ldap_search failed: %s\n",
1358                            tldap_errstr(talloc_tos(), state->ld, rc)));
1359                 return NT_STATUS_LDAP(rc);
1360         }
1361         if (talloc_array_length(alias) != 1) {
1362                 DEBUG(10, ("Expected 1 alias, got %d\n",
1363                            (int)talloc_array_length(alias)));
1364                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1365         }
1366         if (!tldap_entry_dn(alias[0], &dn)) {
1367                 DEBUG(10, ("Could not get DN for alias %s\n",
1368                            sid_string_dbg(sid)));
1369                 return NT_STATUS_INTERNAL_ERROR;
1370         }
1371
1372         rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
1373         if (rc != TLDAP_SUCCESS) {
1374                 DEBUG(10, ("ldap_delete failed: %s\n",
1375                            tldap_errstr(talloc_tos(), state->ld, rc)));
1376                 return NT_STATUS_LDAP(rc);
1377         }
1378
1379         return NT_STATUS_OK;
1380 }
1381
1382 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1383                                       const struct dom_sid *sid,
1384                                       struct acct_info *info)
1385 {
1386         struct pdb_ads_state *state = talloc_get_type_abort(
1387                 m->private_data, struct pdb_ads_state);
1388         struct tldap_context *ld;
1389         const char *attrs[3] = { "objectSid", "description",
1390                                  "samAccountName" };
1391         struct tldap_message **msg;
1392         char *sidstr, *dn;
1393         int rc;
1394         struct tldap_mod *mods;
1395         int num_mods;
1396         bool ok;
1397
1398         ld = pdb_ads_ld(state);
1399         if (ld == NULL) {
1400                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1401         }
1402
1403         sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1404         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1405
1406         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1407                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1408                                 &msg, "(&(objectSid=%s)(objectclass=group)"
1409                                 "(|(grouptype=%d)(grouptype=%d)))",
1410                                 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1411                                 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1412         TALLOC_FREE(sidstr);
1413         if (rc != TLDAP_SUCCESS) {
1414                 DEBUG(10, ("ldap_search failed %s\n",
1415                            tldap_errstr(talloc_tos(), state->ld, rc)));
1416                 return NT_STATUS_LDAP(rc);
1417         }
1418         switch talloc_array_length(msg) {
1419         case 0:
1420                 return NT_STATUS_NO_SUCH_ALIAS;
1421         case 1:
1422                 break;
1423         default:
1424                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1425         }
1426
1427         if (!tldap_entry_dn(msg[0], &dn)) {
1428                 TALLOC_FREE(msg);
1429                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1430         }
1431
1432         mods = NULL;
1433         num_mods = 0;
1434         ok = true;
1435
1436         ok &= tldap_make_mod_fmt(
1437                 msg[0], msg, &mods, &num_mods, "description",
1438                 "%s", info->acct_desc);
1439         ok &= tldap_make_mod_fmt(
1440                 msg[0], msg, &mods, &num_mods, "samAccountName",
1441                 "%s", info->acct_name);
1442         if (!ok) {
1443                 TALLOC_FREE(msg);
1444                 return NT_STATUS_NO_MEMORY;
1445         }
1446         if (num_mods == 0) {
1447                 /* no change */
1448                 TALLOC_FREE(msg);
1449                 return NT_STATUS_OK;
1450         }
1451
1452         rc = tldap_modify(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
1453         TALLOC_FREE(msg);
1454         if (rc != TLDAP_SUCCESS) {
1455                 DEBUG(10, ("ldap_modify failed: %s\n",
1456                            tldap_errstr(talloc_tos(), state->ld, rc)));
1457                 return NT_STATUS_LDAP(rc);
1458         }
1459         return NT_STATUS_OK;
1460 }
1461
1462 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1463                                const struct dom_sid *sid,
1464                                TALLOC_CTX *mem_ctx, char **pdn)
1465 {
1466         struct tldap_message **msg;
1467         char *sidstr, *dn;
1468         int rc;
1469
1470         sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
1471         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1472
1473         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1474                                 NULL, 0, 0, talloc_tos(), &msg,
1475                                 "(objectsid=%s)", sidstr);
1476         TALLOC_FREE(sidstr);
1477         if (rc != TLDAP_SUCCESS) {
1478                 DEBUG(10, ("ldap_search failed %s\n",
1479                            tldap_errstr(talloc_tos(), state->ld, rc)));
1480                 return NT_STATUS_LDAP(rc);
1481         }
1482
1483         switch talloc_array_length(msg) {
1484         case 0:
1485                 return NT_STATUS_NOT_FOUND;
1486         case 1:
1487                 break;
1488         default:
1489                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1490         }
1491
1492         if (!tldap_entry_dn(msg[0], &dn)) {
1493                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1494         }
1495
1496         dn = talloc_strdup(mem_ctx, dn);
1497         if (dn == NULL) {
1498                 return NT_STATUS_NO_MEMORY;
1499         }
1500         TALLOC_FREE(msg);
1501
1502         *pdn = dn;
1503         return NT_STATUS_OK;
1504 }
1505
1506 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1507                                      const struct dom_sid *alias,
1508                                      const struct dom_sid *member,
1509                                      int mod_op)
1510 {
1511         struct pdb_ads_state *state = talloc_get_type_abort(
1512                 m->private_data, struct pdb_ads_state);
1513         struct tldap_context *ld;
1514         TALLOC_CTX *frame = talloc_stackframe();
1515         struct tldap_mod *mods;
1516         int num_mods;
1517         int rc;
1518         char *aliasdn, *memberdn;
1519         NTSTATUS status;
1520
1521         ld = pdb_ads_ld(state);
1522         if (ld == NULL) {
1523                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1524         }
1525
1526         status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1527         if (!NT_STATUS_IS_OK(status)) {
1528                 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1529                            sid_string_dbg(alias), nt_errstr(status)));
1530                 TALLOC_FREE(frame);
1531                 return NT_STATUS_NO_SUCH_ALIAS;
1532         }
1533         status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1534         if (!NT_STATUS_IS_OK(status)) {
1535                 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1536                            sid_string_dbg(member), nt_errstr(status)));
1537                 TALLOC_FREE(frame);
1538                 return status;
1539         }
1540
1541         mods = NULL;
1542         num_mods = 0;
1543
1544         if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op,
1545                                "member", memberdn)) {
1546                 TALLOC_FREE(frame);
1547                 return NT_STATUS_NO_MEMORY;
1548         }
1549
1550         rc = tldap_modify(ld, aliasdn, mods, num_mods, NULL, 0, NULL, 0);
1551         TALLOC_FREE(frame);
1552         if (rc != TLDAP_SUCCESS) {
1553                 DEBUG(10, ("ldap_modify failed: %s\n",
1554                            tldap_errstr(talloc_tos(), state->ld, rc)));
1555                 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1556                         return NT_STATUS_MEMBER_IN_ALIAS;
1557                 }
1558                 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1559                         return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1560                 }
1561                 return NT_STATUS_LDAP(rc);
1562         }
1563
1564         return NT_STATUS_OK;
1565 }
1566
1567 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1568                                      const struct dom_sid *alias,
1569                                      const struct dom_sid *member)
1570 {
1571         return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1572 }
1573
1574 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1575                                      const struct dom_sid *alias,
1576                                      const struct dom_sid *member)
1577 {
1578         return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1579 }
1580
1581 static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
1582                                struct dom_sid *psid)
1583 {
1584         const char *attrs[1] = { "objectSid" };
1585         struct tldap_message **msg;
1586         char *dn;
1587         size_t len;
1588         int rc;
1589         bool ret;
1590
1591         if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1592                                    dnblob->data, dnblob->length, &dn, &len,
1593                                    false)) {
1594                 return false;
1595         }
1596         rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
1597                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1598                                 &msg, "(objectclass=*)");
1599         TALLOC_FREE(dn);
1600         if (talloc_array_length(msg) != 1) {
1601                 DEBUG(10, ("Got %d objects, expected one\n",
1602                            (int)talloc_array_length(msg)));
1603                 TALLOC_FREE(msg);
1604                 return false;
1605         }
1606
1607         ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1608         TALLOC_FREE(msg);
1609         return ret;
1610 }
1611
1612 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1613                                       const struct dom_sid *alias,
1614                                       TALLOC_CTX *mem_ctx,
1615                                       struct dom_sid **pmembers,
1616                                       size_t *pnum_members)
1617 {
1618         struct pdb_ads_state *state = talloc_get_type_abort(
1619                 m->private_data, struct pdb_ads_state);
1620         const char *attrs[1] = { "member" };
1621         char *sidstr;
1622         struct tldap_message **msg;
1623         int i, rc, num_members;
1624         DATA_BLOB *blobs;
1625         struct dom_sid *members;
1626
1627         sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), alias);
1628         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1629
1630         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1631                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1632                                 &msg, "(objectsid=%s)", sidstr);
1633         TALLOC_FREE(sidstr);
1634         if (rc != TLDAP_SUCCESS) {
1635                 DEBUG(10, ("ldap_search failed %s\n",
1636                            tldap_errstr(talloc_tos(), state->ld, rc)));
1637                 return NT_STATUS_LDAP(rc);
1638         }
1639         switch talloc_array_length(msg) {
1640         case 0:
1641                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1642                 break;
1643         case 1:
1644                 break;
1645         default:
1646                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1647                 break;
1648         }
1649
1650         if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
1651                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1652         }
1653
1654         members = talloc_array(mem_ctx, struct dom_sid, num_members);
1655         if (members == NULL) {
1656                 return NT_STATUS_NO_MEMORY;
1657         }
1658
1659         for (i=0; i<num_members; i++) {
1660                 if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
1661                         TALLOC_FREE(members);
1662                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1663                 }
1664         }
1665
1666         *pmembers = members;
1667         *pnum_members = num_members;
1668         return NT_STATUS_OK;
1669 }
1670
1671 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1672                                                TALLOC_CTX *mem_ctx,
1673                                                const struct dom_sid *domain_sid,
1674                                                const struct dom_sid *members,
1675                                                size_t num_members,
1676                                                uint32_t **palias_rids,
1677                                                size_t *pnum_alias_rids)
1678 {
1679         struct pdb_ads_state *state = talloc_get_type_abort(
1680                 m->private_data, struct pdb_ads_state);
1681         const char *attrs[1] = { "objectSid" };
1682         struct tldap_message **msg = NULL;
1683         uint32_t *alias_rids = NULL;
1684         size_t num_alias_rids = 0;
1685         int i, rc, count;
1686         bool got_members = false;
1687         char *filter;
1688         NTSTATUS status;
1689
1690         /*
1691          * TODO: Get the filter right so that we only get the aliases from
1692          * either the SAM or BUILTIN
1693          */
1694
1695         filter = talloc_asprintf(talloc_tos(),
1696                                  "(&(|(grouptype=%d)(grouptype=%d))"
1697                                  "(objectclass=group)(|",
1698                                  GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1699                                  GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1700         if (filter == NULL) {
1701                 return NT_STATUS_NO_MEMORY;
1702         }
1703
1704         for (i=0; i<num_members; i++) {
1705                 char *dn;
1706
1707                 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1708                 if (!NT_STATUS_IS_OK(status)) {
1709                         DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1710                                    sid_string_dbg(&members[i]),
1711                                    nt_errstr(status)));
1712                         continue;
1713                 }
1714                 filter = talloc_asprintf_append_buffer(
1715                         filter, "(member=%s)", dn);
1716                 TALLOC_FREE(dn);
1717                 if (filter == NULL) {
1718                         return NT_STATUS_NO_MEMORY;
1719                 }
1720                 got_members = true;
1721         }
1722
1723         if (!got_members) {
1724                 goto done;
1725         }
1726
1727         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1728                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1729                                 &msg, "%s))", filter);
1730         TALLOC_FREE(filter);
1731         if (rc != TLDAP_SUCCESS) {
1732                 DEBUG(10, ("tldap_search failed %s\n",
1733                            tldap_errstr(talloc_tos(), state->ld, rc)));
1734                 return NT_STATUS_LDAP(rc);
1735         }
1736
1737         count = talloc_array_length(msg);
1738         if (count == 0) {
1739                 goto done;
1740         }
1741
1742         alias_rids = talloc_array(mem_ctx, uint32_t, count);
1743         if (alias_rids == NULL) {
1744                 TALLOC_FREE(msg);
1745                 return NT_STATUS_NO_MEMORY;
1746         }
1747
1748         for (i=0; i<count; i++) {
1749                 struct dom_sid sid;
1750
1751                 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1752                         DEBUG(10, ("Could not pull SID for member %d\n", i));
1753                         continue;
1754                 }
1755                 if (sid_peek_check_rid(domain_sid, &sid,
1756                                        &alias_rids[num_alias_rids])) {
1757                         num_alias_rids += 1;
1758                 }
1759         }
1760 done:
1761         TALLOC_FREE(msg);
1762         *palias_rids = alias_rids;
1763         *pnum_alias_rids = 0;
1764         return NT_STATUS_OK;
1765 }
1766
1767 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1768                                     const struct dom_sid *domain_sid,
1769                                     int num_rids,
1770                                     uint32 *rids,
1771                                     const char **names,
1772                                     enum lsa_SidType *lsa_attrs)
1773 {
1774         struct pdb_ads_state *state = talloc_get_type_abort(
1775                 m->private_data, struct pdb_ads_state);
1776         const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1777         int i, num_mapped;
1778
1779         if (num_rids == 0) {
1780                 return NT_STATUS_NONE_MAPPED;
1781         }
1782
1783         num_mapped = 0;
1784
1785         for (i=0; i<num_rids; i++) {
1786                 struct dom_sid sid;
1787                 struct tldap_message **msg;
1788                 char *sidstr;
1789                 uint32_t attr;
1790                 int rc;
1791
1792                 lsa_attrs[i] = SID_NAME_UNKNOWN;
1793
1794                 sid_compose(&sid, domain_sid, rids[i]);
1795
1796                 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
1797                 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1798
1799                 rc = pdb_ads_search_fmt(state, state->domaindn,
1800                                         TLDAP_SCOPE_SUB, attrs,
1801                                         ARRAY_SIZE(attrs), 0, talloc_tos(),
1802                                         &msg, "(objectsid=%s)", sidstr);
1803                 TALLOC_FREE(sidstr);
1804                 if (rc != TLDAP_SUCCESS) {
1805                         DEBUG(10, ("ldap_search failed %s\n",
1806                                    tldap_errstr(talloc_tos(), state->ld, rc)));
1807                         continue;
1808                 }
1809
1810                 switch talloc_array_length(msg) {
1811                 case 0:
1812                         DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1813                         continue;
1814                 case 1:
1815                         break;
1816                 default:
1817                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1818                 }
1819
1820                 names[i] = tldap_talloc_single_attribute(
1821                         msg[0], "samAccountName", talloc_tos());
1822                 if (names[i] == NULL) {
1823                         DEBUG(10, ("no samAccountName\n"));
1824                         continue;
1825                 }
1826                 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1827                         DEBUG(10, ("no samAccountType"));
1828                         continue;
1829                 }
1830                 lsa_attrs[i] = ds_atype_map(attr);
1831                 num_mapped += 1;
1832         }
1833
1834         if (num_mapped == 0) {
1835                 return NT_STATUS_NONE_MAPPED;
1836         }
1837         if (num_mapped < num_rids) {
1838                 return STATUS_SOME_UNMAPPED;
1839         }
1840         return NT_STATUS_OK;
1841 }
1842
1843 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1844                                      const struct dom_sid *domain_sid,
1845                                      int num_names,
1846                                      const char **pp_names,
1847                                      uint32 *rids,
1848                                      enum lsa_SidType *attrs)
1849 {
1850         return NT_STATUS_NOT_IMPLEMENTED;
1851 }
1852
1853 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1854                                            enum pdb_policy_type type,
1855                                            uint32_t *value)
1856 {
1857         return account_policy_get(type, value)
1858                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1859 }
1860
1861 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1862                                            enum pdb_policy_type type,
1863                                            uint32_t value)
1864 {
1865         return account_policy_set(type, value)
1866                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1867 }
1868
1869 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1870                                     time_t *seq_num)
1871 {
1872         return NT_STATUS_NOT_IMPLEMENTED;
1873 }
1874
1875 struct pdb_ads_search_state {
1876         uint32_t acct_flags;
1877         struct samr_displayentry *entries;
1878         uint32_t num_entries;
1879         ssize_t array_size;
1880         uint32_t current;
1881 };
1882
1883 static bool pdb_ads_next_entry(struct pdb_search *search,
1884                                struct samr_displayentry *entry)
1885 {
1886         struct pdb_ads_search_state *state = talloc_get_type_abort(
1887                 search->private_data, struct pdb_ads_search_state);
1888
1889         if (state->current == state->num_entries) {
1890                 return false;
1891         }
1892
1893         entry->idx = state->entries[state->current].idx;
1894         entry->rid = state->entries[state->current].rid;
1895         entry->acct_flags = state->entries[state->current].acct_flags;
1896
1897         entry->account_name = talloc_strdup(
1898                 search, state->entries[state->current].account_name);
1899         entry->fullname = talloc_strdup(
1900                 search, state->entries[state->current].fullname);
1901         entry->description = talloc_strdup(
1902                 search, state->entries[state->current].description);
1903
1904         if ((entry->account_name == NULL) || (entry->fullname == NULL)
1905             || (entry->description == NULL)) {
1906                 DEBUG(0, ("talloc_strdup failed\n"));
1907                 return false;
1908         }
1909
1910         state->current += 1;
1911         return true;
1912 }
1913
1914 static void pdb_ads_search_end(struct pdb_search *search)
1915 {
1916         struct pdb_ads_search_state *state = talloc_get_type_abort(
1917                 search->private_data, struct pdb_ads_search_state);
1918         TALLOC_FREE(state);
1919 }
1920
1921 static bool pdb_ads_search_filter(struct pdb_methods *m,
1922                                   struct pdb_search *search,
1923                                   const char *filter,
1924                                   struct pdb_ads_search_state **pstate)
1925 {
1926         struct pdb_ads_state *state = talloc_get_type_abort(
1927                 m->private_data, struct pdb_ads_state);
1928         struct pdb_ads_search_state *sstate;
1929         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1930                                  "userAccountControl", "description" };
1931         struct tldap_message **users;
1932         int i, rc, num_users;
1933
1934         sstate = talloc_zero(search, struct pdb_ads_search_state);
1935         if (sstate == NULL) {
1936                 return false;
1937         }
1938
1939         rc = pdb_ads_search_fmt(
1940                 state, state->domaindn, TLDAP_SCOPE_SUB,
1941                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1942                 "%s", filter);
1943         if (rc != TLDAP_SUCCESS) {
1944                 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1945                            tldap_errstr(talloc_tos(), state->ld, rc)));
1946                 return false;
1947         }
1948
1949         num_users = talloc_array_length(users);
1950
1951         sstate->entries = talloc_array(sstate, struct samr_displayentry,
1952                                        num_users);
1953         if (sstate->entries == NULL) {
1954                 DEBUG(10, ("talloc failed\n"));
1955                 return false;
1956         }
1957
1958         sstate->num_entries = 0;
1959
1960         for (i=0; i<num_users; i++) {
1961                 struct samr_displayentry *e;
1962                 struct dom_sid sid;
1963                 uint32_t ctrl;
1964
1965                 e = &sstate->entries[sstate->num_entries];
1966
1967                 e->idx = sstate->num_entries;
1968                 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1969                         DEBUG(10, ("Could not pull sid\n"));
1970                         continue;
1971                 }
1972                 sid_peek_rid(&sid, &e->rid);
1973
1974                 if (tldap_pull_uint32(users[i], "userAccountControl", &ctrl)) {
1975                         e->acct_flags = ds_uf2acb(ctrl);
1976                         if (e->acct_flags & (ACB_WSTRUST|ACB_SVRTRUST)) {
1977                                 e->acct_flags |= ACB_NORMAL;
1978                         }
1979                 } else {
1980                         e->acct_flags = ACB_NORMAL;
1981                 }
1982
1983                 if (e->rid == DOMAIN_RID_GUEST) {
1984                         /*
1985                          * Guest is specially crafted in s3. Make
1986                          * QueryDisplayInfo match QueryUserInfo
1987                          */
1988                         e->account_name = lp_guestaccount();
1989                         e->fullname = lp_guestaccount();
1990                         e->description = "";
1991                         e->acct_flags = ACB_NORMAL;
1992                 } else {
1993                         e->account_name = tldap_talloc_single_attribute(
1994                                 users[i], "samAccountName", sstate->entries);
1995                         e->fullname = tldap_talloc_single_attribute(
1996                                 users[i], "displayName", sstate->entries);
1997                         e->description = tldap_talloc_single_attribute(
1998                                 users[i], "description", sstate->entries);
1999                 }
2000                 if (e->account_name == NULL) {
2001                         return false;
2002                 }
2003                 if (e->fullname == NULL) {
2004                         e->fullname = "";
2005                 }
2006                 if (e->description == NULL) {
2007                         e->description = "";
2008                 }
2009
2010                 sstate->num_entries += 1;
2011                 if (sstate->num_entries >= num_users) {
2012                         break;
2013                 }
2014         }
2015
2016         search->private_data = sstate;
2017         search->next_entry = pdb_ads_next_entry;
2018         search->search_end = pdb_ads_search_end;
2019         *pstate = sstate;
2020         return true;
2021 }
2022
2023 static bool pdb_ads_search_users(struct pdb_methods *m,
2024                                  struct pdb_search *search,
2025                                  uint32 acct_flags)
2026 {
2027         struct pdb_ads_search_state *sstate;
2028         char *filter;
2029         bool ret;
2030
2031         if (acct_flags & ACB_NORMAL) {
2032                 filter = talloc_asprintf(
2033                         talloc_tos(),
2034                         "(&(objectclass=user)(sAMAccountType=%d))",
2035                         ATYPE_NORMAL_ACCOUNT);
2036         } else if (acct_flags & ACB_WSTRUST) {
2037                 filter = talloc_asprintf(
2038                         talloc_tos(),
2039                         "(&(objectclass=user)(sAMAccountType=%d))",
2040                         ATYPE_WORKSTATION_TRUST);
2041         } else {
2042                 filter = talloc_strdup(talloc_tos(), "(objectclass=user)");
2043         }
2044         if (filter == NULL) {
2045                 return false;
2046         }
2047
2048         ret = pdb_ads_search_filter(m, search, filter, &sstate);
2049         TALLOC_FREE(filter);
2050         if (!ret) {
2051                 return false;
2052         }
2053         sstate->acct_flags = acct_flags;
2054         return true;
2055 }
2056
2057 static bool pdb_ads_search_groups(struct pdb_methods *m,
2058                                   struct pdb_search *search)
2059 {
2060         struct pdb_ads_search_state *sstate;
2061         char *filter;
2062         bool ret;
2063
2064         filter = talloc_asprintf(talloc_tos(),
2065                                  "(&(grouptype=%d)(objectclass=group))",
2066                                  GTYPE_SECURITY_GLOBAL_GROUP);
2067         if (filter == NULL) {
2068                 return false;
2069         }
2070         ret = pdb_ads_search_filter(m, search, filter, &sstate);
2071         TALLOC_FREE(filter);
2072         if (!ret) {
2073                 return false;
2074         }
2075         sstate->acct_flags = 0;
2076         return true;
2077 }
2078
2079 static bool pdb_ads_search_aliases(struct pdb_methods *m,
2080                                    struct pdb_search *search,
2081                                    const struct dom_sid *sid)
2082 {
2083         struct pdb_ads_search_state *sstate;
2084         char *filter;
2085         bool ret;
2086
2087         filter = talloc_asprintf(
2088                 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
2089                 sid_check_is_builtin(sid)
2090                 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2091                 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
2092
2093         if (filter == NULL) {
2094                 return false;
2095         }
2096         ret = pdb_ads_search_filter(m, search, filter, &sstate);
2097         TALLOC_FREE(filter);
2098         if (!ret) {
2099                 return false;
2100         }
2101         sstate->acct_flags = 0;
2102         return true;
2103 }
2104
2105 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
2106                                struct dom_sid *sid)
2107 {
2108         struct pdb_ads_state *state = talloc_get_type_abort(
2109                 m->private_data, struct pdb_ads_state);
2110         sid_compose(sid, &state->domainsid, uid);
2111         return true;
2112 }
2113
2114 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
2115                                struct dom_sid *sid)
2116 {
2117         struct pdb_ads_state *state = talloc_get_type_abort(
2118                 m->private_data, struct pdb_ads_state);
2119         sid_compose(sid, &state->domainsid, gid);
2120         return true;
2121 }
2122
2123 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2124                               union unid_t *id, enum lsa_SidType *type)
2125 {
2126         struct pdb_ads_state *state = talloc_get_type_abort(
2127                 m->private_data, struct pdb_ads_state);
2128         struct tldap_message **msg;
2129         char *sidstr;
2130         uint32_t rid;
2131         int rc;
2132
2133         /*
2134          * This is a big, big hack: Just hard-code the rid as uid/gid.
2135          */
2136
2137         sid_peek_rid(sid, &rid);
2138
2139         sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
2140         if (sidstr == NULL) {
2141                 return false;
2142         }
2143
2144         rc = pdb_ads_search_fmt(
2145                 state, state->domaindn, TLDAP_SCOPE_SUB,
2146                 NULL, 0, 0, talloc_tos(), &msg,
2147                 "(&(objectsid=%s)(objectclass=user))", sidstr);
2148         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
2149                 id->uid = rid;
2150                 *type = SID_NAME_USER;
2151                 TALLOC_FREE(sidstr);
2152                 return true;
2153         }
2154
2155         rc = pdb_ads_search_fmt(
2156                 state, state->domaindn, TLDAP_SCOPE_SUB,
2157                 NULL, 0, 0, talloc_tos(), &msg,
2158                 "(&(objectsid=%s)(objectclass=group))", sidstr);
2159         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
2160                 id->gid = rid;
2161                 *type = SID_NAME_DOM_GRP;
2162                 TALLOC_FREE(sidstr);
2163                 return true;
2164         }
2165
2166         TALLOC_FREE(sidstr);
2167         return false;
2168 }
2169
2170 static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
2171 {
2172         return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2173 }
2174
2175 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
2176 {
2177         return false;
2178 }
2179
2180 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
2181                                       const char *domain, char** pwd,
2182                                       struct dom_sid *sid,
2183                                       time_t *pass_last_set_time)
2184 {
2185         return false;
2186 }
2187
2188 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
2189                                       const char* domain, const char* pwd,
2190                                       const struct dom_sid *sid)
2191 {
2192         return false;
2193 }
2194
2195 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
2196                                       const char *domain)
2197 {
2198         return false;
2199 }
2200
2201 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
2202                                          TALLOC_CTX *mem_ctx,
2203                                          uint32 *num_domains,
2204                                          struct trustdom_info ***domains)
2205 {
2206         *num_domains = 0;
2207         *domains = NULL;
2208         return NT_STATUS_OK;
2209 }
2210
2211 static void pdb_ads_init_methods(struct pdb_methods *m)
2212 {
2213         m->name = "ads";
2214         m->get_domain_info = pdb_ads_get_domain_info;
2215         m->getsampwnam = pdb_ads_getsampwnam;
2216         m->getsampwsid = pdb_ads_getsampwsid;
2217         m->create_user = pdb_ads_create_user;
2218         m->delete_user = pdb_ads_delete_user;
2219         m->add_sam_account = pdb_ads_add_sam_account;
2220         m->update_sam_account = pdb_ads_update_sam_account;
2221         m->delete_sam_account = pdb_ads_delete_sam_account;
2222         m->rename_sam_account = pdb_ads_rename_sam_account;
2223         m->update_login_attempts = pdb_ads_update_login_attempts;
2224         m->getgrsid = pdb_ads_getgrsid;
2225         m->getgrgid = pdb_ads_getgrgid;
2226         m->getgrnam = pdb_ads_getgrnam;
2227         m->create_dom_group = pdb_ads_create_dom_group;
2228         m->delete_dom_group = pdb_ads_delete_dom_group;
2229         m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
2230         m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
2231         m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
2232         m->enum_group_mapping = pdb_ads_enum_group_mapping;
2233         m->enum_group_members = pdb_ads_enum_group_members;
2234         m->enum_group_memberships = pdb_ads_enum_group_memberships;
2235         m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
2236         m->add_groupmem = pdb_ads_add_groupmem;
2237         m->del_groupmem = pdb_ads_del_groupmem;
2238         m->create_alias = pdb_ads_create_alias;
2239         m->delete_alias = pdb_ads_delete_alias;
2240         m->get_aliasinfo = pdb_default_get_aliasinfo;
2241         m->set_aliasinfo = pdb_ads_set_aliasinfo;
2242         m->add_aliasmem = pdb_ads_add_aliasmem;
2243         m->del_aliasmem = pdb_ads_del_aliasmem;
2244         m->enum_aliasmem = pdb_ads_enum_aliasmem;
2245         m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
2246         m->lookup_rids = pdb_ads_lookup_rids;
2247         m->lookup_names = pdb_ads_lookup_names;
2248         m->get_account_policy = pdb_ads_get_account_policy;
2249         m->set_account_policy = pdb_ads_set_account_policy;
2250         m->get_seq_num = pdb_ads_get_seq_num;
2251         m->search_users = pdb_ads_search_users;
2252         m->search_groups = pdb_ads_search_groups;
2253         m->search_aliases = pdb_ads_search_aliases;
2254         m->uid_to_sid = pdb_ads_uid_to_sid;
2255         m->gid_to_sid = pdb_ads_gid_to_sid;
2256         m->sid_to_id = pdb_ads_sid_to_id;
2257         m->capabilities = pdb_ads_capabilities;
2258         m->new_rid = pdb_ads_new_rid;
2259         m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2260         m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2261         m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2262         m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2263 }
2264
2265 static void free_private_data(void **vp)
2266 {
2267         struct pdb_ads_state *state = talloc_get_type_abort(
2268                 *vp, struct pdb_ads_state);
2269
2270         TALLOC_FREE(state->ld);
2271         return;
2272 }
2273
2274 /*
2275   this is used to catch debug messages from events
2276 */
2277 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2278                            const char *fmt, va_list ap)  PRINTF_ATTRIBUTE(3,0);
2279
2280 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2281                            const char *fmt, va_list ap)
2282 {
2283         int samba_level = -1;
2284         char *s = NULL;
2285         switch (level) {
2286         case TLDAP_DEBUG_FATAL:
2287                 samba_level = 0;
2288                 break;
2289         case TLDAP_DEBUG_ERROR:
2290                 samba_level = 1;
2291                 break;
2292         case TLDAP_DEBUG_WARNING:
2293                 samba_level = 2;
2294                 break;
2295         case TLDAP_DEBUG_TRACE:
2296                 samba_level = 11;
2297                 break;
2298
2299         };
2300         if (vasprintf(&s, fmt, ap) == -1) {
2301                 return;
2302         }
2303         DEBUG(samba_level, ("tldap: %s", s));
2304         free(s);
2305 }
2306
2307 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2308 {
2309         NTSTATUS status;
2310         int fd;
2311
2312         if (tldap_connection_ok(state->ld)) {
2313                 return state->ld;
2314         }
2315         TALLOC_FREE(state->ld);
2316
2317         status = open_socket_out(
2318                 (struct sockaddr_storage *)(void *)&state->socket_address,
2319                 0, 0, &fd);
2320         if (!NT_STATUS_IS_OK(status)) {
2321                 DEBUG(10, ("Could not connect to %s: %s\n",
2322                            state->socket_address.sun_path, nt_errstr(status)));
2323                 return NULL;
2324         }
2325
2326         set_blocking(fd, false);
2327
2328         state->ld = tldap_context_create(state, fd);
2329         if (state->ld == NULL) {
2330                 close(fd);
2331                 return NULL;
2332         }
2333         tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2334
2335         return state->ld;
2336 }
2337
2338 int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2339                        int scope, const char *attrs[], int num_attrs,
2340                        int attrsonly,
2341                        TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2342                        const char *fmt, ...)
2343 {
2344         struct tldap_context *ld;
2345         va_list ap;
2346         int ret;
2347
2348         ld = pdb_ads_ld(state);
2349         if (ld == NULL) {
2350                 return TLDAP_SERVER_DOWN;
2351         }
2352
2353         va_start(ap, fmt);
2354         ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2355                               mem_ctx, res, fmt, ap);
2356         va_end(ap);
2357
2358         if (ret != TLDAP_SERVER_DOWN) {
2359                 return ret;
2360         }
2361
2362         /* retry once */
2363         ld = pdb_ads_ld(state);
2364         if (ld == NULL) {
2365                 return TLDAP_SERVER_DOWN;
2366         }
2367
2368         va_start(ap, fmt);
2369         ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2370                               mem_ctx, res, fmt, ap);
2371         va_end(ap);
2372         return ret;
2373 }
2374
2375 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2376                                 const char *location)
2377 {
2378         const char *domain_attrs[2] = { "objectSid", "objectGUID" };
2379         const char *ncname_attrs[1] = { "netbiosname" };
2380         struct tldap_context *ld;
2381         struct tldap_message *rootdse, **domain, **ncname;
2382         TALLOC_CTX *frame = talloc_stackframe();
2383         NTSTATUS status;
2384         int num_domains;
2385         int rc;
2386
2387         ZERO_STRUCT(state->socket_address);
2388         state->socket_address.sun_family = AF_UNIX;
2389         strlcpy(state->socket_address.sun_path, location,
2390                 sizeof(state->socket_address.sun_path));
2391
2392         ld = pdb_ads_ld(state);
2393         if (ld == NULL) {
2394                 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2395                 goto done;
2396         }
2397
2398         rc = tldap_fetch_rootdse(ld);
2399         if (rc != TLDAP_SUCCESS) {
2400                 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2401                            tldap_errstr(talloc_tos(), state->ld, rc)));
2402                 status = NT_STATUS_LDAP(rc);
2403                 goto done;
2404         }
2405         rootdse = tldap_rootdse(state->ld);
2406
2407         state->domaindn = tldap_talloc_single_attribute(
2408                 rootdse, "defaultNamingContext", state);
2409         if (state->domaindn == NULL) {
2410                 DEBUG(10, ("Could not get defaultNamingContext\n"));
2411                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2412                 goto done;
2413         }
2414         DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2415
2416         state->configdn = tldap_talloc_single_attribute(
2417                 rootdse, "configurationNamingContext", state);
2418         if (state->domaindn == NULL) {
2419                 DEBUG(10, ("Could not get configurationNamingContext\n"));
2420                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2421                 goto done;
2422         }
2423         DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2424
2425         /*
2426          * Figure out our domain's SID
2427          */
2428         rc = pdb_ads_search_fmt(
2429                 state, state->domaindn, TLDAP_SCOPE_BASE,
2430                 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2431                 talloc_tos(), &domain, "(objectclass=*)");
2432         if (rc != TLDAP_SUCCESS) {
2433                 DEBUG(10, ("Could not retrieve domain: %s\n",
2434                            tldap_errstr(talloc_tos(), state->ld, rc)));
2435                 status = NT_STATUS_LDAP(rc);
2436                 goto done;
2437         }
2438
2439         num_domains = talloc_array_length(domain);
2440         if (num_domains != 1) {
2441                 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2442                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2443                 goto done;
2444         }
2445         if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2446                 DEBUG(10, ("Could not retrieve domain SID\n"));
2447                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2448                 goto done;
2449         }
2450         if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) {
2451                 DEBUG(10, ("Could not retrieve domain GUID\n"));
2452                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2453                 goto done;
2454         }
2455         DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2456
2457         /*
2458          * Figure out our domain's short name
2459          */
2460         rc = pdb_ads_search_fmt(
2461                 state, state->configdn, TLDAP_SCOPE_SUB,
2462                 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2463                 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2464         if (rc != TLDAP_SUCCESS) {
2465                 DEBUG(10, ("Could not retrieve ncname: %s\n",
2466                            tldap_errstr(talloc_tos(), state->ld, rc)));
2467                 status = NT_STATUS_LDAP(rc);
2468                 goto done;
2469         }
2470         if (talloc_array_length(ncname) != 1) {
2471                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2472                 goto done;
2473         }
2474
2475         state->netbiosname = tldap_talloc_single_attribute(
2476                 ncname[0], "netbiosname", state);
2477         if (state->netbiosname == NULL) {
2478                 DEBUG(10, ("Could not get netbiosname\n"));
2479                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2480                 goto done;
2481         }
2482         DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2483
2484         if (!strequal(lp_workgroup(), state->netbiosname)) {
2485                 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2486                           state->netbiosname, lp_workgroup()));
2487                 status = NT_STATUS_NO_SUCH_DOMAIN;
2488                 goto done;
2489         }
2490
2491         secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2492
2493         status = NT_STATUS_OK;
2494 done:
2495         TALLOC_FREE(frame);
2496         return status;
2497 }
2498
2499 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2500                              const char *location)
2501 {
2502         struct pdb_methods *m;
2503         struct pdb_ads_state *state;
2504         char *tmp = NULL;
2505         NTSTATUS status;
2506
2507         m = talloc(NULL, struct pdb_methods);
2508         if (m == NULL) {
2509                 return NT_STATUS_NO_MEMORY;
2510         }
2511         state = talloc_zero(m, struct pdb_ads_state);
2512         if (state == NULL) {
2513                 goto nomem;
2514         }
2515         m->private_data = state;
2516         m->free_private_data = free_private_data;
2517         pdb_ads_init_methods(m);
2518
2519         if (location == NULL) {
2520                 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2521                                       lp_private_dir());
2522                 location = tmp;
2523         }
2524         if (location == NULL) {
2525                 goto nomem;
2526         }
2527
2528         status = pdb_ads_connect(state, location);
2529         if (!NT_STATUS_IS_OK(status)) {
2530                 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2531                 goto fail;
2532         }
2533
2534         *pdb_method = m;
2535         return NT_STATUS_OK;
2536 nomem:
2537         status = NT_STATUS_NO_MEMORY;
2538 fail:
2539         TALLOC_FREE(m);
2540         return status;
2541 }
2542
2543 NTSTATUS pdb_ads_init(void);
2544 NTSTATUS pdb_ads_init(void)
2545 {
2546         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
2547                                    pdb_init_ads);
2548 }