s3: Fix a cut&paste error in pdb_ads_connect
[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, false);
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                                    false)) {
1657                 return false;
1658         }
1659         rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
1660                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1661                                 &msg, "(objectclass=*)");
1662         TALLOC_FREE(dn);
1663         if (talloc_array_length(msg) != 1) {
1664                 DEBUG(10, ("Got %d objects, expected one\n",
1665                            (int)talloc_array_length(msg)));
1666                 TALLOC_FREE(msg);
1667                 return false;
1668         }
1669
1670         ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1671         TALLOC_FREE(msg);
1672         return ret;
1673 }
1674
1675 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1676                                       const struct dom_sid *alias,
1677                                       TALLOC_CTX *mem_ctx,
1678                                       struct dom_sid **pmembers,
1679                                       size_t *pnum_members)
1680 {
1681         struct pdb_ads_state *state = talloc_get_type_abort(
1682                 m->private_data, struct pdb_ads_state);
1683         const char *attrs[1] = { "member" };
1684         char *sidstr;
1685         struct tldap_message **msg;
1686         int i, rc, num_members;
1687         DATA_BLOB *blobs;
1688         struct dom_sid *members;
1689
1690         sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), alias);
1691         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1692
1693         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1694                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1695                                 &msg, "(objectsid=%s)", sidstr);
1696         TALLOC_FREE(sidstr);
1697         if (rc != TLDAP_SUCCESS) {
1698                 DEBUG(10, ("ldap_search failed %s\n",
1699                            tldap_errstr(talloc_tos(), state->ld, rc)));
1700                 return NT_STATUS_LDAP(rc);
1701         }
1702         switch talloc_array_length(msg) {
1703         case 0:
1704                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1705                 break;
1706         case 1:
1707                 break;
1708         default:
1709                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1710                 break;
1711         }
1712
1713         if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
1714                 *pmembers = NULL;
1715                 *pnum_members = 0;
1716                 return NT_STATUS_OK;
1717         }
1718
1719         members = talloc_array(mem_ctx, struct dom_sid, num_members);
1720         if (members == NULL) {
1721                 return NT_STATUS_NO_MEMORY;
1722         }
1723
1724         for (i=0; i<num_members; i++) {
1725                 if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
1726                         TALLOC_FREE(members);
1727                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1728                 }
1729         }
1730
1731         *pmembers = members;
1732         *pnum_members = num_members;
1733         return NT_STATUS_OK;
1734 }
1735
1736 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1737                                                TALLOC_CTX *mem_ctx,
1738                                                const struct dom_sid *domain_sid,
1739                                                const struct dom_sid *members,
1740                                                size_t num_members,
1741                                                uint32_t **palias_rids,
1742                                                size_t *pnum_alias_rids)
1743 {
1744         struct pdb_ads_state *state = talloc_get_type_abort(
1745                 m->private_data, struct pdb_ads_state);
1746         const char *attrs[1] = { "objectSid" };
1747         struct tldap_message **msg = NULL;
1748         uint32_t *alias_rids = NULL;
1749         size_t num_alias_rids = 0;
1750         int i, rc, count;
1751         bool got_members = false;
1752         char *filter;
1753         NTSTATUS status;
1754
1755         /*
1756          * TODO: Get the filter right so that we only get the aliases from
1757          * either the SAM or BUILTIN
1758          */
1759
1760         filter = talloc_asprintf(talloc_tos(),
1761                                  "(&(|(grouptype=%d)(grouptype=%d))"
1762                                  "(objectclass=group)(|",
1763                                  GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1764                                  GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1765         if (filter == NULL) {
1766                 return NT_STATUS_NO_MEMORY;
1767         }
1768
1769         for (i=0; i<num_members; i++) {
1770                 char *dn;
1771
1772                 status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
1773                 if (!NT_STATUS_IS_OK(status)) {
1774                         DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
1775                                    sid_string_dbg(&members[i]),
1776                                    nt_errstr(status)));
1777                         continue;
1778                 }
1779                 filter = talloc_asprintf_append_buffer(
1780                         filter, "(member=%s)", dn);
1781                 TALLOC_FREE(dn);
1782                 if (filter == NULL) {
1783                         return NT_STATUS_NO_MEMORY;
1784                 }
1785                 got_members = true;
1786         }
1787
1788         if (!got_members) {
1789                 goto done;
1790         }
1791
1792         rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1793                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1794                                 &msg, "%s))", filter);
1795         TALLOC_FREE(filter);
1796         if (rc != TLDAP_SUCCESS) {
1797                 DEBUG(10, ("tldap_search failed %s\n",
1798                            tldap_errstr(talloc_tos(), state->ld, rc)));
1799                 return NT_STATUS_LDAP(rc);
1800         }
1801
1802         count = talloc_array_length(msg);
1803         if (count == 0) {
1804                 goto done;
1805         }
1806
1807         alias_rids = talloc_array(mem_ctx, uint32_t, count);
1808         if (alias_rids == NULL) {
1809                 TALLOC_FREE(msg);
1810                 return NT_STATUS_NO_MEMORY;
1811         }
1812
1813         for (i=0; i<count; i++) {
1814                 struct dom_sid sid;
1815
1816                 if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
1817                         DEBUG(10, ("Could not pull SID for member %d\n", i));
1818                         continue;
1819                 }
1820                 if (sid_peek_check_rid(domain_sid, &sid,
1821                                        &alias_rids[num_alias_rids])) {
1822                         num_alias_rids += 1;
1823                 }
1824         }
1825 done:
1826         TALLOC_FREE(msg);
1827         *palias_rids = alias_rids;
1828         *pnum_alias_rids = 0;
1829         return NT_STATUS_OK;
1830 }
1831
1832 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1833                                     const struct dom_sid *domain_sid,
1834                                     int num_rids,
1835                                     uint32 *rids,
1836                                     const char **names,
1837                                     enum lsa_SidType *lsa_attrs)
1838 {
1839         struct pdb_ads_state *state = talloc_get_type_abort(
1840                 m->private_data, struct pdb_ads_state);
1841         const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1842         int i, num_mapped;
1843
1844         if (num_rids == 0) {
1845                 return NT_STATUS_NONE_MAPPED;
1846         }
1847
1848         num_mapped = 0;
1849
1850         for (i=0; i<num_rids; i++) {
1851                 struct dom_sid sid;
1852                 struct tldap_message **msg;
1853                 char *sidstr;
1854                 uint32_t attr;
1855                 int rc;
1856
1857                 lsa_attrs[i] = SID_NAME_UNKNOWN;
1858
1859                 sid_compose(&sid, domain_sid, rids[i]);
1860
1861                 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
1862                 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1863
1864                 rc = pdb_ads_search_fmt(state, state->domaindn,
1865                                         TLDAP_SCOPE_SUB, attrs,
1866                                         ARRAY_SIZE(attrs), 0, talloc_tos(),
1867                                         &msg, "(objectsid=%s)", sidstr);
1868                 TALLOC_FREE(sidstr);
1869                 if (rc != TLDAP_SUCCESS) {
1870                         DEBUG(10, ("ldap_search failed %s\n",
1871                                    tldap_errstr(talloc_tos(), state->ld, rc)));
1872                         continue;
1873                 }
1874
1875                 switch talloc_array_length(msg) {
1876                 case 0:
1877                         DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1878                         continue;
1879                 case 1:
1880                         break;
1881                 default:
1882                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1883                 }
1884
1885                 names[i] = tldap_talloc_single_attribute(
1886                         msg[0], "samAccountName", talloc_tos());
1887                 if (names[i] == NULL) {
1888                         DEBUG(10, ("no samAccountName\n"));
1889                         continue;
1890                 }
1891                 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1892                         DEBUG(10, ("no samAccountType"));
1893                         continue;
1894                 }
1895                 lsa_attrs[i] = ds_atype_map(attr);
1896                 num_mapped += 1;
1897         }
1898
1899         if (num_mapped == 0) {
1900                 return NT_STATUS_NONE_MAPPED;
1901         }
1902         if (num_mapped < num_rids) {
1903                 return STATUS_SOME_UNMAPPED;
1904         }
1905         return NT_STATUS_OK;
1906 }
1907
1908 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1909                                      const struct dom_sid *domain_sid,
1910                                      int num_names,
1911                                      const char **pp_names,
1912                                      uint32 *rids,
1913                                      enum lsa_SidType *attrs)
1914 {
1915         return NT_STATUS_NOT_IMPLEMENTED;
1916 }
1917
1918 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1919                                            enum pdb_policy_type type,
1920                                            uint32_t *value)
1921 {
1922         return account_policy_get(type, value)
1923                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1924 }
1925
1926 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1927                                            enum pdb_policy_type type,
1928                                            uint32_t value)
1929 {
1930         return account_policy_set(type, value)
1931                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1932 }
1933
1934 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1935                                     time_t *seq_num)
1936 {
1937         return NT_STATUS_NOT_IMPLEMENTED;
1938 }
1939
1940 struct pdb_ads_search_state {
1941         uint32_t acct_flags;
1942         struct samr_displayentry *entries;
1943         uint32_t num_entries;
1944         ssize_t array_size;
1945         uint32_t current;
1946 };
1947
1948 static bool pdb_ads_next_entry(struct pdb_search *search,
1949                                struct samr_displayentry *entry)
1950 {
1951         struct pdb_ads_search_state *state = talloc_get_type_abort(
1952                 search->private_data, struct pdb_ads_search_state);
1953
1954         if (state->current == state->num_entries) {
1955                 return false;
1956         }
1957
1958         entry->idx = state->entries[state->current].idx;
1959         entry->rid = state->entries[state->current].rid;
1960         entry->acct_flags = state->entries[state->current].acct_flags;
1961
1962         entry->account_name = talloc_strdup(
1963                 search, state->entries[state->current].account_name);
1964         entry->fullname = talloc_strdup(
1965                 search, state->entries[state->current].fullname);
1966         entry->description = talloc_strdup(
1967                 search, state->entries[state->current].description);
1968
1969         if ((entry->account_name == NULL) || (entry->fullname == NULL)
1970             || (entry->description == NULL)) {
1971                 DEBUG(0, ("talloc_strdup failed\n"));
1972                 return false;
1973         }
1974
1975         state->current += 1;
1976         return true;
1977 }
1978
1979 static void pdb_ads_search_end(struct pdb_search *search)
1980 {
1981         struct pdb_ads_search_state *state = talloc_get_type_abort(
1982                 search->private_data, struct pdb_ads_search_state);
1983         TALLOC_FREE(state);
1984 }
1985
1986 static bool pdb_ads_search_filter(struct pdb_methods *m,
1987                                   struct pdb_search *search,
1988                                   const char *filter,
1989                                   uint32_t acct_flags,
1990                                   struct pdb_ads_search_state **pstate)
1991 {
1992         struct pdb_ads_state *state = talloc_get_type_abort(
1993                 m->private_data, struct pdb_ads_state);
1994         struct pdb_ads_search_state *sstate;
1995         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1996                                  "userAccountControl", "description" };
1997         struct tldap_message **users;
1998         int i, rc, num_users;
1999
2000         sstate = talloc_zero(search, struct pdb_ads_search_state);
2001         if (sstate == NULL) {
2002                 return false;
2003         }
2004         sstate->acct_flags = acct_flags;
2005
2006         rc = pdb_ads_search_fmt(
2007                 state, state->domaindn, TLDAP_SCOPE_SUB,
2008                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
2009                 "%s", filter);
2010         if (rc != TLDAP_SUCCESS) {
2011                 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
2012                            tldap_errstr(talloc_tos(), state->ld, rc)));
2013                 return false;
2014         }
2015
2016         num_users = talloc_array_length(users);
2017
2018         sstate->entries = talloc_array(sstate, struct samr_displayentry,
2019                                        num_users);
2020         if (sstate->entries == NULL) {
2021                 DEBUG(10, ("talloc failed\n"));
2022                 return false;
2023         }
2024
2025         sstate->num_entries = 0;
2026
2027         for (i=0; i<num_users; i++) {
2028                 struct samr_displayentry *e;
2029                 struct dom_sid sid;
2030                 uint32_t ctrl;
2031
2032                 e = &sstate->entries[sstate->num_entries];
2033
2034                 e->idx = sstate->num_entries;
2035                 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
2036                         DEBUG(10, ("Could not pull sid\n"));
2037                         continue;
2038                 }
2039                 sid_peek_rid(&sid, &e->rid);
2040
2041                 if (tldap_pull_uint32(users[i], "userAccountControl", &ctrl)) {
2042
2043                         e->acct_flags = ds_uf2acb(ctrl);
2044
2045                         DEBUG(10, ("pdb_ads_search_filter: Found %x, "
2046                                    "filter %x\n", (int)e->acct_flags,
2047                                    (int)sstate->acct_flags));
2048
2049
2050                         if ((sstate->acct_flags != 0) &&
2051                             ((sstate->acct_flags & e->acct_flags) == 0)) {
2052                                 continue;
2053                         }
2054
2055                         if (e->acct_flags & (ACB_WSTRUST|ACB_SVRTRUST)) {
2056                                 e->acct_flags |= ACB_NORMAL;
2057                         }
2058                 } else {
2059                         e->acct_flags = ACB_NORMAL;
2060                 }
2061
2062                 if (e->rid == DOMAIN_RID_GUEST) {
2063                         /*
2064                          * Guest is specially crafted in s3. Make
2065                          * QueryDisplayInfo match QueryUserInfo
2066                          */
2067                         e->account_name = lp_guestaccount();
2068                         e->fullname = lp_guestaccount();
2069                         e->description = "";
2070                         e->acct_flags = ACB_NORMAL;
2071                 } else {
2072                         e->account_name = tldap_talloc_single_attribute(
2073                                 users[i], "samAccountName", sstate->entries);
2074                         e->fullname = tldap_talloc_single_attribute(
2075                                 users[i], "displayName", sstate->entries);
2076                         e->description = tldap_talloc_single_attribute(
2077                                 users[i], "description", sstate->entries);
2078                 }
2079                 if (e->account_name == NULL) {
2080                         return false;
2081                 }
2082                 if (e->fullname == NULL) {
2083                         e->fullname = "";
2084                 }
2085                 if (e->description == NULL) {
2086                         e->description = "";
2087                 }
2088
2089                 sstate->num_entries += 1;
2090                 if (sstate->num_entries >= num_users) {
2091                         break;
2092                 }
2093         }
2094
2095         search->private_data = sstate;
2096         search->next_entry = pdb_ads_next_entry;
2097         search->search_end = pdb_ads_search_end;
2098         *pstate = sstate;
2099         return true;
2100 }
2101
2102 static bool pdb_ads_search_users(struct pdb_methods *m,
2103                                  struct pdb_search *search,
2104                                  uint32 acct_flags)
2105 {
2106         struct pdb_ads_search_state *sstate;
2107         char *filter;
2108         bool ret;
2109
2110         DEBUG(10, ("pdb_ads_search_users got flags %x\n", acct_flags));
2111
2112         if (acct_flags & ACB_NORMAL) {
2113                 filter = talloc_asprintf(
2114                         talloc_tos(),
2115                         "(&(objectclass=user)(sAMAccountType=%d))",
2116                         ATYPE_NORMAL_ACCOUNT);
2117         } else if (acct_flags & ACB_WSTRUST) {
2118                 filter = talloc_asprintf(
2119                         talloc_tos(),
2120                         "(&(objectclass=user)(sAMAccountType=%d))",
2121                         ATYPE_WORKSTATION_TRUST);
2122         } else {
2123                 filter = talloc_strdup(talloc_tos(), "(objectclass=user)");
2124         }
2125         if (filter == NULL) {
2126                 return false;
2127         }
2128
2129         ret = pdb_ads_search_filter(m, search, filter, acct_flags, &sstate);
2130         TALLOC_FREE(filter);
2131         if (!ret) {
2132                 return false;
2133         }
2134         return true;
2135 }
2136
2137 static bool pdb_ads_search_groups(struct pdb_methods *m,
2138                                   struct pdb_search *search)
2139 {
2140         struct pdb_ads_search_state *sstate;
2141         char *filter;
2142         bool ret;
2143
2144         filter = talloc_asprintf(talloc_tos(),
2145                                  "(&(grouptype=%d)(objectclass=group))",
2146                                  GTYPE_SECURITY_GLOBAL_GROUP);
2147         if (filter == NULL) {
2148                 return false;
2149         }
2150         ret = pdb_ads_search_filter(m, search, filter, 0, &sstate);
2151         TALLOC_FREE(filter);
2152         if (!ret) {
2153                 return false;
2154         }
2155         return true;
2156 }
2157
2158 static bool pdb_ads_search_aliases(struct pdb_methods *m,
2159                                    struct pdb_search *search,
2160                                    const struct dom_sid *sid)
2161 {
2162         struct pdb_ads_search_state *sstate;
2163         char *filter;
2164         bool ret;
2165
2166         filter = talloc_asprintf(
2167                 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
2168                 sid_check_is_builtin(sid)
2169                 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2170                 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
2171
2172         if (filter == NULL) {
2173                 return false;
2174         }
2175         ret = pdb_ads_search_filter(m, search, filter, 0, &sstate);
2176         TALLOC_FREE(filter);
2177         if (!ret) {
2178                 return false;
2179         }
2180         return true;
2181 }
2182
2183 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
2184                                struct dom_sid *sid)
2185 {
2186         struct pdb_ads_state *state = talloc_get_type_abort(
2187                 m->private_data, struct pdb_ads_state);
2188         sid_compose(sid, &state->domainsid, uid);
2189         return true;
2190 }
2191
2192 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
2193                                struct dom_sid *sid)
2194 {
2195         struct pdb_ads_state *state = talloc_get_type_abort(
2196                 m->private_data, struct pdb_ads_state);
2197         sid_compose(sid, &state->domainsid, gid);
2198         return true;
2199 }
2200
2201 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2202                               union unid_t *id, enum lsa_SidType *type)
2203 {
2204         struct pdb_ads_state *state = talloc_get_type_abort(
2205                 m->private_data, struct pdb_ads_state);
2206         const char *attrs[4] = { "objectClass", "samAccountType",
2207                                  "uidNumber", "gidNumber" };
2208         struct tldap_message **msg;
2209         char *sidstr, *base;
2210         uint32_t atype;
2211         int rc;
2212         bool ret = false;
2213
2214         sidstr = sid_binstring_hex(sid);
2215         if (sidstr == NULL) {
2216                 return false;
2217         }
2218         base = talloc_asprintf(talloc_tos(), "<SID=%s>", sidstr);
2219         SAFE_FREE(sidstr);
2220
2221         rc = pdb_ads_search_fmt(
2222                 state, base, TLDAP_SCOPE_BASE,
2223                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
2224                 "(objectclass=*)");
2225         TALLOC_FREE(base);
2226
2227         if (rc != TLDAP_SUCCESS) {
2228                 DEBUG(10, ("pdb_ads_search_fmt failed: %s\n",
2229                            tldap_errstr(talloc_tos(), state->ld, rc)));
2230                 return false;
2231         }
2232         if (talloc_array_length(msg) != 1) {
2233                 DEBUG(10, ("Got %d objects, expected 1\n",
2234                            talloc_array_length(msg)));
2235                 goto fail;
2236         }
2237         if (!tldap_pull_uint32(msg[0], "samAccountType", &atype)) {
2238                 DEBUG(10, ("samAccountType not found\n"));
2239                 goto fail;
2240         }
2241         if (atype == ATYPE_ACCOUNT) {
2242                 uint32_t uid;
2243                 *type = SID_NAME_USER;
2244                 if (!tldap_pull_uint32(msg[0], "uidNumber", &uid)) {
2245                         DEBUG(10, ("Did not find uidNumber\n"));
2246                         goto fail;
2247                 }
2248                 id->uid = uid;
2249         } else {
2250                 uint32_t gid;
2251                 *type = SID_NAME_DOM_GRP;
2252                 if (!tldap_pull_uint32(msg[0], "gidNumber", &gid)) {
2253                         DEBUG(10, ("Did not find gidNumber\n"));
2254                         goto fail;
2255                 }
2256                 id->gid = gid;
2257         }
2258         ret = true;
2259 fail:
2260         TALLOC_FREE(msg);
2261         return ret;
2262 }
2263
2264 static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
2265 {
2266         return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2267 }
2268
2269 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
2270 {
2271         return false;
2272 }
2273
2274 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
2275                                       const char *domain, char** pwd,
2276                                       struct dom_sid *sid,
2277                                       time_t *pass_last_set_time)
2278 {
2279         return false;
2280 }
2281
2282 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
2283                                       const char* domain, const char* pwd,
2284                                       const struct dom_sid *sid)
2285 {
2286         return false;
2287 }
2288
2289 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
2290                                       const char *domain)
2291 {
2292         return false;
2293 }
2294
2295 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
2296                                          TALLOC_CTX *mem_ctx,
2297                                          uint32 *num_domains,
2298                                          struct trustdom_info ***domains)
2299 {
2300         *num_domains = 0;
2301         *domains = NULL;
2302         return NT_STATUS_OK;
2303 }
2304
2305 static void pdb_ads_init_methods(struct pdb_methods *m)
2306 {
2307         m->name = "ads";
2308         m->get_domain_info = pdb_ads_get_domain_info;
2309         m->getsampwnam = pdb_ads_getsampwnam;
2310         m->getsampwsid = pdb_ads_getsampwsid;
2311         m->create_user = pdb_ads_create_user;
2312         m->delete_user = pdb_ads_delete_user;
2313         m->add_sam_account = pdb_ads_add_sam_account;
2314         m->update_sam_account = pdb_ads_update_sam_account;
2315         m->delete_sam_account = pdb_ads_delete_sam_account;
2316         m->rename_sam_account = pdb_ads_rename_sam_account;
2317         m->update_login_attempts = pdb_ads_update_login_attempts;
2318         m->getgrsid = pdb_ads_getgrsid;
2319         m->getgrgid = pdb_ads_getgrgid;
2320         m->getgrnam = pdb_ads_getgrnam;
2321         m->create_dom_group = pdb_ads_create_dom_group;
2322         m->delete_dom_group = pdb_ads_delete_dom_group;
2323         m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
2324         m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
2325         m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
2326         m->enum_group_mapping = pdb_ads_enum_group_mapping;
2327         m->enum_group_members = pdb_ads_enum_group_members;
2328         m->enum_group_memberships = pdb_ads_enum_group_memberships;
2329         m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
2330         m->add_groupmem = pdb_ads_add_groupmem;
2331         m->del_groupmem = pdb_ads_del_groupmem;
2332         m->create_alias = pdb_ads_create_alias;
2333         m->delete_alias = pdb_ads_delete_alias;
2334         m->get_aliasinfo = pdb_default_get_aliasinfo;
2335         m->set_aliasinfo = pdb_ads_set_aliasinfo;
2336         m->add_aliasmem = pdb_ads_add_aliasmem;
2337         m->del_aliasmem = pdb_ads_del_aliasmem;
2338         m->enum_aliasmem = pdb_ads_enum_aliasmem;
2339         m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
2340         m->lookup_rids = pdb_ads_lookup_rids;
2341         m->lookup_names = pdb_ads_lookup_names;
2342         m->get_account_policy = pdb_ads_get_account_policy;
2343         m->set_account_policy = pdb_ads_set_account_policy;
2344         m->get_seq_num = pdb_ads_get_seq_num;
2345         m->search_users = pdb_ads_search_users;
2346         m->search_groups = pdb_ads_search_groups;
2347         m->search_aliases = pdb_ads_search_aliases;
2348         m->uid_to_sid = pdb_ads_uid_to_sid;
2349         m->gid_to_sid = pdb_ads_gid_to_sid;
2350         m->sid_to_id = pdb_ads_sid_to_id;
2351         m->capabilities = pdb_ads_capabilities;
2352         m->new_rid = pdb_ads_new_rid;
2353         m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
2354         m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
2355         m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
2356         m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
2357 }
2358
2359 static void free_private_data(void **vp)
2360 {
2361         struct pdb_ads_state *state = talloc_get_type_abort(
2362                 *vp, struct pdb_ads_state);
2363
2364         TALLOC_FREE(state->ld);
2365         return;
2366 }
2367
2368 /*
2369   this is used to catch debug messages from events
2370 */
2371 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2372                            const char *fmt, va_list ap)  PRINTF_ATTRIBUTE(3,0);
2373
2374 static void s3_tldap_debug(void *context, enum tldap_debug_level level,
2375                            const char *fmt, va_list ap)
2376 {
2377         int samba_level = -1;
2378         char *s = NULL;
2379         switch (level) {
2380         case TLDAP_DEBUG_FATAL:
2381                 samba_level = 0;
2382                 break;
2383         case TLDAP_DEBUG_ERROR:
2384                 samba_level = 1;
2385                 break;
2386         case TLDAP_DEBUG_WARNING:
2387                 samba_level = 2;
2388                 break;
2389         case TLDAP_DEBUG_TRACE:
2390                 samba_level = 11;
2391                 break;
2392
2393         };
2394         if (vasprintf(&s, fmt, ap) == -1) {
2395                 return;
2396         }
2397         DEBUG(samba_level, ("tldap: %s", s));
2398         free(s);
2399 }
2400
2401 static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
2402 {
2403         NTSTATUS status;
2404         int fd;
2405
2406         if (tldap_connection_ok(state->ld)) {
2407                 return state->ld;
2408         }
2409         TALLOC_FREE(state->ld);
2410
2411         status = open_socket_out(
2412                 (struct sockaddr_storage *)(void *)&state->socket_address,
2413                 0, 0, &fd);
2414         if (!NT_STATUS_IS_OK(status)) {
2415                 DEBUG(10, ("Could not connect to %s: %s\n",
2416                            state->socket_address.sun_path, nt_errstr(status)));
2417                 return NULL;
2418         }
2419
2420         set_blocking(fd, false);
2421
2422         state->ld = tldap_context_create(state, fd);
2423         if (state->ld == NULL) {
2424                 close(fd);
2425                 return NULL;
2426         }
2427         tldap_set_debug(state->ld, s3_tldap_debug, NULL);
2428
2429         return state->ld;
2430 }
2431
2432 int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
2433                        int scope, const char *attrs[], int num_attrs,
2434                        int attrsonly,
2435                        TALLOC_CTX *mem_ctx, struct tldap_message ***res,
2436                        const char *fmt, ...)
2437 {
2438         struct tldap_context *ld;
2439         va_list ap;
2440         int ret;
2441
2442         ld = pdb_ads_ld(state);
2443         if (ld == NULL) {
2444                 return TLDAP_SERVER_DOWN;
2445         }
2446
2447         va_start(ap, fmt);
2448         ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2449                               mem_ctx, res, fmt, ap);
2450         va_end(ap);
2451
2452         if (ret != TLDAP_SERVER_DOWN) {
2453                 return ret;
2454         }
2455
2456         /* retry once */
2457         ld = pdb_ads_ld(state);
2458         if (ld == NULL) {
2459                 return TLDAP_SERVER_DOWN;
2460         }
2461
2462         va_start(ap, fmt);
2463         ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
2464                               mem_ctx, res, fmt, ap);
2465         va_end(ap);
2466         return ret;
2467 }
2468
2469 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
2470                                 const char *location)
2471 {
2472         const char *domain_attrs[2] = { "objectSid", "objectGUID" };
2473         const char *ncname_attrs[1] = { "netbiosname" };
2474         struct tldap_context *ld;
2475         struct tldap_message *rootdse, **domain, **ncname;
2476         TALLOC_CTX *frame = talloc_stackframe();
2477         NTSTATUS status;
2478         int num_domains;
2479         int rc;
2480
2481         ZERO_STRUCT(state->socket_address);
2482         state->socket_address.sun_family = AF_UNIX;
2483         strlcpy(state->socket_address.sun_path, location,
2484                 sizeof(state->socket_address.sun_path));
2485
2486         ld = pdb_ads_ld(state);
2487         if (ld == NULL) {
2488                 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2489                 goto done;
2490         }
2491
2492         rc = tldap_fetch_rootdse(ld);
2493         if (rc != TLDAP_SUCCESS) {
2494                 DEBUG(10, ("Could not retrieve rootdse: %s\n",
2495                            tldap_errstr(talloc_tos(), state->ld, rc)));
2496                 status = NT_STATUS_LDAP(rc);
2497                 goto done;
2498         }
2499         rootdse = tldap_rootdse(state->ld);
2500
2501         state->domaindn = tldap_talloc_single_attribute(
2502                 rootdse, "defaultNamingContext", state);
2503         if (state->domaindn == NULL) {
2504                 DEBUG(10, ("Could not get defaultNamingContext\n"));
2505                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2506                 goto done;
2507         }
2508         DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
2509
2510         state->configdn = tldap_talloc_single_attribute(
2511                 rootdse, "configurationNamingContext", state);
2512         if (state->configdn == NULL) {
2513                 DEBUG(10, ("Could not get configurationNamingContext\n"));
2514                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2515                 goto done;
2516         }
2517         DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
2518
2519         /*
2520          * Figure out our domain's SID
2521          */
2522         rc = pdb_ads_search_fmt(
2523                 state, state->domaindn, TLDAP_SCOPE_BASE,
2524                 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
2525                 talloc_tos(), &domain, "(objectclass=*)");
2526         if (rc != TLDAP_SUCCESS) {
2527                 DEBUG(10, ("Could not retrieve domain: %s\n",
2528                            tldap_errstr(talloc_tos(), state->ld, rc)));
2529                 status = NT_STATUS_LDAP(rc);
2530                 goto done;
2531         }
2532
2533         num_domains = talloc_array_length(domain);
2534         if (num_domains != 1) {
2535                 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
2536                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2537                 goto done;
2538         }
2539         if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
2540                 DEBUG(10, ("Could not retrieve domain SID\n"));
2541                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2542                 goto done;
2543         }
2544         if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) {
2545                 DEBUG(10, ("Could not retrieve domain GUID\n"));
2546                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2547                 goto done;
2548         }
2549         DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
2550
2551         /*
2552          * Figure out our domain's short name
2553          */
2554         rc = pdb_ads_search_fmt(
2555                 state, state->configdn, TLDAP_SCOPE_SUB,
2556                 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
2557                 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
2558         if (rc != TLDAP_SUCCESS) {
2559                 DEBUG(10, ("Could not retrieve ncname: %s\n",
2560                            tldap_errstr(talloc_tos(), state->ld, rc)));
2561                 status = NT_STATUS_LDAP(rc);
2562                 goto done;
2563         }
2564         if (talloc_array_length(ncname) != 1) {
2565                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2566                 goto done;
2567         }
2568
2569         state->netbiosname = tldap_talloc_single_attribute(
2570                 ncname[0], "netbiosname", state);
2571         if (state->netbiosname == NULL) {
2572                 DEBUG(10, ("Could not get netbiosname\n"));
2573                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2574                 goto done;
2575         }
2576         DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
2577
2578         if (!strequal(lp_workgroup(), state->netbiosname)) {
2579                 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
2580                           state->netbiosname, lp_workgroup()));
2581                 status = NT_STATUS_NO_SUCH_DOMAIN;
2582                 goto done;
2583         }
2584
2585         secrets_store_domain_sid(state->netbiosname, &state->domainsid);
2586
2587         status = NT_STATUS_OK;
2588 done:
2589         TALLOC_FREE(frame);
2590         return status;
2591 }
2592
2593 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
2594                              const char *location)
2595 {
2596         struct pdb_methods *m;
2597         struct pdb_ads_state *state;
2598         char *tmp = NULL;
2599         NTSTATUS status;
2600
2601         m = talloc(NULL, struct pdb_methods);
2602         if (m == NULL) {
2603                 return NT_STATUS_NO_MEMORY;
2604         }
2605         state = talloc_zero(m, struct pdb_ads_state);
2606         if (state == NULL) {
2607                 goto nomem;
2608         }
2609         m->private_data = state;
2610         m->free_private_data = free_private_data;
2611         pdb_ads_init_methods(m);
2612
2613         if (location == NULL) {
2614                 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
2615                                       lp_private_dir());
2616                 location = tmp;
2617         }
2618         if (location == NULL) {
2619                 goto nomem;
2620         }
2621
2622         status = pdb_ads_connect(state, location);
2623         if (!NT_STATUS_IS_OK(status)) {
2624                 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
2625                 goto fail;
2626         }
2627
2628         *pdb_method = m;
2629         return NT_STATUS_OK;
2630 nomem:
2631         status = NT_STATUS_NO_MEMORY;
2632 fail:
2633         TALLOC_FREE(m);
2634         return status;
2635 }
2636
2637 NTSTATUS pdb_ads_init(void);
2638 NTSTATUS pdb_ads_init(void)
2639 {
2640         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
2641                                    pdb_init_ads);
2642 }