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