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