9753cdf712ed2d27b2a26af84f473ba8d04af7dd
[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         return NT_STATUS_NOT_IMPLEMENTED;
1115 }
1116
1117 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1118                                const struct dom_sid *sid,
1119                                TALLOC_CTX *mem_ctx, char **pdn)
1120 {
1121         struct tldap_message **msg;
1122         char *sidstr, *dn;
1123         int rc;
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                               NULL, 0, 0, talloc_tos(), &msg,
1130                               "(objectsid=%s)", sidstr);
1131         TALLOC_FREE(sidstr);
1132         if (rc != TLDAP_SUCCESS) {
1133                 DEBUG(10, ("ldap_search failed %s\n",
1134                            tldap_errstr(debug_ctx(), state->ld, rc)));
1135                 return NT_STATUS_LDAP(rc);
1136         }
1137
1138         switch talloc_array_length(msg) {
1139         case 0:
1140                 return NT_STATUS_NOT_FOUND;
1141         case 1:
1142                 break;
1143         default:
1144                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1145         }
1146
1147         if (!tldap_entry_dn(msg[0], &dn)) {
1148                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1149         }
1150
1151         dn = talloc_strdup(mem_ctx, dn);
1152         if (dn == NULL) {
1153                 return NT_STATUS_NO_MEMORY;
1154         }
1155         TALLOC_FREE(msg);
1156
1157         *pdn = dn;
1158         return NT_STATUS_OK;
1159 }
1160
1161 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1162                                      const DOM_SID *alias,
1163                                      const DOM_SID *member,
1164                                      int mod_op)
1165 {
1166         struct pdb_ads_state *state = talloc_get_type_abort(
1167                 m->private_data, struct pdb_ads_state);
1168         TALLOC_CTX *frame = talloc_stackframe();
1169         struct tldap_mod *mods;
1170         int rc;
1171         char *aliasdn, *memberdn;
1172         NTSTATUS status;
1173
1174         status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1175         if (!NT_STATUS_IS_OK(status)) {
1176                 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1177                            sid_string_dbg(alias), nt_errstr(status)));
1178                 TALLOC_FREE(frame);
1179                 return NT_STATUS_NO_SUCH_ALIAS;
1180         }
1181         status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1182         if (!NT_STATUS_IS_OK(status)) {
1183                 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1184                            sid_string_dbg(member), nt_errstr(status)));
1185                 TALLOC_FREE(frame);
1186                 return status;
1187         }
1188
1189         mods = NULL;
1190
1191         if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1192                                "member", memberdn)) {
1193                 TALLOC_FREE(frame);
1194                 return NT_STATUS_NO_MEMORY;
1195         }
1196
1197         rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
1198         TALLOC_FREE(frame);
1199         if (rc != TLDAP_SUCCESS) {
1200                 DEBUG(10, ("ldap_modify failed: %s\n",
1201                            tldap_errstr(debug_ctx(), state->ld, rc)));
1202                 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1203                         return NT_STATUS_MEMBER_IN_ALIAS;
1204                 }
1205                 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1206                         return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1207                 }
1208                 return NT_STATUS_LDAP(rc);
1209         }
1210
1211         return NT_STATUS_OK;
1212 }
1213
1214 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1215                                      const DOM_SID *alias,
1216                                      const DOM_SID *member)
1217 {
1218         return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1219 }
1220
1221 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1222                                      const DOM_SID *alias,
1223                                      const DOM_SID *member)
1224 {
1225         return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1226 }
1227
1228 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1229                                struct dom_sid *psid)
1230 {
1231         const char *attrs[1] = { "objectSid" };
1232         struct tldap_message **msg;
1233         char *dn;
1234         size_t len;
1235         int rc;
1236         bool ret;
1237
1238         if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1239                                    dnblob->data, dnblob->length, &dn, &len,
1240                                    false)) {
1241                 return false;
1242         }
1243         rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1244                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1245                               &msg, "(objectclass=*)");
1246         TALLOC_FREE(dn);
1247         if (talloc_array_length(msg) != 1) {
1248                 DEBUG(10, ("Got %d objects, expected one\n",
1249                            (int)talloc_array_length(msg)));
1250                 TALLOC_FREE(msg);
1251                 return false;
1252         }
1253
1254         ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1255         TALLOC_FREE(msg);
1256         return ret;
1257 }
1258
1259 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1260                                       const DOM_SID *alias,
1261                                       TALLOC_CTX *mem_ctx,
1262                                       DOM_SID **pmembers,
1263                                       size_t *pnum_members)
1264 {
1265         struct pdb_ads_state *state = talloc_get_type_abort(
1266                 m->private_data, struct pdb_ads_state);
1267         const char *attrs[1] = { "member" };
1268         char *sidstr;
1269         struct tldap_message **msg;
1270         int i, rc, num_members;
1271         DATA_BLOB *blobs;
1272         struct dom_sid *members;
1273
1274         sidstr = sid_binstring(talloc_tos(), alias);
1275         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1276
1277         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1278                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1279                               "(objectsid=%s)", sidstr);
1280         TALLOC_FREE(sidstr);
1281         if (rc != TLDAP_SUCCESS) {
1282                 DEBUG(10, ("ldap_search failed %s\n",
1283                            tldap_errstr(debug_ctx(), state->ld, rc)));
1284                 return NT_STATUS_LDAP(rc);
1285         }
1286         switch talloc_array_length(msg) {
1287         case 0:
1288                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1289                 break;
1290         case 1:
1291                 break;
1292         default:
1293                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1294                 break;
1295         }
1296
1297         if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1298                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1299         }
1300
1301         members = talloc_array(mem_ctx, struct dom_sid, num_members);
1302         if (members == NULL) {
1303                 return NT_STATUS_NO_MEMORY;
1304         }
1305
1306         for (i=0; i<num_members; i++) {
1307                 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1308                         TALLOC_FREE(members);
1309                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1310                 }
1311         }
1312
1313         *pmembers = members;
1314         *pnum_members = num_members;
1315         return NT_STATUS_OK;
1316 }
1317
1318 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1319                                                TALLOC_CTX *mem_ctx,
1320                                                const DOM_SID *domain_sid,
1321                                                const DOM_SID *members,
1322                                                size_t num_members,
1323                                                uint32 **pp_alias_rids,
1324                                                size_t *p_num_alias_rids)
1325 {
1326         return NT_STATUS_NOT_IMPLEMENTED;
1327 }
1328
1329 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1330                                     const DOM_SID *domain_sid,
1331                                     int num_rids,
1332                                     uint32 *rids,
1333                                     const char **names,
1334                                     enum lsa_SidType *lsa_attrs)
1335 {
1336         struct pdb_ads_state *state = talloc_get_type_abort(
1337                 m->private_data, struct pdb_ads_state);
1338         const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
1339         int i, num_mapped;
1340
1341         if (num_rids == 0) {
1342                 return NT_STATUS_NONE_MAPPED;
1343         }
1344
1345         num_mapped = 0;
1346
1347         for (i=0; i<num_rids; i++) {
1348                 struct dom_sid sid;
1349                 struct tldap_message **msg;
1350                 char *sidstr;
1351                 uint32_t attr;
1352                 int rc;
1353
1354                 lsa_attrs[i] = SID_NAME_UNKNOWN;
1355
1356                 sid_compose(&sid, domain_sid, rids[i]);
1357
1358                 sidstr = sid_binstring(talloc_tos(), &sid);
1359                 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1360
1361                 rc = tldap_search_fmt(state->ld, state->domaindn,
1362                                       TLDAP_SCOPE_SUB, attrs,
1363                                       ARRAY_SIZE(attrs), 0, talloc_tos(),
1364                                       &msg, "(objectsid=%s)", sidstr);
1365                 TALLOC_FREE(sidstr);
1366                 if (rc != TLDAP_SUCCESS) {
1367                         DEBUG(10, ("ldap_search failed %s\n",
1368                                    tldap_errstr(debug_ctx(), state->ld, rc)));
1369                         continue;
1370                 }
1371
1372                 switch talloc_array_length(msg) {
1373                 case 0:
1374                         DEBUG(10, ("rid %d not found\n", (int)rids[i]));
1375                         continue;
1376                 case 1:
1377                         break;
1378                 default:
1379                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1380                 }
1381
1382                 names[i] = tldap_talloc_single_attribute(
1383                         msg[0], "samAccountName", talloc_tos());
1384                 if (names[i] == NULL) {
1385                         DEBUG(10, ("no samAccountName\n"));
1386                         continue;
1387                 }
1388                 if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
1389                         DEBUG(10, ("no samAccountType"));
1390                         continue;
1391                 }
1392                 lsa_attrs[i] = ads_atype_map(attr);
1393                 num_mapped += 1;
1394         }
1395
1396         if (num_mapped == 0) {
1397                 return NT_STATUS_NONE_MAPPED;
1398         }
1399         if (num_mapped < num_rids) {
1400                 return STATUS_SOME_UNMAPPED;
1401         }
1402         return NT_STATUS_OK;
1403 }
1404
1405 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1406                                      const DOM_SID *domain_sid,
1407                                      int num_names,
1408                                      const char **pp_names,
1409                                      uint32 *rids,
1410                                      enum lsa_SidType *attrs)
1411 {
1412         return NT_STATUS_NOT_IMPLEMENTED;
1413 }
1414
1415 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1416                                            int policy_index, uint32 *value)
1417 {
1418         return account_policy_get(policy_index, value)
1419                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1420 }
1421
1422 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1423                                            int policy_index, uint32 value)
1424 {
1425         return account_policy_set(policy_index, value)
1426                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1427 }
1428
1429 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1430                                     time_t *seq_num)
1431 {
1432         return NT_STATUS_NOT_IMPLEMENTED;
1433 }
1434
1435 struct pdb_ads_search_state {
1436         uint32_t acct_flags;
1437         struct samr_displayentry *entries;
1438         uint32_t num_entries;
1439         ssize_t array_size;
1440         uint32_t current;
1441 };
1442
1443 static bool pdb_ads_next_entry(struct pdb_search *search,
1444                                struct samr_displayentry *entry)
1445 {
1446         struct pdb_ads_search_state *state = talloc_get_type_abort(
1447                 search->private_data, struct pdb_ads_search_state);
1448
1449         if (state->current == state->num_entries) {
1450                 return false;
1451         }
1452
1453         entry->idx = state->entries[state->current].idx;
1454         entry->rid = state->entries[state->current].rid;
1455         entry->acct_flags = state->entries[state->current].acct_flags;
1456
1457         entry->account_name = talloc_strdup(
1458                 search, state->entries[state->current].account_name);
1459         entry->fullname = talloc_strdup(
1460                 search, state->entries[state->current].fullname);
1461         entry->description = talloc_strdup(
1462                 search, state->entries[state->current].description);
1463
1464         if ((entry->account_name == NULL) || (entry->fullname == NULL)
1465             || (entry->description == NULL)) {
1466                 DEBUG(0, ("talloc_strdup failed\n"));
1467                 return false;
1468         }
1469
1470         state->current += 1;
1471         return true;
1472 }
1473
1474 static void pdb_ads_search_end(struct pdb_search *search)
1475 {
1476         struct pdb_ads_search_state *state = talloc_get_type_abort(
1477                 search->private_data, struct pdb_ads_search_state);
1478         TALLOC_FREE(state);
1479 }
1480
1481 static bool pdb_ads_search_filter(struct pdb_methods *m,
1482                                   struct pdb_search *search,
1483                                   const char *filter,
1484                                   struct pdb_ads_search_state **pstate)
1485 {
1486         struct pdb_ads_state *state = talloc_get_type_abort(
1487                 m->private_data, struct pdb_ads_state);
1488         struct pdb_ads_search_state *sstate;
1489         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1490                                  "userAccountControl", "description" };
1491         struct tldap_message **users;
1492         int i, rc, num_users;
1493
1494         sstate = talloc_zero(search, struct pdb_ads_search_state);
1495         if (sstate == NULL) {
1496                 return false;
1497         }
1498
1499         rc = tldap_search_fmt(
1500                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1501                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1502                 "%s", filter);
1503         if (rc != TLDAP_SUCCESS) {
1504                 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1505                            tldap_errstr(debug_ctx(), state->ld, rc)));
1506                 return false;
1507         }
1508
1509         num_users = talloc_array_length(users);
1510
1511         sstate->entries = talloc_array(sstate, struct samr_displayentry,
1512                                        num_users);
1513         if (sstate->entries == NULL) {
1514                 DEBUG(10, ("talloc failed\n"));
1515                 return false;
1516         }
1517
1518         sstate->num_entries = 0;
1519
1520         for (i=0; i<num_users; i++) {
1521                 struct samr_displayentry *e;
1522                 struct dom_sid sid;
1523
1524                 e = &sstate->entries[sstate->num_entries];
1525
1526                 e->idx = sstate->num_entries;
1527                 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1528                         DEBUG(10, ("Could not pull sid\n"));
1529                         continue;
1530                 }
1531                 sid_peek_rid(&sid, &e->rid);
1532                 e->acct_flags = ACB_NORMAL;
1533                 e->account_name = tldap_talloc_single_attribute(
1534                         users[i], "samAccountName", sstate->entries);
1535                 if (e->account_name == NULL) {
1536                         return false;
1537                 }
1538                 e->fullname = tldap_talloc_single_attribute(
1539                         users[i], "displayName", sstate->entries);
1540                 if (e->fullname == NULL) {
1541                         e->fullname = "";
1542                 }
1543                 e->description = tldap_talloc_single_attribute(
1544                         users[i], "description", sstate->entries);
1545                 if (e->description == NULL) {
1546                         e->description = "";
1547                 }
1548
1549                 sstate->num_entries += 1;
1550                 if (sstate->num_entries >= num_users) {
1551                         break;
1552                 }
1553         }
1554
1555         search->private_data = sstate;
1556         search->next_entry = pdb_ads_next_entry;
1557         search->search_end = pdb_ads_search_end;
1558         *pstate = sstate;
1559         return true;
1560 }
1561
1562 static bool pdb_ads_search_users(struct pdb_methods *m,
1563                                  struct pdb_search *search,
1564                                  uint32 acct_flags)
1565 {
1566         struct pdb_ads_search_state *sstate;
1567         bool ret;
1568
1569         ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1570         if (!ret) {
1571                 return false;
1572         }
1573         sstate->acct_flags = acct_flags;
1574         return true;
1575 }
1576
1577 static bool pdb_ads_search_groups(struct pdb_methods *m,
1578                                   struct pdb_search *search)
1579 {
1580         struct pdb_ads_search_state *sstate;
1581         char *filter;
1582         bool ret;
1583
1584         filter = talloc_asprintf(talloc_tos(),
1585                                  "(&(grouptype=%d)(objectclass=group))",
1586                                  GTYPE_SECURITY_GLOBAL_GROUP);
1587         if (filter == NULL) {
1588                 return false;
1589         }
1590         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1591         TALLOC_FREE(filter);
1592         if (!ret) {
1593                 return false;
1594         }
1595         sstate->acct_flags = 0;
1596         return true;
1597 }
1598
1599 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1600                                    struct pdb_search *search,
1601                                    const DOM_SID *sid)
1602 {
1603         struct pdb_ads_search_state *sstate;
1604         char *filter;
1605         bool ret;
1606
1607         filter = talloc_asprintf(
1608                 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1609                 sid_check_is_builtin(sid)
1610                 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1611                 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1612
1613         if (filter == NULL) {
1614                 return false;
1615         }
1616         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1617         TALLOC_FREE(filter);
1618         if (!ret) {
1619                 return false;
1620         }
1621         sstate->acct_flags = 0;
1622         return true;
1623 }
1624
1625 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1626                                uint32 *rid)
1627 {
1628         return false;
1629 }
1630
1631 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1632                                DOM_SID *sid)
1633 {
1634         struct pdb_ads_state *state = talloc_get_type_abort(
1635                 m->private_data, struct pdb_ads_state);
1636         sid_compose(sid, &state->domainsid, uid);
1637         return true;
1638 }
1639
1640 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1641                                DOM_SID *sid)
1642 {
1643         struct pdb_ads_state *state = talloc_get_type_abort(
1644                 m->private_data, struct pdb_ads_state);
1645         sid_compose(sid, &state->domainsid, gid);
1646         return true;
1647 }
1648
1649 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1650                               union unid_t *id, enum lsa_SidType *type)
1651 {
1652         struct pdb_ads_state *state = talloc_get_type_abort(
1653                 m->private_data, struct pdb_ads_state);
1654         struct tldap_message **msg;
1655         char *sidstr;
1656         uint32_t rid;
1657         int rc;
1658
1659         /*
1660          * This is a big, big hack: Just hard-code the rid as uid/gid.
1661          */
1662
1663         sid_peek_rid(sid, &rid);
1664
1665         sidstr = sid_binstring(talloc_tos(), sid);
1666         if (sidstr == NULL) {
1667                 return false;
1668         }
1669
1670         rc = tldap_search_fmt(
1671                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1672                 NULL, 0, 0, talloc_tos(), &msg,
1673                 "(&(objectsid=%s)(objectclass=user))", sidstr);
1674         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1675                 id->uid = rid;
1676                 *type = SID_NAME_USER;
1677                 TALLOC_FREE(sidstr);
1678                 return true;
1679         }
1680
1681         rc = tldap_search_fmt(
1682                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1683                 NULL, 0, 0, talloc_tos(), &msg,
1684                 "(&(objectsid=%s)(objectclass=group))", sidstr);
1685         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1686                 id->gid = rid;
1687                 *type = SID_NAME_DOM_GRP;
1688                 TALLOC_FREE(sidstr);
1689                 return true;
1690         }
1691
1692         TALLOC_FREE(sidstr);
1693         return false;
1694 }
1695
1696 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1697 {
1698         return false;
1699 }
1700
1701 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1702 {
1703         return false;
1704 }
1705
1706 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1707                                       const char *domain, char** pwd,
1708                                       DOM_SID *sid,
1709                                       time_t *pass_last_set_time)
1710 {
1711         return false;
1712 }
1713
1714 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1715                                       const char* domain, const char* pwd,
1716                                       const DOM_SID *sid)
1717 {
1718         return false;
1719 }
1720
1721 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1722                                       const char *domain)
1723 {
1724         return false;
1725 }
1726
1727 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1728                                          TALLOC_CTX *mem_ctx,
1729                                          uint32 *num_domains,
1730                                          struct trustdom_info ***domains)
1731 {
1732         return NT_STATUS_NOT_IMPLEMENTED;
1733 }
1734
1735 static void pdb_ads_init_methods(struct pdb_methods *m)
1736 {
1737         m->name = "ads";
1738         m->getsampwnam = pdb_ads_getsampwnam;
1739         m->getsampwsid = pdb_ads_getsampwsid;
1740         m->create_user = pdb_ads_create_user;
1741         m->delete_user = pdb_ads_delete_user;
1742         m->add_sam_account = pdb_ads_add_sam_account;
1743         m->update_sam_account = pdb_ads_update_sam_account;
1744         m->delete_sam_account = pdb_ads_delete_sam_account;
1745         m->rename_sam_account = pdb_ads_rename_sam_account;
1746         m->update_login_attempts = pdb_ads_update_login_attempts;
1747         m->getgrsid = pdb_ads_getgrsid;
1748         m->getgrgid = pdb_ads_getgrgid;
1749         m->getgrnam = pdb_ads_getgrnam;
1750         m->create_dom_group = pdb_ads_create_dom_group;
1751         m->delete_dom_group = pdb_ads_delete_dom_group;
1752         m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1753         m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1754         m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1755         m->enum_group_mapping = pdb_ads_enum_group_mapping;
1756         m->enum_group_members = pdb_ads_enum_group_members;
1757         m->enum_group_memberships = pdb_ads_enum_group_memberships;
1758         m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1759         m->add_groupmem = pdb_ads_add_groupmem;
1760         m->del_groupmem = pdb_ads_del_groupmem;
1761         m->create_alias = pdb_ads_create_alias;
1762         m->delete_alias = pdb_ads_delete_alias;
1763         m->get_aliasinfo = pdb_default_get_aliasinfo;
1764         m->set_aliasinfo = pdb_ads_set_aliasinfo;
1765         m->add_aliasmem = pdb_ads_add_aliasmem;
1766         m->del_aliasmem = pdb_ads_del_aliasmem;
1767         m->enum_aliasmem = pdb_ads_enum_aliasmem;
1768         m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1769         m->lookup_rids = pdb_ads_lookup_rids;
1770         m->lookup_names = pdb_ads_lookup_names;
1771         m->get_account_policy = pdb_ads_get_account_policy;
1772         m->set_account_policy = pdb_ads_set_account_policy;
1773         m->get_seq_num = pdb_ads_get_seq_num;
1774         m->search_users = pdb_ads_search_users;
1775         m->search_groups = pdb_ads_search_groups;
1776         m->search_aliases = pdb_ads_search_aliases;
1777         m->uid_to_rid = pdb_ads_uid_to_rid;
1778         m->uid_to_sid = pdb_ads_uid_to_sid;
1779         m->gid_to_sid = pdb_ads_gid_to_sid;
1780         m->sid_to_id = pdb_ads_sid_to_id;
1781         m->rid_algorithm = pdb_ads_rid_algorithm;
1782         m->new_rid = pdb_ads_new_rid;
1783         m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1784         m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1785         m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1786         m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1787 }
1788
1789 static void free_private_data(void **vp)
1790 {
1791         struct pdb_ads_state *state = talloc_get_type_abort(
1792                 *vp, struct pdb_ads_state);
1793
1794         TALLOC_FREE(state->ld);
1795         return;
1796 }
1797
1798 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1799                                 const char *location)
1800 {
1801         const char *rootdse_attrs[2] = {
1802                 "defaultNamingContext", "configurationNamingContext" };
1803         const char *domain_attrs[1] = { "objectSid" };
1804         const char *ncname_attrs[1] = { "netbiosname" };
1805         struct tldap_message **rootdse, **domain, **ncname;
1806         TALLOC_CTX *frame = talloc_stackframe();
1807         struct sockaddr_un sunaddr;
1808         NTSTATUS status;
1809         int num_domains;
1810         int fd, rc;
1811
1812         ZERO_STRUCT(sunaddr);
1813         sunaddr.sun_family = AF_UNIX;
1814         strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1815
1816         status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1817                                  0, 0, &fd);
1818         if (!NT_STATUS_IS_OK(status)) {
1819                 DEBUG(10, ("Could not connect to %s: %s\n", location,
1820                            nt_errstr(status)));
1821                 goto done;
1822         }
1823
1824         state->ld = tldap_context_create(state, fd);
1825         if (state->ld == NULL) {
1826                 close(fd);
1827                 status = NT_STATUS_NO_MEMORY;
1828                 goto done;
1829         }
1830
1831         rc = tldap_search_fmt(
1832                 state->ld, "", TLDAP_SCOPE_BASE,
1833                 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1834                 talloc_tos(), &rootdse, "(objectclass=*)");
1835         if (rc != TLDAP_SUCCESS) {
1836                 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1837                            tldap_errstr(debug_ctx(), state->ld, rc)));
1838                 status = NT_STATUS_LDAP(rc);
1839                 goto done;
1840         }
1841         if (talloc_array_length(rootdse) != 1) {
1842                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1843                 goto done;
1844         }
1845
1846         state->domaindn = tldap_talloc_single_attribute(
1847                 rootdse[0], "defaultNamingContext", state);
1848         if (state->domaindn == NULL) {
1849                 DEBUG(10, ("Could not get defaultNamingContext\n"));
1850                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1851                 goto done;
1852         }
1853         DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1854
1855         state->configdn = tldap_talloc_single_attribute(
1856                 rootdse[0], "configurationNamingContext", state);
1857         if (state->domaindn == NULL) {
1858                 DEBUG(10, ("Could not get configurationNamingContext\n"));
1859                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1860                 goto done;
1861         }
1862         DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1863
1864         /*
1865          * Figure out our domain's SID
1866          */
1867         rc = tldap_search_fmt(
1868                 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1869                 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1870                 talloc_tos(), &domain, "(objectclass=*)");
1871         if (rc != TLDAP_SUCCESS) {
1872                 DEBUG(10, ("Could not retrieve domain: %s\n",
1873                            tldap_errstr(debug_ctx(), state->ld, rc)));
1874                 status = NT_STATUS_LDAP(rc);
1875                 goto done;
1876         }
1877
1878         num_domains = talloc_array_length(domain);
1879         if (num_domains != 1) {
1880                 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1881                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1882                 goto done;
1883         }
1884         if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1885                 DEBUG(10, ("Could not retrieve domain SID\n"));
1886                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1887                 goto done;
1888         }
1889         DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1890
1891         /*
1892          * Figure out our domain's short name
1893          */
1894         rc = tldap_search_fmt(
1895                 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1896                 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1897                 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1898         if (rc != TLDAP_SUCCESS) {
1899                 DEBUG(10, ("Could not retrieve ncname: %s\n",
1900                            tldap_errstr(debug_ctx(), state->ld, rc)));
1901                 status = NT_STATUS_LDAP(rc);
1902                 goto done;
1903         }
1904         if (talloc_array_length(ncname) != 1) {
1905                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1906                 goto done;
1907         }
1908
1909         state->netbiosname = tldap_talloc_single_attribute(
1910                 ncname[0], "netbiosname", state);
1911         if (state->netbiosname == NULL) {
1912                 DEBUG(10, ("Could not get netbiosname\n"));
1913                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1914                 goto done;
1915         }
1916         DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1917
1918         if (!strequal(lp_workgroup(), state->netbiosname)) {
1919                 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1920                           state->netbiosname, lp_workgroup()));
1921                 status = NT_STATUS_NO_SUCH_DOMAIN;
1922                 goto done;
1923         }
1924
1925         secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1926
1927         status = NT_STATUS_OK;
1928 done:
1929         TALLOC_FREE(frame);
1930         return status;
1931 }
1932
1933 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1934                              const char *location)
1935 {
1936         struct pdb_methods *m;
1937         struct pdb_ads_state *state;
1938         char *tmp = NULL;
1939         NTSTATUS status;
1940
1941         m = talloc(talloc_autofree_context(), struct pdb_methods);
1942         if (m == NULL) {
1943                 return NT_STATUS_NO_MEMORY;
1944         }
1945         state = talloc(m, struct pdb_ads_state);
1946         if (state == NULL) {
1947                 goto nomem;
1948         }
1949         m->private_data = state;
1950         m->free_private_data = free_private_data;
1951         pdb_ads_init_methods(m);
1952
1953         if (location == NULL) {
1954                 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1955                                       lp_private_dir());
1956                 location = tmp;
1957         }
1958         if (location == NULL) {
1959                 goto nomem;
1960         }
1961
1962         status = pdb_ads_connect(state, location);
1963         if (!NT_STATUS_IS_OK(status)) {
1964                 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1965                 goto fail;
1966         }
1967
1968         *pdb_method = m;
1969         return NT_STATUS_OK;
1970 nomem:
1971         status = NT_STATUS_NO_MEMORY;
1972 fail:
1973         TALLOC_FREE(m);
1974         return status;
1975 }
1976
1977 NTSTATUS pdb_ads_init(void);
1978 NTSTATUS pdb_ads_init(void)
1979 {
1980         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
1981                                    pdb_init_ads);
1982 }