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