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