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