Implement pdb_ads_enum_group_members
[ira/wip.git] / source3 / passdb / pdb_ads.c
1 /*
2    Unix SMB/CIFS implementation.
3    pdb_ldap with ads schema
4    Copyright (C) Volker Lendecke 2009
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21
22 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
23                                     struct samu *sam_acct,
24                                     const DOM_SID *sid);
25 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
26                                DOM_SID *sid);
27 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
28                                struct dom_sid *psid);
29
30
31 struct pdb_ads_state {
32         struct tldap_context *ld;
33         struct dom_sid domainsid;
34         char *domaindn;
35         char *configdn;
36         char *netbiosname;
37 };
38
39 static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
40                               time_t *ptime)
41 {
42         uint64_t tmp;
43
44         if (!tldap_pull_uint64(msg, attr, &tmp)) {
45                 return false;
46         }
47         *ptime = uint64s_nt_time_to_unix_abs(&tmp);
48         return true;
49 }
50
51 static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
52 {
53         uint32_t rid;
54         sid_peek_rid(sid, &rid);
55         return rid;
56 }
57
58 struct pdb_ads_samu_private {
59         char *dn;
60         struct tldap_message *ldapmsg;
61 };
62
63 static struct samu *pdb_ads_init_guest(TALLOC_CTX *mem_ctx,
64                                        struct pdb_methods *m)
65 {
66         struct pdb_ads_state *state = talloc_get_type_abort(
67                 m->private_data, struct pdb_ads_state);
68         struct dom_sid guest_sid;
69         struct samu *guest;
70         NTSTATUS status;
71
72         sid_compose(&guest_sid, &state->domainsid, DOMAIN_USER_RID_GUEST);
73
74         guest = samu_new(mem_ctx);
75         if (guest == NULL) {
76                 return NULL;
77         }
78
79         status = pdb_ads_getsampwsid(m, guest, &guest_sid);
80         if (!NT_STATUS_IS_OK(status)) {
81                 DEBUG(10, ("Could not init guest account: %s\n",
82                            nt_errstr(status)));
83                 TALLOC_FREE(guest);
84                 return NULL;
85         }
86         return guest;
87 }
88
89 static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
90         struct pdb_methods *m, struct samu *sam)
91 {
92         struct pdb_ads_samu_private *result;
93         uint32_t rid;
94
95         result = (struct pdb_ads_samu_private *)
96                 pdb_get_backend_private_data(sam, m);
97
98         if (result != NULL) {
99                 return talloc_get_type_abort(
100                         result, struct pdb_ads_samu_private);
101         }
102
103         /*
104          * This is now a weirdness of the passdb API. For the guest user we
105          * are not asked first.
106          */
107         sid_peek_rid(pdb_get_user_sid(sam), &rid);
108
109         if (rid == DOMAIN_USER_RID_GUEST) {
110                 struct samu *guest = pdb_ads_init_guest(talloc_tos(), m);
111
112                 if (guest == NULL) {
113                         return NULL;
114                 }
115                 result = talloc_get_type_abort(
116                         pdb_get_backend_private_data(guest, m),
117                         struct pdb_ads_samu_private);
118                 pdb_set_backend_private_data(
119                         sam, talloc_move(sam, &result), NULL, m, PDB_SET);
120                 TALLOC_FREE(guest);
121                 return talloc_get_type_abort(
122                         pdb_get_backend_private_data(sam, m),
123                         struct pdb_ads_samu_private);
124         }
125
126         return NULL;
127 }
128
129 static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m,
130                                           struct samu *sam,
131                                           struct tldap_message *entry)
132 {
133         struct pdb_ads_state *state = talloc_get_type_abort(
134                 m->private_data, struct pdb_ads_state);
135         TALLOC_CTX *frame = talloc_stackframe();
136         struct pdb_ads_samu_private *priv;
137         NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
138         char *str;
139         time_t tmp_time;
140         struct dom_sid sid;
141         uint64_t n;
142         DATA_BLOB blob;
143
144         priv = talloc(sam, struct pdb_ads_samu_private);
145         if (priv == NULL) {
146                 return NT_STATUS_NO_MEMORY;
147         }
148         if (!tldap_entry_dn(entry, &priv->dn)) {
149                 TALLOC_FREE(priv);
150                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
151         }
152
153         str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
154         if (str == NULL) {
155                 DEBUG(10, ("no samAccountName\n"));
156                 goto fail;
157         }
158         pdb_set_username(sam, str, PDB_SET);
159         TALLOC_FREE(str);
160
161         if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
162                 pdb_set_logon_time(sam, tmp_time, PDB_SET);
163         }
164         if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
165                 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
166         }
167         if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
168                 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
169         }
170         if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
171                 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
172         }
173
174         str = tldap_talloc_single_attribute(entry, "samAccoutName",
175                                             talloc_tos());
176         if (str != NULL) {
177                 pdb_set_username(sam, str, PDB_SET);
178         }
179
180         str = tldap_talloc_single_attribute(entry, "displayName",
181                                             talloc_tos());
182         if (str != NULL) {
183                 pdb_set_fullname(sam, str, PDB_SET);
184         }
185
186         str = tldap_talloc_single_attribute(entry, "homeDirectory",
187                                             talloc_tos());
188         if (str != NULL) {
189                 pdb_set_homedir(sam, str, PDB_SET);
190         }
191
192         str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
193         if (str != NULL) {
194                 pdb_set_dir_drive(sam, str, PDB_SET);
195         }
196
197         str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
198         if (str != NULL) {
199                 pdb_set_logon_script(sam, str, PDB_SET);
200         }
201
202         str = tldap_talloc_single_attribute(entry, "profilePath",
203                                             talloc_tos());
204         if (str != NULL) {
205                 pdb_set_profile_path(sam, str, PDB_SET);
206         }
207
208         str = tldap_talloc_single_attribute(entry, "profilePath",
209                                             talloc_tos());
210         if (str != NULL) {
211                 pdb_set_profile_path(sam, str, PDB_SET);
212         }
213
214         if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
215                 DEBUG(10, ("Could not pull SID\n"));
216                 goto fail;
217         }
218         pdb_set_user_sid(sam, &sid, PDB_SET);
219
220         if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
221                 DEBUG(10, ("Could not pull userAccountControl\n"));
222                 goto fail;
223         }
224         pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET);
225
226         if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
227                 if (blob.length != NT_HASH_LEN) {
228                         DEBUG(0, ("Got NT hash of length %d, expected %d\n",
229                                   (int)blob.length, NT_HASH_LEN));
230                         goto fail;
231                 }
232                 pdb_set_nt_passwd(sam, blob.data, PDB_SET);
233         }
234
235         if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
236                 if (blob.length != LM_HASH_LEN) {
237                         DEBUG(0, ("Got LM hash of length %d, expected %d\n",
238                                   (int)blob.length, LM_HASH_LEN));
239                         goto fail;
240                 }
241                 pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
242         }
243
244         if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
245                 sid_compose(&sid, &state->domainsid, n);
246                 pdb_set_group_sid(sam, &sid, PDB_SET);
247
248         }
249
250         priv->ldapmsg = talloc_move(priv, &entry);
251         pdb_set_backend_private_data(sam, priv, NULL, m, PDB_SET);
252
253         status = NT_STATUS_OK;
254 fail:
255         TALLOC_FREE(frame);
256         return status;
257 }
258
259 static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
260                                       struct tldap_message *existing,
261                                       TALLOC_CTX *mem_ctx,
262                                       int *pnum_mods, struct tldap_mod **pmods,
263                                       struct samu *sam)
264 {
265         bool ret = true;
266
267         /* TODO: All fields :-) */
268
269         ret &= tldap_make_mod_fmt(
270                 existing, mem_ctx, pnum_mods, pmods, "displayName",
271                 "%s", pdb_get_fullname(sam));
272
273         ret &= tldap_make_mod_blob(
274                 existing, mem_ctx, pnum_mods, pmods, "unicodePwd",
275                 data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN));
276
277         ret &= tldap_make_mod_blob(
278                 existing, mem_ctx, pnum_mods, pmods, "dBCSPwd",
279                 data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN));
280
281         return ret;
282 }
283
284 static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
285                                        struct pdb_ads_state *state,
286                                        struct samu *sam_acct,
287                                        const char *filter)
288 {
289         const char * attrs[] = {
290                 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
291                 "sAMAccountName", "displayName", "homeDirectory",
292                 "homeDrive", "scriptPath", "profilePath", "description",
293                 "userWorkstations", "comment", "userParameters", "objectSid",
294                 "primaryGroupID", "userAccountControl", "logonHours",
295                 "badPwdCount", "logonCount", "countryCode", "codePage",
296                 "unicodePwd", "dBCSPwd" };
297         struct tldap_message **users;
298         int rc, count;
299
300         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
301                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
302                               &users, "%s", filter);
303         if (rc != TLDAP_SUCCESS) {
304                 DEBUG(10, ("ldap_search failed %s\n",
305                            tldap_errstr(debug_ctx(), state->ld, rc)));
306                 return NT_STATUS_LDAP(rc);
307         }
308
309         count = talloc_array_length(users);
310         if (count != 1) {
311                 DEBUG(10, ("Expected 1 user, got %d\n", count));
312                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
313         }
314
315         return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]);
316 }
317
318 static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
319                                     struct samu *sam_acct,
320                                     const char *username)
321 {
322         struct pdb_ads_state *state = talloc_get_type_abort(
323                 m->private_data, struct pdb_ads_state);
324         char *filter;
325
326         filter = talloc_asprintf(
327                 talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
328                 username);
329         NT_STATUS_HAVE_NO_MEMORY(filter);
330
331         return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
332 }
333
334 static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
335                                     struct samu *sam_acct,
336                                     const DOM_SID *sid)
337 {
338         struct pdb_ads_state *state = talloc_get_type_abort(
339                 m->private_data, struct pdb_ads_state);
340         char *sidstr, *filter;
341
342         sidstr = sid_binstring(talloc_tos(), sid);
343         NT_STATUS_HAVE_NO_MEMORY(sidstr);
344
345         filter = talloc_asprintf(
346                 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
347         TALLOC_FREE(sidstr);
348         NT_STATUS_HAVE_NO_MEMORY(filter);
349
350         return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
351 }
352
353 static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
354                                     TALLOC_CTX *tmp_ctx,
355                                     const char *name, uint32 acct_flags,
356                                     uint32 *rid)
357 {
358         struct pdb_ads_state *state = talloc_get_type_abort(
359                 m->private_data, struct pdb_ads_state);
360         const char *attrs[1] = { "objectSid" };
361         struct tldap_mod *mods = NULL;
362         int num_mods = 0;
363         struct tldap_message **user;
364         struct dom_sid sid;
365         char *dn;
366         int rc;
367         bool ok;
368
369         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
370                              state->domaindn);
371         if (dn == NULL) {
372                 return NT_STATUS_NO_MEMORY;
373         }
374
375         /* TODO: Create machines etc */
376
377         ok = true;
378         ok &= tldap_make_mod_fmt(
379                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user");
380         ok &= tldap_make_mod_fmt(
381                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
382                 name);
383         if (!ok) {
384                 return NT_STATUS_NO_MEMORY;
385         }
386
387         rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
388         if (rc != TLDAP_SUCCESS) {
389                 DEBUG(10, ("ldap_add failed %s\n",
390                            tldap_errstr(debug_ctx(), state->ld, rc)));
391                 TALLOC_FREE(dn);
392                 return NT_STATUS_LDAP(rc);
393         }
394
395         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
396                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &user,
397                              "(&(objectclass=user)(samaccountname=%s))",
398                              name);
399         if (rc != TLDAP_SUCCESS) {
400                 DEBUG(10, ("Could not find just created user %s: %s\n",
401                            name, tldap_errstr(debug_ctx(), state->ld, rc)));
402                 TALLOC_FREE(dn);
403                 return NT_STATUS_LDAP(rc);
404         }
405
406         if (talloc_array_length(user) != 1) {
407                 DEBUG(10, ("Got %d users, expected one\n",
408                            (int)talloc_array_length(user)));
409                 TALLOC_FREE(dn);
410                 return NT_STATUS_LDAP(rc);
411         }
412
413         if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
414                 DEBUG(10, ("Could not fetch objectSid from user %s\n",
415                            name));
416                 TALLOC_FREE(dn);
417                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
418         }
419
420         sid_peek_rid(&sid, rid);
421         TALLOC_FREE(dn);
422         return NT_STATUS_OK;
423 }
424
425 static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
426                                     TALLOC_CTX *tmp_ctx,
427                                     struct samu *sam)
428 {
429         struct pdb_ads_state *state = talloc_get_type_abort(
430                 m->private_data, struct pdb_ads_state);
431         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
432         int rc;
433
434         rc = tldap_delete(state->ld, priv->dn, NULL, NULL);
435         if (rc != TLDAP_SUCCESS) {
436                 DEBUG(10, ("ldap_delete for %s failed: %s\n", priv->dn,
437                            tldap_errstr(debug_ctx(), state->ld, rc)));
438                 return NT_STATUS_LDAP(rc);
439         }
440         return NT_STATUS_OK;
441 }
442
443 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
444                                         struct samu *sampass)
445 {
446         return NT_STATUS_NOT_IMPLEMENTED;
447 }
448
449 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
450                                            struct samu *sam)
451 {
452         struct pdb_ads_state *state = talloc_get_type_abort(
453                 m->private_data, struct pdb_ads_state);
454         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
455         struct tldap_mod *mods = NULL;
456         int rc, num_mods = 0;
457
458         if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
459                                        &num_mods, &mods, sam)) {
460                 return NT_STATUS_NO_MEMORY;
461         }
462
463         rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, NULL);
464         if (rc != TLDAP_SUCCESS) {
465                 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
466                            tldap_errstr(debug_ctx(), state->ld, rc)));
467                 return NT_STATUS_LDAP(rc);
468         }
469
470         TALLOC_FREE(mods);
471
472         return NT_STATUS_OK;
473 }
474
475 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
476                                            struct samu *username)
477 {
478         return NT_STATUS_NOT_IMPLEMENTED;
479 }
480
481 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
482                                            struct samu *oldname,
483                                            const char *newname)
484 {
485         return NT_STATUS_NOT_IMPLEMENTED;
486 }
487
488 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
489                                               struct samu *sam_acct,
490                                               bool success)
491 {
492         return NT_STATUS_NOT_IMPLEMENTED;
493 }
494
495 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
496                                     const char *filter)
497 {
498         struct pdb_ads_state *state = talloc_get_type_abort(
499                 m->private_data, struct pdb_ads_state);
500         const char *attrs[4] = { "objectSid", "description", "samAccountName",
501                                  "groupType" };
502         char *str;
503         struct tldap_message **group;
504         uint32_t grouptype;
505         int rc;
506
507         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
508                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
509                               &group, "%s", filter);
510         if (rc != TLDAP_SUCCESS) {
511                 DEBUG(10, ("ldap_search failed %s\n",
512                            tldap_errstr(debug_ctx(), state->ld, rc)));
513                 return NT_STATUS_LDAP(rc);
514         }
515         if (talloc_array_length(group) != 1) {
516                 DEBUG(10, ("Expected 1 user, got %d\n",
517                            (int)talloc_array_length(group)));
518                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
519         }
520
521         if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
522                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
523         }
524         map->gid = pdb_ads_sid2gid(&map->sid);
525
526         if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
527                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
528         }
529         switch (grouptype) {
530         case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
531         case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
532                 map->sid_name_use = SID_NAME_ALIAS;
533                 break;
534         case GTYPE_SECURITY_GLOBAL_GROUP:
535                 map->sid_name_use = SID_NAME_DOM_GRP;
536                 break;
537         default:
538                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
539         }
540
541         str = tldap_talloc_single_attribute(group[0], "samAccountName",
542                                             talloc_tos());
543         if (str == NULL) {
544                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
545         }
546         fstrcpy(map->nt_name, str);
547         TALLOC_FREE(str);
548
549         str = tldap_talloc_single_attribute(group[0], "description",
550                                             talloc_tos());
551         if (str != NULL) {
552                 fstrcpy(map->comment, str);
553                 TALLOC_FREE(str);
554         } else {
555                 map->comment[0] = '\0';
556         }
557
558         TALLOC_FREE(group);
559         return NT_STATUS_OK;
560 }
561
562 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
563                                  DOM_SID sid)
564 {
565         char *filter;
566         NTSTATUS status;
567
568         filter = talloc_asprintf(talloc_tos(),
569                                  "(&(objectsid=%s)(objectclass=group))",
570                                  sid_string_talloc(talloc_tos(), &sid));
571         if (filter == NULL) {
572                 return NT_STATUS_NO_MEMORY;
573         }
574
575         status = pdb_ads_getgrfilter(m, map, filter);
576         TALLOC_FREE(filter);
577         return status;
578 }
579
580 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
581                                  gid_t gid)
582 {
583         struct dom_sid sid;
584         pdb_ads_gid_to_sid(m, gid, &sid);
585         return pdb_ads_getgrsid(m, map, sid);
586 }
587
588 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
589                                  const char *name)
590 {
591         char *filter;
592         NTSTATUS status;
593
594         filter = talloc_asprintf(talloc_tos(),
595                                  "(&(samaccountname=%s)(objectclass=group))",
596                                  name);
597         if (filter == NULL) {
598                 return NT_STATUS_NO_MEMORY;
599         }
600
601         status = pdb_ads_getgrfilter(m, map, filter);
602         TALLOC_FREE(filter);
603         return status;
604 }
605
606 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
607                                          TALLOC_CTX *mem_ctx, const char *name,
608                                          uint32 *rid)
609 {
610         TALLOC_CTX *frame = talloc_stackframe();
611         struct pdb_ads_state *state = talloc_get_type_abort(
612                 m->private_data, struct pdb_ads_state);
613         const char *attrs[1] = { "objectSid" };
614         int num_mods = 0;
615         struct tldap_mod *mods = NULL;
616         struct tldap_message **alias;
617         struct dom_sid sid;
618         char *dn;
619         int rc;
620         bool ok = true;
621
622         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
623                              state->domaindn);
624         if (dn == NULL) {
625                 TALLOC_FREE(frame);
626                 return NT_STATUS_NO_MEMORY;
627         }
628
629         ok &= tldap_make_mod_fmt(
630                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
631                 name);
632         ok &= tldap_make_mod_fmt(
633                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
634         ok &= tldap_make_mod_fmt(
635                 NULL, talloc_tos(), &num_mods, &mods, "groupType",
636                 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
637
638         if (!ok) {
639                 TALLOC_FREE(frame);
640                 return NT_STATUS_NO_MEMORY;
641         }
642
643         rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
644         if (rc != TLDAP_SUCCESS) {
645                 DEBUG(10, ("ldap_add failed %s\n",
646                            tldap_errstr(debug_ctx(), state->ld, rc)));
647                 TALLOC_FREE(frame);
648                 return NT_STATUS_LDAP(rc);
649         }
650
651         rc = tldap_search_fmt(
652                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
653                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
654                 "(&(objectclass=group)(samaccountname=%s))", name);
655         if (rc != TLDAP_SUCCESS) {
656                 DEBUG(10, ("Could not find just created alias %s: %s\n",
657                            name, tldap_errstr(debug_ctx(), state->ld, rc)));
658                 TALLOC_FREE(frame);
659                 return NT_STATUS_LDAP(rc);
660         }
661
662         if (talloc_array_length(alias) != 1) {
663                 DEBUG(10, ("Got %d alias, expected one\n",
664                            (int)talloc_array_length(alias)));
665                 TALLOC_FREE(frame);
666                 return NT_STATUS_LDAP(rc);
667         }
668
669         if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
670                 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
671                            name));
672                 TALLOC_FREE(frame);
673                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
674         }
675
676         sid_peek_rid(&sid, rid);
677         TALLOC_FREE(frame);
678         return NT_STATUS_OK;
679 }
680
681 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
682                                          TALLOC_CTX *mem_ctx, uint32 rid)
683 {
684         return NT_STATUS_NOT_IMPLEMENTED;
685 }
686
687 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
688                                                 GROUP_MAP *map)
689 {
690         return NT_STATUS_NOT_IMPLEMENTED;
691 }
692
693 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
694                                                    GROUP_MAP *map)
695 {
696         return NT_STATUS_NOT_IMPLEMENTED;
697 }
698
699 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
700                                                    DOM_SID sid)
701 {
702         return NT_STATUS_NOT_IMPLEMENTED;
703 }
704
705 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
706                                            const DOM_SID *sid,
707                                            enum lsa_SidType sid_name_use,
708                                            GROUP_MAP **pp_rmap,
709                                            size_t *p_num_entries,
710                                            bool unix_only)
711 {
712         return NT_STATUS_NOT_IMPLEMENTED;
713 }
714
715 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
716                                            TALLOC_CTX *mem_ctx,
717                                            const DOM_SID *group,
718                                            uint32 **pmembers,
719                                            size_t *pnum_members)
720 {
721         struct pdb_ads_state *state = talloc_get_type_abort(
722                 m->private_data, struct pdb_ads_state);
723         const char *attrs[1] = { "member" };
724         char *sidstr;
725         struct tldap_message **msg;
726         int i, rc, num_members;
727         DATA_BLOB *blobs;
728         uint32_t *members;
729
730         sidstr = sid_binstring(talloc_tos(), group);
731         NT_STATUS_HAVE_NO_MEMORY(sidstr);
732
733         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
734                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
735                               "(objectsid=%s)", sidstr);
736         TALLOC_FREE(sidstr);
737         if (rc != TLDAP_SUCCESS) {
738                 DEBUG(10, ("ldap_search failed %s\n",
739                            tldap_errstr(debug_ctx(), state->ld, rc)));
740                 return NT_STATUS_LDAP(rc);
741         }
742         switch talloc_array_length(msg) {
743         case 0:
744                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
745                 break;
746         case 1:
747                 break;
748         default:
749                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
750                 break;
751         }
752
753         if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
754                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
755         }
756
757         members = talloc_array(mem_ctx, uint32_t, num_members);
758         if (members == NULL) {
759                 return NT_STATUS_NO_MEMORY;
760         }
761
762         for (i=0; i<num_members; i++) {
763                 struct dom_sid sid;
764                 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &sid)
765                     || !sid_peek_rid(&sid, &members[i])) {
766                         TALLOC_FREE(members);
767                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
768                 }
769         }
770
771         *pmembers = members;
772         *pnum_members = num_members;
773         return NT_STATUS_OK;
774 }
775
776 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
777                                                TALLOC_CTX *mem_ctx,
778                                                struct samu *user,
779                                                DOM_SID **pp_sids,
780                                                gid_t **pp_gids,
781                                                size_t *p_num_groups)
782 {
783         struct pdb_ads_state *state = talloc_get_type_abort(
784                 m->private_data, struct pdb_ads_state);
785         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
786                 m, user);
787         const char *attrs[1] = { "objectSid" };
788         struct tldap_message **groups;
789         int i, rc, count;
790         size_t num_groups;
791         struct dom_sid *group_sids;
792         gid_t *gids;
793
794         rc = tldap_search_fmt(
795                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
796                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
797                 "(&(member=%s)(grouptype=%d)(objectclass=group))",
798                 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
799         if (rc != TLDAP_SUCCESS) {
800                 DEBUG(10, ("ldap_search failed %s\n",
801                            tldap_errstr(debug_ctx(), state->ld, rc)));
802                 return NT_STATUS_LDAP(rc);
803         }
804
805         count = talloc_array_length(groups);
806
807         group_sids = talloc_array(mem_ctx, struct dom_sid, count);
808         if (group_sids == NULL) {
809                 return NT_STATUS_NO_MEMORY;
810         }
811         gids = talloc_array(mem_ctx, gid_t, count);
812         if (gids == NULL) {
813                 TALLOC_FREE(group_sids);
814                 return NT_STATUS_NO_MEMORY;
815         }
816         num_groups = 0;
817
818         for (i=0; i<count; i++) {
819                 if (!tldap_pull_binsid(groups[i], "objectSid",
820                                        &group_sids[num_groups])) {
821                         continue;
822                 }
823                 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
824
825                 num_groups += 1;
826                 if (num_groups == count) {
827                         break;
828                 }
829         }
830
831         *pp_sids = group_sids;
832         *pp_gids = gids;
833         *p_num_groups = num_groups;
834         return NT_STATUS_OK;
835 }
836
837 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
838                                                TALLOC_CTX *mem_ctx,
839                                                struct samu *user)
840 {
841         return NT_STATUS_NOT_IMPLEMENTED;
842 }
843
844 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
845                                      TALLOC_CTX *mem_ctx,
846                                      uint32 group_rid, uint32 member_rid)
847 {
848         return NT_STATUS_NOT_IMPLEMENTED;
849 }
850
851 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
852                                      TALLOC_CTX *mem_ctx,
853                                      uint32 group_rid, uint32 member_rid)
854 {
855         return NT_STATUS_NOT_IMPLEMENTED;
856 }
857
858 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
859                                      const char *name, uint32 *rid)
860 {
861         TALLOC_CTX *frame = talloc_stackframe();
862         struct pdb_ads_state *state = talloc_get_type_abort(
863                 m->private_data, struct pdb_ads_state);
864         const char *attrs[1] = { "objectSid" };
865         int num_mods = 0;
866         struct tldap_mod *mods = NULL;
867         struct tldap_message **alias;
868         struct dom_sid sid;
869         char *dn;
870         int rc;
871         bool ok = true;
872
873         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
874                              state->domaindn);
875         if (dn == NULL) {
876                 TALLOC_FREE(frame);
877                 return NT_STATUS_NO_MEMORY;
878         }
879
880         ok &= tldap_make_mod_fmt(
881                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
882                 name);
883         ok &= tldap_make_mod_fmt(
884                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
885         ok &= tldap_make_mod_fmt(
886                 NULL, talloc_tos(), &num_mods, &mods, "groupType",
887                 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
888
889         if (!ok) {
890                 TALLOC_FREE(frame);
891                 return NT_STATUS_NO_MEMORY;
892         }
893
894         rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
895         if (rc != TLDAP_SUCCESS) {
896                 DEBUG(10, ("ldap_add failed %s\n",
897                            tldap_errstr(debug_ctx(), state->ld, rc)));
898                 TALLOC_FREE(frame);
899                 return NT_STATUS_LDAP(rc);
900         }
901
902         rc = tldap_search_fmt(
903                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
904                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
905                 "(&(objectclass=group)(samaccountname=%s))", name);
906         if (rc != TLDAP_SUCCESS) {
907                 DEBUG(10, ("Could not find just created alias %s: %s\n",
908                            name, tldap_errstr(debug_ctx(), state->ld, rc)));
909                 TALLOC_FREE(frame);
910                 return NT_STATUS_LDAP(rc);
911         }
912
913         if (talloc_array_length(alias) != 1) {
914                 DEBUG(10, ("Got %d alias, expected one\n",
915                            (int)talloc_array_length(alias)));
916                 TALLOC_FREE(frame);
917                 return NT_STATUS_LDAP(rc);
918         }
919
920         if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
921                 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
922                            name));
923                 TALLOC_FREE(frame);
924                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
925         }
926
927         sid_peek_rid(&sid, rid);
928         TALLOC_FREE(frame);
929         return NT_STATUS_OK;
930 }
931
932 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
933                                      const DOM_SID *sid)
934 {
935         struct pdb_ads_state *state = talloc_get_type_abort(
936                 m->private_data, struct pdb_ads_state);
937         struct tldap_message **alias;
938         char *sidstr, *dn;
939         int rc;
940
941         sidstr = sid_binstring(talloc_tos(), sid);
942         if (sidstr == NULL) {
943                 return NT_STATUS_NO_MEMORY;
944         }
945
946         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
947                               NULL, 0, 0, talloc_tos(), &alias,
948                               "(&(objectSid=%s)(objectclass=group)"
949                               "(|(grouptype=%d)(grouptype=%d)))",
950                               sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
951                               GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
952         TALLOC_FREE(sidstr);
953         if (rc != TLDAP_SUCCESS) {
954                 DEBUG(10, ("ldap_search failed: %s\n",
955                            tldap_errstr(debug_ctx(), state->ld, rc)));
956                 TALLOC_FREE(dn);
957                 return NT_STATUS_LDAP(rc);
958         }
959         if (talloc_array_length(alias) != 1) {
960                 DEBUG(10, ("Expected 1 alias, got %d\n",
961                            (int)talloc_array_length(alias)));
962                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
963         }
964         if (!tldap_entry_dn(alias[0], &dn)) {
965                 DEBUG(10, ("Could not get DN for alias %s\n",
966                            sid_string_dbg(sid)));
967                 return NT_STATUS_INTERNAL_ERROR;
968         }
969
970         rc = tldap_delete(state->ld, dn, NULL, NULL);
971         if (rc != TLDAP_SUCCESS) {
972                 DEBUG(10, ("ldap_delete failed: %s\n",
973                            tldap_errstr(debug_ctx(), state->ld, rc)));
974                 TALLOC_FREE(dn);
975                 return NT_STATUS_LDAP(rc);
976         }
977
978         return NT_STATUS_OK;
979 }
980
981 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
982                                       const DOM_SID *sid,
983                                       struct acct_info *info)
984 {
985         return NT_STATUS_NOT_IMPLEMENTED;
986 }
987
988 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
989                                       const DOM_SID *sid,
990                                       struct acct_info *info)
991 {
992         return NT_STATUS_NOT_IMPLEMENTED;
993 }
994
995 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
996                                const struct dom_sid *sid,
997                                TALLOC_CTX *mem_ctx, char **pdn)
998 {
999         struct tldap_message **msg;
1000         char *sidstr, *dn;
1001         int rc;
1002
1003         sidstr = sid_binstring(talloc_tos(), sid);
1004         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1005
1006         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1007                               NULL, 0, 0, talloc_tos(), &msg,
1008                               "(objectsid=%s)", sidstr);
1009         TALLOC_FREE(sidstr);
1010         if (rc != TLDAP_SUCCESS) {
1011                 DEBUG(10, ("ldap_search failed %s\n",
1012                            tldap_errstr(debug_ctx(), state->ld, rc)));
1013                 return NT_STATUS_LDAP(rc);
1014         }
1015
1016         switch talloc_array_length(msg) {
1017         case 0:
1018                 return NT_STATUS_NOT_FOUND;
1019         case 1:
1020                 break;
1021         default:
1022                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1023         }
1024
1025         if (!tldap_entry_dn(msg[0], &dn)) {
1026                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1027         }
1028
1029         dn = talloc_strdup(mem_ctx, dn);
1030         if (dn == NULL) {
1031                 return NT_STATUS_NO_MEMORY;
1032         }
1033         TALLOC_FREE(msg);
1034
1035         *pdn = dn;
1036         return NT_STATUS_OK;
1037 }
1038
1039 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1040                                      const DOM_SID *alias,
1041                                      const DOM_SID *member,
1042                                      int mod_op)
1043 {
1044         struct pdb_ads_state *state = talloc_get_type_abort(
1045                 m->private_data, struct pdb_ads_state);
1046         TALLOC_CTX *frame = talloc_stackframe();
1047         struct tldap_mod *mods;
1048         int rc;
1049         char *aliasdn, *memberdn;
1050         NTSTATUS status;
1051
1052         status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1053         if (!NT_STATUS_IS_OK(status)) {
1054                 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1055                            sid_string_dbg(alias), nt_errstr(status)));
1056                 TALLOC_FREE(frame);
1057                 return NT_STATUS_NO_SUCH_ALIAS;
1058         }
1059         status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1060         if (!NT_STATUS_IS_OK(status)) {
1061                 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1062                            sid_string_dbg(member), nt_errstr(status)));
1063                 TALLOC_FREE(frame);
1064                 return status;
1065         }
1066
1067         mods = NULL;
1068
1069         if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1070                                "member", memberdn)) {
1071                 TALLOC_FREE(frame);
1072                 return NT_STATUS_NO_MEMORY;
1073         }
1074
1075         rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
1076         TALLOC_FREE(frame);
1077         if (rc != TLDAP_SUCCESS) {
1078                 DEBUG(10, ("ldap_modify failed: %s\n",
1079                            tldap_errstr(debug_ctx(), state->ld, rc)));
1080                 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1081                         return NT_STATUS_MEMBER_IN_ALIAS;
1082                 }
1083                 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1084                         return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1085                 }
1086                 return NT_STATUS_LDAP(rc);
1087         }
1088
1089         return NT_STATUS_OK;
1090 }
1091
1092 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1093                                      const DOM_SID *alias,
1094                                      const DOM_SID *member)
1095 {
1096         return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1097 }
1098
1099 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1100                                      const DOM_SID *alias,
1101                                      const DOM_SID *member)
1102 {
1103         return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1104 }
1105
1106 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1107                                struct dom_sid *psid)
1108 {
1109         const char *attrs[1] = { "objectSid" };
1110         struct tldap_message **msg;
1111         char *dn;
1112         size_t len;
1113         int rc;
1114         bool ret;
1115
1116         if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1117                                    dnblob->data, dnblob->length, &dn, &len,
1118                                    false)) {
1119                 return false;
1120         }
1121         rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1122                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1123                               &msg, "(objectclass=*)");
1124         TALLOC_FREE(dn);
1125         if (talloc_array_length(msg) != 1) {
1126                 DEBUG(10, ("Got %d objects, expected one\n",
1127                            (int)talloc_array_length(msg)));
1128                 TALLOC_FREE(msg);
1129                 return false;
1130         }
1131
1132         ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1133         TALLOC_FREE(msg);
1134         return ret;
1135 }
1136
1137 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1138                                       const DOM_SID *alias,
1139                                       TALLOC_CTX *mem_ctx,
1140                                       DOM_SID **pmembers,
1141                                       size_t *pnum_members)
1142 {
1143         struct pdb_ads_state *state = talloc_get_type_abort(
1144                 m->private_data, struct pdb_ads_state);
1145         const char *attrs[1] = { "member" };
1146         char *sidstr;
1147         struct tldap_message **msg;
1148         int i, rc, num_members;
1149         DATA_BLOB *blobs;
1150         struct dom_sid *members;
1151
1152         sidstr = sid_binstring(talloc_tos(), alias);
1153         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1154
1155         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1156                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1157                               "(objectsid=%s)", sidstr);
1158         TALLOC_FREE(sidstr);
1159         if (rc != TLDAP_SUCCESS) {
1160                 DEBUG(10, ("ldap_search failed %s\n",
1161                            tldap_errstr(debug_ctx(), state->ld, rc)));
1162                 return NT_STATUS_LDAP(rc);
1163         }
1164         switch talloc_array_length(msg) {
1165         case 0:
1166                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1167                 break;
1168         case 1:
1169                 break;
1170         default:
1171                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1172                 break;
1173         }
1174
1175         if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1176                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1177         }
1178
1179         members = talloc_array(mem_ctx, struct dom_sid, num_members);
1180         if (members == NULL) {
1181                 return NT_STATUS_NO_MEMORY;
1182         }
1183
1184         for (i=0; i<num_members; i++) {
1185                 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1186                         TALLOC_FREE(members);
1187                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1188                 }
1189         }
1190
1191         *pmembers = members;
1192         *pnum_members = num_members;
1193         return NT_STATUS_OK;
1194 }
1195
1196 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1197                                                TALLOC_CTX *mem_ctx,
1198                                                const DOM_SID *domain_sid,
1199                                                const DOM_SID *members,
1200                                                size_t num_members,
1201                                                uint32 **pp_alias_rids,
1202                                                size_t *p_num_alias_rids)
1203 {
1204         return NT_STATUS_NOT_IMPLEMENTED;
1205 }
1206
1207 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1208                                     const DOM_SID *domain_sid,
1209                                     int num_rids,
1210                                     uint32 *rids,
1211                                     const char **pp_names,
1212                                     enum lsa_SidType *attrs)
1213 {
1214         return NT_STATUS_NOT_IMPLEMENTED;
1215 }
1216
1217 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1218                                      const DOM_SID *domain_sid,
1219                                      int num_names,
1220                                      const char **pp_names,
1221                                      uint32 *rids,
1222                                      enum lsa_SidType *attrs)
1223 {
1224         return NT_STATUS_NOT_IMPLEMENTED;
1225 }
1226
1227 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1228                                            int policy_index, uint32 *value)
1229 {
1230         return account_policy_get(policy_index, value)
1231                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1232 }
1233
1234 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1235                                            int policy_index, uint32 value)
1236 {
1237         return account_policy_set(policy_index, value)
1238                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1239 }
1240
1241 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1242                                     time_t *seq_num)
1243 {
1244         return NT_STATUS_NOT_IMPLEMENTED;
1245 }
1246
1247 struct pdb_ads_search_state {
1248         uint32_t acct_flags;
1249         struct samr_displayentry *entries;
1250         uint32_t num_entries;
1251         ssize_t array_size;
1252         uint32_t current;
1253 };
1254
1255 static bool pdb_ads_next_entry(struct pdb_search *search,
1256                                struct samr_displayentry *entry)
1257 {
1258         struct pdb_ads_search_state *state = talloc_get_type_abort(
1259                 search->private_data, struct pdb_ads_search_state);
1260
1261         if (state->current == state->num_entries) {
1262                 return false;
1263         }
1264
1265         entry->idx = state->entries[state->current].idx;
1266         entry->rid = state->entries[state->current].rid;
1267         entry->acct_flags = state->entries[state->current].acct_flags;
1268
1269         entry->account_name = talloc_strdup(
1270                 search, state->entries[state->current].account_name);
1271         entry->fullname = talloc_strdup(
1272                 search, state->entries[state->current].fullname);
1273         entry->description = talloc_strdup(
1274                 search, state->entries[state->current].description);
1275
1276         if ((entry->account_name == NULL) || (entry->fullname == NULL)
1277             || (entry->description == NULL)) {
1278                 DEBUG(0, ("talloc_strdup failed\n"));
1279                 return false;
1280         }
1281
1282         state->current += 1;
1283         return true;
1284 }
1285
1286 static void pdb_ads_search_end(struct pdb_search *search)
1287 {
1288         struct pdb_ads_search_state *state = talloc_get_type_abort(
1289                 search->private_data, struct pdb_ads_search_state);
1290         TALLOC_FREE(state);
1291 }
1292
1293 static bool pdb_ads_search_filter(struct pdb_methods *m,
1294                                   struct pdb_search *search,
1295                                   const char *filter,
1296                                   struct pdb_ads_search_state **pstate)
1297 {
1298         struct pdb_ads_state *state = talloc_get_type_abort(
1299                 m->private_data, struct pdb_ads_state);
1300         struct pdb_ads_search_state *sstate;
1301         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1302                                  "userAccountControl", "description" };
1303         struct tldap_message **users;
1304         int i, rc, num_users;
1305
1306         sstate = talloc_zero(search, struct pdb_ads_search_state);
1307         if (sstate == NULL) {
1308                 return false;
1309         }
1310
1311         rc = tldap_search_fmt(
1312                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1313                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1314                 "%s", filter);
1315         if (rc != TLDAP_SUCCESS) {
1316                 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1317                            tldap_errstr(debug_ctx(), state->ld, rc)));
1318                 return false;
1319         }
1320
1321         num_users = talloc_array_length(users);
1322
1323         sstate->entries = talloc_array(sstate, struct samr_displayentry,
1324                                        num_users);
1325         if (sstate->entries == NULL) {
1326                 DEBUG(10, ("talloc failed\n"));
1327                 return false;
1328         }
1329
1330         sstate->num_entries = 0;
1331
1332         for (i=0; i<num_users; i++) {
1333                 struct samr_displayentry *e;
1334                 struct dom_sid sid;
1335
1336                 e = &sstate->entries[sstate->num_entries];
1337
1338                 e->idx = sstate->num_entries;
1339                 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1340                         DEBUG(10, ("Could not pull sid\n"));
1341                         continue;
1342                 }
1343                 sid_peek_rid(&sid, &e->rid);
1344                 e->acct_flags = ACB_NORMAL;
1345                 e->account_name = tldap_talloc_single_attribute(
1346                         users[i], "samAccountName", sstate->entries);
1347                 if (e->account_name == NULL) {
1348                         return false;
1349                 }
1350                 e->fullname = tldap_talloc_single_attribute(
1351                         users[i], "displayName", sstate->entries);
1352                 if (e->fullname == NULL) {
1353                         e->fullname = "";
1354                 }
1355                 e->description = tldap_talloc_single_attribute(
1356                         users[i], "description", sstate->entries);
1357                 if (e->description == NULL) {
1358                         e->description = "";
1359                 }
1360
1361                 sstate->num_entries += 1;
1362                 if (sstate->num_entries >= num_users) {
1363                         break;
1364                 }
1365         }
1366
1367         search->private_data = sstate;
1368         search->next_entry = pdb_ads_next_entry;
1369         search->search_end = pdb_ads_search_end;
1370         *pstate = sstate;
1371         return true;
1372 }
1373
1374 static bool pdb_ads_search_users(struct pdb_methods *m,
1375                                  struct pdb_search *search,
1376                                  uint32 acct_flags)
1377 {
1378         struct pdb_ads_search_state *sstate;
1379         bool ret;
1380
1381         ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1382         if (!ret) {
1383                 return false;
1384         }
1385         sstate->acct_flags = acct_flags;
1386         return true;
1387 }
1388
1389 static bool pdb_ads_search_groups(struct pdb_methods *m,
1390                                   struct pdb_search *search)
1391 {
1392         struct pdb_ads_search_state *sstate;
1393         char *filter;
1394         bool ret;
1395
1396         filter = talloc_asprintf(talloc_tos(),
1397                                  "(&(grouptype=%d)(objectclass=group))",
1398                                  GTYPE_SECURITY_GLOBAL_GROUP);
1399         if (filter == NULL) {
1400                 return false;
1401         }
1402         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1403         TALLOC_FREE(filter);
1404         if (!ret) {
1405                 return false;
1406         }
1407         sstate->acct_flags = 0;
1408         return true;
1409 }
1410
1411 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1412                                    struct pdb_search *search,
1413                                    const DOM_SID *sid)
1414 {
1415         struct pdb_ads_search_state *sstate;
1416         char *filter;
1417         bool ret;
1418
1419         filter = talloc_asprintf(
1420                 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1421                 sid_check_is_builtin(sid)
1422                 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1423                 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1424
1425         if (filter == NULL) {
1426                 return false;
1427         }
1428         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1429         TALLOC_FREE(filter);
1430         if (!ret) {
1431                 return false;
1432         }
1433         sstate->acct_flags = 0;
1434         return true;
1435 }
1436
1437 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1438                                uint32 *rid)
1439 {
1440         return false;
1441 }
1442
1443 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1444                                DOM_SID *sid)
1445 {
1446         struct pdb_ads_state *state = talloc_get_type_abort(
1447                 m->private_data, struct pdb_ads_state);
1448         sid_compose(sid, &state->domainsid, uid);
1449         return true;
1450 }
1451
1452 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1453                                DOM_SID *sid)
1454 {
1455         struct pdb_ads_state *state = talloc_get_type_abort(
1456                 m->private_data, struct pdb_ads_state);
1457         sid_compose(sid, &state->domainsid, gid);
1458         return true;
1459 }
1460
1461 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1462                               union unid_t *id, enum lsa_SidType *type)
1463 {
1464         struct pdb_ads_state *state = talloc_get_type_abort(
1465                 m->private_data, struct pdb_ads_state);
1466         struct tldap_message **msg;
1467         char *sidstr;
1468         uint32_t rid;
1469         int rc;
1470
1471         /*
1472          * This is a big, big hack: Just hard-code the rid as uid/gid.
1473          */
1474
1475         sid_peek_rid(sid, &rid);
1476
1477         sidstr = sid_binstring(talloc_tos(), sid);
1478         if (sidstr == NULL) {
1479                 return false;
1480         }
1481
1482         rc = tldap_search_fmt(
1483                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1484                 NULL, 0, 0, talloc_tos(), &msg,
1485                 "(&(objectsid=%s)(objectclass=user))", sidstr);
1486         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1487                 id->uid = rid;
1488                 *type = SID_NAME_USER;
1489                 TALLOC_FREE(sidstr);
1490                 return true;
1491         }
1492
1493         rc = tldap_search_fmt(
1494                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1495                 NULL, 0, 0, talloc_tos(), &msg,
1496                 "(&(objectsid=%s)(objectclass=group))", sidstr);
1497         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1498                 id->gid = rid;
1499                 *type = SID_NAME_DOM_GRP;
1500                 TALLOC_FREE(sidstr);
1501                 return true;
1502         }
1503
1504         TALLOC_FREE(sidstr);
1505         return false;
1506 }
1507
1508 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1509 {
1510         return false;
1511 }
1512
1513 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1514 {
1515         return false;
1516 }
1517
1518 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1519                                       const char *domain, char** pwd,
1520                                       DOM_SID *sid,
1521                                       time_t *pass_last_set_time)
1522 {
1523         return false;
1524 }
1525
1526 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1527                                       const char* domain, const char* pwd,
1528                                       const DOM_SID *sid)
1529 {
1530         return false;
1531 }
1532
1533 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1534                                       const char *domain)
1535 {
1536         return false;
1537 }
1538
1539 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1540                                          TALLOC_CTX *mem_ctx,
1541                                          uint32 *num_domains,
1542                                          struct trustdom_info ***domains)
1543 {
1544         return NT_STATUS_NOT_IMPLEMENTED;
1545 }
1546
1547 static void pdb_ads_init_methods(struct pdb_methods *m)
1548 {
1549         m->name = "ads";
1550         m->getsampwnam = pdb_ads_getsampwnam;
1551         m->getsampwsid = pdb_ads_getsampwsid;
1552         m->create_user = pdb_ads_create_user;
1553         m->delete_user = pdb_ads_delete_user;
1554         m->add_sam_account = pdb_ads_add_sam_account;
1555         m->update_sam_account = pdb_ads_update_sam_account;
1556         m->delete_sam_account = pdb_ads_delete_sam_account;
1557         m->rename_sam_account = pdb_ads_rename_sam_account;
1558         m->update_login_attempts = pdb_ads_update_login_attempts;
1559         m->getgrsid = pdb_ads_getgrsid;
1560         m->getgrgid = pdb_ads_getgrgid;
1561         m->getgrnam = pdb_ads_getgrnam;
1562         m->create_dom_group = pdb_ads_create_dom_group;
1563         m->delete_dom_group = pdb_ads_delete_dom_group;
1564         m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1565         m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1566         m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1567         m->enum_group_mapping = pdb_ads_enum_group_mapping;
1568         m->enum_group_members = pdb_ads_enum_group_members;
1569         m->enum_group_memberships = pdb_ads_enum_group_memberships;
1570         m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1571         m->add_groupmem = pdb_ads_add_groupmem;
1572         m->del_groupmem = pdb_ads_del_groupmem;
1573         m->create_alias = pdb_ads_create_alias;
1574         m->delete_alias = pdb_ads_delete_alias;
1575         m->get_aliasinfo = pdb_ads_get_aliasinfo;
1576         m->set_aliasinfo = pdb_ads_set_aliasinfo;
1577         m->add_aliasmem = pdb_ads_add_aliasmem;
1578         m->del_aliasmem = pdb_ads_del_aliasmem;
1579         m->enum_aliasmem = pdb_ads_enum_aliasmem;
1580         m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1581         m->lookup_rids = pdb_ads_lookup_rids;
1582         m->lookup_names = pdb_ads_lookup_names;
1583         m->get_account_policy = pdb_ads_get_account_policy;
1584         m->set_account_policy = pdb_ads_set_account_policy;
1585         m->get_seq_num = pdb_ads_get_seq_num;
1586         m->search_users = pdb_ads_search_users;
1587         m->search_groups = pdb_ads_search_groups;
1588         m->search_aliases = pdb_ads_search_aliases;
1589         m->uid_to_rid = pdb_ads_uid_to_rid;
1590         m->uid_to_sid = pdb_ads_uid_to_sid;
1591         m->gid_to_sid = pdb_ads_gid_to_sid;
1592         m->sid_to_id = pdb_ads_sid_to_id;
1593         m->rid_algorithm = pdb_ads_rid_algorithm;
1594         m->new_rid = pdb_ads_new_rid;
1595         m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1596         m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1597         m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1598         m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1599 }
1600
1601 static void free_private_data(void **vp)
1602 {
1603         struct pdb_ads_state *state = talloc_get_type_abort(
1604                 *vp, struct pdb_ads_state);
1605
1606         TALLOC_FREE(state->ld);
1607         return;
1608 }
1609
1610 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1611                                 const char *location)
1612 {
1613         const char *rootdse_attrs[2] = {
1614                 "defaultNamingContext", "configurationNamingContext" };
1615         const char *domain_attrs[1] = { "objectSid" };
1616         const char *ncname_attrs[1] = { "netbiosname" };
1617         struct tldap_message **rootdse, **domain, **ncname;
1618         TALLOC_CTX *frame = talloc_stackframe();
1619         struct sockaddr_un sunaddr;
1620         NTSTATUS status;
1621         int num_domains;
1622         int fd, rc;
1623
1624         ZERO_STRUCT(sunaddr);
1625         sunaddr.sun_family = AF_UNIX;
1626         strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1627
1628         status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1629                                  0, 0, &fd);
1630         if (!NT_STATUS_IS_OK(status)) {
1631                 DEBUG(10, ("Could not connect to %s: %s\n", location,
1632                            nt_errstr(status)));
1633                 goto done;
1634         }
1635
1636         state->ld = tldap_context_create(state, fd);
1637         if (state->ld == NULL) {
1638                 close(fd);
1639                 status = NT_STATUS_NO_MEMORY;
1640                 goto done;
1641         }
1642
1643         rc = tldap_search_fmt(
1644                 state->ld, "", TLDAP_SCOPE_BASE,
1645                 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1646                 talloc_tos(), &rootdse, "(objectclass=*)");
1647         if (rc != TLDAP_SUCCESS) {
1648                 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1649                            tldap_errstr(debug_ctx(), state->ld, rc)));
1650                 status = NT_STATUS_LDAP(rc);
1651                 goto done;
1652         }
1653         if (talloc_array_length(rootdse) != 1) {
1654                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1655                 goto done;
1656         }
1657
1658         state->domaindn = tldap_talloc_single_attribute(
1659                 rootdse[0], "defaultNamingContext", state);
1660         if (state->domaindn == NULL) {
1661                 DEBUG(10, ("Could not get defaultNamingContext\n"));
1662                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1663                 goto done;
1664         }
1665         DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1666
1667         state->configdn = tldap_talloc_single_attribute(
1668                 rootdse[0], "configurationNamingContext", state);
1669         if (state->domaindn == NULL) {
1670                 DEBUG(10, ("Could not get configurationNamingContext\n"));
1671                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1672                 goto done;
1673         }
1674         DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1675
1676         /*
1677          * Figure out our domain's SID
1678          */
1679         rc = tldap_search_fmt(
1680                 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1681                 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1682                 talloc_tos(), &domain, "(objectclass=*)");
1683         if (rc != TLDAP_SUCCESS) {
1684                 DEBUG(10, ("Could not retrieve domain: %s\n",
1685                            tldap_errstr(debug_ctx(), state->ld, rc)));
1686                 status = NT_STATUS_LDAP(rc);
1687                 goto done;
1688         }
1689
1690         num_domains = talloc_array_length(domain);
1691         if (num_domains != 1) {
1692                 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1693                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1694                 goto done;
1695         }
1696         if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1697                 DEBUG(10, ("Could not retrieve domain SID\n"));
1698                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1699                 goto done;
1700         }
1701         DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1702
1703         /*
1704          * Figure out our domain's short name
1705          */
1706         rc = tldap_search_fmt(
1707                 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1708                 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1709                 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1710         if (rc != TLDAP_SUCCESS) {
1711                 DEBUG(10, ("Could not retrieve ncname: %s\n",
1712                            tldap_errstr(debug_ctx(), state->ld, rc)));
1713                 status = NT_STATUS_LDAP(rc);
1714                 goto done;
1715         }
1716         if (talloc_array_length(ncname) != 1) {
1717                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1718                 goto done;
1719         }
1720
1721         state->netbiosname = tldap_talloc_single_attribute(
1722                 ncname[0], "netbiosname", state);
1723         if (state->netbiosname == NULL) {
1724                 DEBUG(10, ("Could not get netbiosname\n"));
1725                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1726                 goto done;
1727         }
1728         DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1729
1730         if (!strequal(lp_workgroup(), state->netbiosname)) {
1731                 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1732                           state->netbiosname, lp_workgroup()));
1733                 status = NT_STATUS_NO_SUCH_DOMAIN;
1734                 goto done;
1735         }
1736
1737         secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1738
1739         status = NT_STATUS_OK;
1740 done:
1741         TALLOC_FREE(frame);
1742         return status;
1743 }
1744
1745 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1746                              const char *location)
1747 {
1748         struct pdb_methods *m;
1749         struct pdb_ads_state *state;
1750         char *tmp = NULL;
1751         NTSTATUS status;
1752
1753         m = talloc(talloc_autofree_context(), struct pdb_methods);
1754         if (m == NULL) {
1755                 return NT_STATUS_NO_MEMORY;
1756         }
1757         state = talloc(m, struct pdb_ads_state);
1758         if (state == NULL) {
1759                 goto nomem;
1760         }
1761         m->private_data = state;
1762         m->free_private_data = free_private_data;
1763         pdb_ads_init_methods(m);
1764
1765         if (location == NULL) {
1766                 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1767                                       lp_private_dir());
1768                 location = tmp;
1769         }
1770         if (location == NULL) {
1771                 goto nomem;
1772         }
1773
1774         status = pdb_ads_connect(state, location);
1775         if (!NT_STATUS_IS_OK(status)) {
1776                 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1777                 goto fail;
1778         }
1779
1780         *pdb_method = m;
1781         return NT_STATUS_OK;
1782 nomem:
1783         status = NT_STATUS_NO_MEMORY;
1784 fail:
1785         TALLOC_FREE(m);
1786         return status;
1787 }
1788
1789 NTSTATUS pdb_ads_init(void);
1790 NTSTATUS pdb_ads_init(void)
1791 {
1792         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
1793                                    pdb_init_ads);
1794 }