c3e918964527cc39f745dd178e75e734105f1a73
[metze/samba/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         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
447         int rc;
448
449         rc = tldap_delete(state->ld, priv->dn, NULL, NULL);
450         if (rc != TLDAP_SUCCESS) {
451                 DEBUG(10, ("ldap_delete for %s failed: %s\n", priv->dn,
452                            tldap_errstr(debug_ctx(), state->ld, rc)));
453                 return NT_STATUS_LDAP(rc);
454         }
455         return NT_STATUS_OK;
456 }
457
458 static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
459                                         struct samu *sampass)
460 {
461         return NT_STATUS_NOT_IMPLEMENTED;
462 }
463
464 static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
465                                            struct samu *sam)
466 {
467         struct pdb_ads_state *state = talloc_get_type_abort(
468                 m->private_data, struct pdb_ads_state);
469         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
470         struct tldap_mod *mods = NULL;
471         int rc, num_mods = 0;
472
473         if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
474                                        &num_mods, &mods, sam)) {
475                 return NT_STATUS_NO_MEMORY;
476         }
477
478         rc = tldap_modify(state->ld, priv->dn, num_mods, mods, NULL, NULL);
479         if (rc != TLDAP_SUCCESS) {
480                 DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
481                            tldap_errstr(debug_ctx(), state->ld, rc)));
482                 return NT_STATUS_LDAP(rc);
483         }
484
485         TALLOC_FREE(mods);
486
487         return NT_STATUS_OK;
488 }
489
490 static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
491                                            struct samu *username)
492 {
493         return NT_STATUS_NOT_IMPLEMENTED;
494 }
495
496 static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
497                                            struct samu *oldname,
498                                            const char *newname)
499 {
500         return NT_STATUS_NOT_IMPLEMENTED;
501 }
502
503 static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
504                                               struct samu *sam_acct,
505                                               bool success)
506 {
507         return NT_STATUS_NOT_IMPLEMENTED;
508 }
509
510 static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
511                                     const char *filter)
512 {
513         struct pdb_ads_state *state = talloc_get_type_abort(
514                 m->private_data, struct pdb_ads_state);
515         const char *attrs[4] = { "objectSid", "description", "samAccountName",
516                                  "groupType" };
517         char *str;
518         struct tldap_message **group;
519         uint32_t grouptype;
520         int rc;
521
522         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
523                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
524                               &group, "%s", filter);
525         if (rc != TLDAP_SUCCESS) {
526                 DEBUG(10, ("ldap_search failed %s\n",
527                            tldap_errstr(debug_ctx(), state->ld, rc)));
528                 return NT_STATUS_LDAP(rc);
529         }
530         if (talloc_array_length(group) != 1) {
531                 DEBUG(10, ("Expected 1 user, got %d\n",
532                            (int)talloc_array_length(group)));
533                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
534         }
535
536         if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
537                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
538         }
539         map->gid = pdb_ads_sid2gid(&map->sid);
540
541         if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
542                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
543         }
544         switch (grouptype) {
545         case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
546         case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
547                 map->sid_name_use = SID_NAME_ALIAS;
548                 break;
549         case GTYPE_SECURITY_GLOBAL_GROUP:
550                 map->sid_name_use = SID_NAME_DOM_GRP;
551                 break;
552         default:
553                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
554         }
555
556         str = tldap_talloc_single_attribute(group[0], "samAccountName",
557                                             talloc_tos());
558         if (str == NULL) {
559                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
560         }
561         fstrcpy(map->nt_name, str);
562         TALLOC_FREE(str);
563
564         str = tldap_talloc_single_attribute(group[0], "description",
565                                             talloc_tos());
566         if (str != NULL) {
567                 fstrcpy(map->comment, str);
568                 TALLOC_FREE(str);
569         } else {
570                 map->comment[0] = '\0';
571         }
572
573         TALLOC_FREE(group);
574         return NT_STATUS_OK;
575 }
576
577 static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
578                                  DOM_SID sid)
579 {
580         char *filter;
581         NTSTATUS status;
582
583         filter = talloc_asprintf(talloc_tos(),
584                                  "(&(objectsid=%s)(objectclass=group))",
585                                  sid_string_talloc(talloc_tos(), &sid));
586         if (filter == NULL) {
587                 return NT_STATUS_NO_MEMORY;
588         }
589
590         status = pdb_ads_getgrfilter(m, map, filter);
591         TALLOC_FREE(filter);
592         return status;
593 }
594
595 static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
596                                  gid_t gid)
597 {
598         struct dom_sid sid;
599         pdb_ads_gid_to_sid(m, gid, &sid);
600         return pdb_ads_getgrsid(m, map, sid);
601 }
602
603 static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
604                                  const char *name)
605 {
606         char *filter;
607         NTSTATUS status;
608
609         filter = talloc_asprintf(talloc_tos(),
610                                  "(&(samaccountname=%s)(objectclass=group))",
611                                  name);
612         if (filter == NULL) {
613                 return NT_STATUS_NO_MEMORY;
614         }
615
616         status = pdb_ads_getgrfilter(m, map, filter);
617         TALLOC_FREE(filter);
618         return status;
619 }
620
621 static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
622                                          TALLOC_CTX *mem_ctx, const char *name,
623                                          uint32 *rid)
624 {
625         TALLOC_CTX *frame = talloc_stackframe();
626         struct pdb_ads_state *state = talloc_get_type_abort(
627                 m->private_data, struct pdb_ads_state);
628         const char *attrs[1] = { "objectSid" };
629         int num_mods = 0;
630         struct tldap_mod *mods = NULL;
631         struct tldap_message **alias;
632         struct dom_sid sid;
633         char *dn;
634         int rc;
635         bool ok = true;
636
637         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
638                              state->domaindn);
639         if (dn == NULL) {
640                 TALLOC_FREE(frame);
641                 return NT_STATUS_NO_MEMORY;
642         }
643
644         ok &= tldap_make_mod_fmt(
645                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
646                 name);
647         ok &= tldap_make_mod_fmt(
648                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
649         ok &= tldap_make_mod_fmt(
650                 NULL, talloc_tos(), &num_mods, &mods, "groupType",
651                 "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
652
653         if (!ok) {
654                 TALLOC_FREE(frame);
655                 return NT_STATUS_NO_MEMORY;
656         }
657
658         rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
659         if (rc != TLDAP_SUCCESS) {
660                 DEBUG(10, ("ldap_add failed %s\n",
661                            tldap_errstr(debug_ctx(), state->ld, rc)));
662                 TALLOC_FREE(frame);
663                 return NT_STATUS_LDAP(rc);
664         }
665
666         rc = tldap_search_fmt(
667                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
668                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
669                 "(&(objectclass=group)(samaccountname=%s))", name);
670         if (rc != TLDAP_SUCCESS) {
671                 DEBUG(10, ("Could not find just created alias %s: %s\n",
672                            name, tldap_errstr(debug_ctx(), state->ld, rc)));
673                 TALLOC_FREE(frame);
674                 return NT_STATUS_LDAP(rc);
675         }
676
677         if (talloc_array_length(alias) != 1) {
678                 DEBUG(10, ("Got %d alias, expected one\n",
679                            (int)talloc_array_length(alias)));
680                 TALLOC_FREE(frame);
681                 return NT_STATUS_LDAP(rc);
682         }
683
684         if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
685                 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
686                            name));
687                 TALLOC_FREE(frame);
688                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
689         }
690
691         sid_peek_rid(&sid, rid);
692         TALLOC_FREE(frame);
693         return NT_STATUS_OK;
694 }
695
696 static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
697                                          TALLOC_CTX *mem_ctx, uint32 rid)
698 {
699         struct pdb_ads_state *state = talloc_get_type_abort(
700                 m->private_data, struct pdb_ads_state);
701         struct dom_sid sid;
702         char *sidstr;
703         struct tldap_message **msg;
704         char *dn;
705         int rc;
706
707         sid_compose(&sid, &state->domainsid, rid);
708
709         sidstr = sid_binstring(talloc_tos(), &sid);
710         NT_STATUS_HAVE_NO_MEMORY(sidstr);
711
712         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
713                               NULL, 0, 0, talloc_tos(), &msg,
714                               ("(&(objectSid=%s)(objectClass=group))"),
715                               sidstr);
716         TALLOC_FREE(sidstr);
717         if (rc != TLDAP_SUCCESS) {
718                 DEBUG(10, ("ldap_search failed %s\n",
719                            tldap_errstr(debug_ctx(), state->ld, rc)));
720                 return NT_STATUS_LDAP(rc);
721         }
722
723         switch talloc_array_length(msg) {
724         case 0:
725                 return NT_STATUS_NO_SUCH_GROUP;
726         case 1:
727                 break;
728         default:
729                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
730         }
731
732         if (!tldap_entry_dn(msg[0], &dn)) {
733                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
734         }
735
736         rc = tldap_delete(state->ld, dn, NULL, NULL);
737         if (rc != TLDAP_SUCCESS) {
738                 DEBUG(10, ("ldap_delete failed: %s\n",
739                            tldap_errstr(debug_ctx(), state->ld, rc)));
740                 TALLOC_FREE(dn);
741                 return NT_STATUS_LDAP(rc);
742         }
743
744         TALLOC_FREE(msg);
745         return NT_STATUS_OK;
746 }
747
748 static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
749                                                 GROUP_MAP *map)
750 {
751         return NT_STATUS_NOT_IMPLEMENTED;
752 }
753
754 static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
755                                                    GROUP_MAP *map)
756 {
757         return NT_STATUS_NOT_IMPLEMENTED;
758 }
759
760 static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
761                                                    DOM_SID sid)
762 {
763         return NT_STATUS_NOT_IMPLEMENTED;
764 }
765
766 static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
767                                            const DOM_SID *sid,
768                                            enum lsa_SidType sid_name_use,
769                                            GROUP_MAP **pp_rmap,
770                                            size_t *p_num_entries,
771                                            bool unix_only)
772 {
773         return NT_STATUS_NOT_IMPLEMENTED;
774 }
775
776 static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
777                                            TALLOC_CTX *mem_ctx,
778                                            const DOM_SID *group,
779                                            uint32 **pmembers,
780                                            size_t *pnum_members)
781 {
782         struct pdb_ads_state *state = talloc_get_type_abort(
783                 m->private_data, struct pdb_ads_state);
784         const char *attrs[1] = { "member" };
785         char *sidstr;
786         struct tldap_message **msg;
787         int i, rc, num_members;
788         DATA_BLOB *blobs;
789         uint32_t *members;
790
791         sidstr = sid_binstring(talloc_tos(), group);
792         NT_STATUS_HAVE_NO_MEMORY(sidstr);
793
794         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
795                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
796                               "(objectsid=%s)", sidstr);
797         TALLOC_FREE(sidstr);
798         if (rc != TLDAP_SUCCESS) {
799                 DEBUG(10, ("ldap_search failed %s\n",
800                            tldap_errstr(debug_ctx(), state->ld, rc)));
801                 return NT_STATUS_LDAP(rc);
802         }
803         switch talloc_array_length(msg) {
804         case 0:
805                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
806                 break;
807         case 1:
808                 break;
809         default:
810                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
811                 break;
812         }
813
814         if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
815                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
816         }
817
818         members = talloc_array(mem_ctx, uint32_t, num_members);
819         if (members == NULL) {
820                 return NT_STATUS_NO_MEMORY;
821         }
822
823         for (i=0; i<num_members; i++) {
824                 struct dom_sid sid;
825                 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &sid)
826                     || !sid_peek_rid(&sid, &members[i])) {
827                         TALLOC_FREE(members);
828                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
829                 }
830         }
831
832         *pmembers = members;
833         *pnum_members = num_members;
834         return NT_STATUS_OK;
835 }
836
837 static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
838                                                TALLOC_CTX *mem_ctx,
839                                                struct samu *user,
840                                                DOM_SID **pp_sids,
841                                                gid_t **pp_gids,
842                                                size_t *p_num_groups)
843 {
844         struct pdb_ads_state *state = talloc_get_type_abort(
845                 m->private_data, struct pdb_ads_state);
846         struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(
847                 m, user);
848         const char *attrs[1] = { "objectSid" };
849         struct tldap_message **groups;
850         int i, rc, count;
851         size_t num_groups;
852         struct dom_sid *group_sids;
853         gid_t *gids;
854
855         rc = tldap_search_fmt(
856                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
857                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
858                 "(&(member=%s)(grouptype=%d)(objectclass=group))",
859                 priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
860         if (rc != TLDAP_SUCCESS) {
861                 DEBUG(10, ("ldap_search failed %s\n",
862                            tldap_errstr(debug_ctx(), state->ld, rc)));
863                 return NT_STATUS_LDAP(rc);
864         }
865
866         count = talloc_array_length(groups);
867
868         group_sids = talloc_array(mem_ctx, struct dom_sid, count);
869         if (group_sids == NULL) {
870                 return NT_STATUS_NO_MEMORY;
871         }
872         gids = talloc_array(mem_ctx, gid_t, count);
873         if (gids == NULL) {
874                 TALLOC_FREE(group_sids);
875                 return NT_STATUS_NO_MEMORY;
876         }
877         num_groups = 0;
878
879         for (i=0; i<count; i++) {
880                 if (!tldap_pull_binsid(groups[i], "objectSid",
881                                        &group_sids[num_groups])) {
882                         continue;
883                 }
884                 gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
885
886                 num_groups += 1;
887                 if (num_groups == count) {
888                         break;
889                 }
890         }
891
892         *pp_sids = group_sids;
893         *pp_gids = gids;
894         *p_num_groups = num_groups;
895         return NT_STATUS_OK;
896 }
897
898 static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
899                                                TALLOC_CTX *mem_ctx,
900                                                struct samu *user)
901 {
902         return NT_STATUS_NOT_IMPLEMENTED;
903 }
904
905 static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
906                                      TALLOC_CTX *mem_ctx,
907                                      uint32 grouprid, uint32 memberrid,
908                                      int mod_op)
909 {
910         struct pdb_ads_state *state = talloc_get_type_abort(
911                 m->private_data, struct pdb_ads_state);
912         TALLOC_CTX *frame = talloc_stackframe();
913         struct dom_sid groupsid, membersid;
914         char *groupdn, *memberdn;
915         struct tldap_mod *mods;
916         int rc;
917         NTSTATUS status;
918
919         sid_compose(&groupsid, &state->domainsid, grouprid);
920         sid_compose(&membersid, &state->domainsid, memberrid);
921
922         status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
923         if (!NT_STATUS_IS_OK(status)) {
924                 TALLOC_FREE(frame);
925                 return NT_STATUS_NO_SUCH_GROUP;
926         }
927         status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
928         if (!NT_STATUS_IS_OK(status)) {
929                 TALLOC_FREE(frame);
930                 return NT_STATUS_NO_SUCH_USER;
931         }
932
933         mods = NULL;
934
935         if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
936                                "member", memberdn)) {
937                 TALLOC_FREE(frame);
938                 return NT_STATUS_NO_MEMORY;
939         }
940
941         rc = tldap_modify(state->ld, groupdn, 1, mods, NULL, NULL);
942         TALLOC_FREE(frame);
943         if (rc != TLDAP_SUCCESS) {
944                 DEBUG(10, ("ldap_modify failed: %s\n",
945                            tldap_errstr(debug_ctx(), state->ld, rc)));
946                 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
947                         return NT_STATUS_MEMBER_IN_GROUP;
948                 }
949                 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
950                         return NT_STATUS_MEMBER_NOT_IN_GROUP;
951                 }
952                 return NT_STATUS_LDAP(rc);
953         }
954
955         return NT_STATUS_OK;
956 }
957
958 static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
959                                      TALLOC_CTX *mem_ctx,
960                                      uint32 group_rid, uint32 member_rid)
961 {
962         return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
963                                     TLDAP_MOD_ADD);
964 }
965
966 static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
967                                      TALLOC_CTX *mem_ctx,
968                                      uint32 group_rid, uint32 member_rid)
969 {
970         return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
971                                     TLDAP_MOD_DELETE);
972 }
973
974 static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
975                                      const char *name, uint32 *rid)
976 {
977         TALLOC_CTX *frame = talloc_stackframe();
978         struct pdb_ads_state *state = talloc_get_type_abort(
979                 m->private_data, struct pdb_ads_state);
980         const char *attrs[1] = { "objectSid" };
981         int num_mods = 0;
982         struct tldap_mod *mods = NULL;
983         struct tldap_message **alias;
984         struct dom_sid sid;
985         char *dn;
986         int rc;
987         bool ok = true;
988
989         dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
990                              state->domaindn);
991         if (dn == NULL) {
992                 TALLOC_FREE(frame);
993                 return NT_STATUS_NO_MEMORY;
994         }
995
996         ok &= tldap_make_mod_fmt(
997                 NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s",
998                 name);
999         ok &= tldap_make_mod_fmt(
1000                 NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group");
1001         ok &= tldap_make_mod_fmt(
1002                 NULL, talloc_tos(), &num_mods, &mods, "groupType",
1003                 "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1004
1005         if (!ok) {
1006                 TALLOC_FREE(frame);
1007                 return NT_STATUS_NO_MEMORY;
1008         }
1009
1010         rc = tldap_add(state->ld, dn, num_mods, mods, NULL, NULL);
1011         if (rc != TLDAP_SUCCESS) {
1012                 DEBUG(10, ("ldap_add failed %s\n",
1013                            tldap_errstr(debug_ctx(), state->ld, rc)));
1014                 TALLOC_FREE(frame);
1015                 return NT_STATUS_LDAP(rc);
1016         }
1017
1018         rc = tldap_search_fmt(
1019                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1020                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
1021                 "(&(objectclass=group)(samaccountname=%s))", name);
1022         if (rc != TLDAP_SUCCESS) {
1023                 DEBUG(10, ("Could not find just created alias %s: %s\n",
1024                            name, tldap_errstr(debug_ctx(), state->ld, rc)));
1025                 TALLOC_FREE(frame);
1026                 return NT_STATUS_LDAP(rc);
1027         }
1028
1029         if (talloc_array_length(alias) != 1) {
1030                 DEBUG(10, ("Got %d alias, expected one\n",
1031                            (int)talloc_array_length(alias)));
1032                 TALLOC_FREE(frame);
1033                 return NT_STATUS_LDAP(rc);
1034         }
1035
1036         if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
1037                 DEBUG(10, ("Could not fetch objectSid from alias %s\n",
1038                            name));
1039                 TALLOC_FREE(frame);
1040                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1041         }
1042
1043         sid_peek_rid(&sid, rid);
1044         TALLOC_FREE(frame);
1045         return NT_STATUS_OK;
1046 }
1047
1048 static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
1049                                      const DOM_SID *sid)
1050 {
1051         struct pdb_ads_state *state = talloc_get_type_abort(
1052                 m->private_data, struct pdb_ads_state);
1053         struct tldap_message **alias;
1054         char *sidstr, *dn;
1055         int rc;
1056
1057         sidstr = sid_binstring(talloc_tos(), sid);
1058         if (sidstr == NULL) {
1059                 return NT_STATUS_NO_MEMORY;
1060         }
1061
1062         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1063                               NULL, 0, 0, talloc_tos(), &alias,
1064                               "(&(objectSid=%s)(objectclass=group)"
1065                               "(|(grouptype=%d)(grouptype=%d)))",
1066                               sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1067                               GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1068         TALLOC_FREE(sidstr);
1069         if (rc != TLDAP_SUCCESS) {
1070                 DEBUG(10, ("ldap_search failed: %s\n",
1071                            tldap_errstr(debug_ctx(), state->ld, rc)));
1072                 TALLOC_FREE(dn);
1073                 return NT_STATUS_LDAP(rc);
1074         }
1075         if (talloc_array_length(alias) != 1) {
1076                 DEBUG(10, ("Expected 1 alias, got %d\n",
1077                            (int)talloc_array_length(alias)));
1078                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1079         }
1080         if (!tldap_entry_dn(alias[0], &dn)) {
1081                 DEBUG(10, ("Could not get DN for alias %s\n",
1082                            sid_string_dbg(sid)));
1083                 return NT_STATUS_INTERNAL_ERROR;
1084         }
1085
1086         rc = tldap_delete(state->ld, dn, NULL, NULL);
1087         if (rc != TLDAP_SUCCESS) {
1088                 DEBUG(10, ("ldap_delete failed: %s\n",
1089                            tldap_errstr(debug_ctx(), state->ld, rc)));
1090                 TALLOC_FREE(dn);
1091                 return NT_STATUS_LDAP(rc);
1092         }
1093
1094         return NT_STATUS_OK;
1095 }
1096
1097 static NTSTATUS pdb_ads_get_aliasinfo(struct pdb_methods *m,
1098                                       const DOM_SID *sid,
1099                                       struct acct_info *info)
1100 {
1101         return NT_STATUS_NOT_IMPLEMENTED;
1102 }
1103
1104 static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
1105                                       const DOM_SID *sid,
1106                                       struct acct_info *info)
1107 {
1108         return NT_STATUS_NOT_IMPLEMENTED;
1109 }
1110
1111 static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
1112                                const struct dom_sid *sid,
1113                                TALLOC_CTX *mem_ctx, char **pdn)
1114 {
1115         struct tldap_message **msg;
1116         char *sidstr, *dn;
1117         int rc;
1118
1119         sidstr = sid_binstring(talloc_tos(), sid);
1120         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1121
1122         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1123                               NULL, 0, 0, talloc_tos(), &msg,
1124                               "(objectsid=%s)", sidstr);
1125         TALLOC_FREE(sidstr);
1126         if (rc != TLDAP_SUCCESS) {
1127                 DEBUG(10, ("ldap_search failed %s\n",
1128                            tldap_errstr(debug_ctx(), state->ld, rc)));
1129                 return NT_STATUS_LDAP(rc);
1130         }
1131
1132         switch talloc_array_length(msg) {
1133         case 0:
1134                 return NT_STATUS_NOT_FOUND;
1135         case 1:
1136                 break;
1137         default:
1138                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1139         }
1140
1141         if (!tldap_entry_dn(msg[0], &dn)) {
1142                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1143         }
1144
1145         dn = talloc_strdup(mem_ctx, dn);
1146         if (dn == NULL) {
1147                 return NT_STATUS_NO_MEMORY;
1148         }
1149         TALLOC_FREE(msg);
1150
1151         *pdn = dn;
1152         return NT_STATUS_OK;
1153 }
1154
1155 static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
1156                                      const DOM_SID *alias,
1157                                      const DOM_SID *member,
1158                                      int mod_op)
1159 {
1160         struct pdb_ads_state *state = talloc_get_type_abort(
1161                 m->private_data, struct pdb_ads_state);
1162         TALLOC_CTX *frame = talloc_stackframe();
1163         struct tldap_mod *mods;
1164         int rc;
1165         char *aliasdn, *memberdn;
1166         NTSTATUS status;
1167
1168         status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
1169         if (!NT_STATUS_IS_OK(status)) {
1170                 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1171                            sid_string_dbg(alias), nt_errstr(status)));
1172                 TALLOC_FREE(frame);
1173                 return NT_STATUS_NO_SUCH_ALIAS;
1174         }
1175         status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
1176         if (!NT_STATUS_IS_OK(status)) {
1177                 DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
1178                            sid_string_dbg(member), nt_errstr(status)));
1179                 TALLOC_FREE(frame);
1180                 return status;
1181         }
1182
1183         mods = NULL;
1184
1185         if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op,
1186                                "member", memberdn)) {
1187                 TALLOC_FREE(frame);
1188                 return NT_STATUS_NO_MEMORY;
1189         }
1190
1191         rc = tldap_modify(state->ld, aliasdn, 1, mods, NULL, NULL);
1192         TALLOC_FREE(frame);
1193         if (rc != TLDAP_SUCCESS) {
1194                 DEBUG(10, ("ldap_modify failed: %s\n",
1195                            tldap_errstr(debug_ctx(), state->ld, rc)));
1196                 if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
1197                         return NT_STATUS_MEMBER_IN_ALIAS;
1198                 }
1199                 if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
1200                         return NT_STATUS_MEMBER_NOT_IN_ALIAS;
1201                 }
1202                 return NT_STATUS_LDAP(rc);
1203         }
1204
1205         return NT_STATUS_OK;
1206 }
1207
1208 static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
1209                                      const DOM_SID *alias,
1210                                      const DOM_SID *member)
1211 {
1212         return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
1213 }
1214
1215 static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
1216                                      const DOM_SID *alias,
1217                                      const DOM_SID *member)
1218 {
1219         return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
1220 }
1221
1222 static bool pdb_ads_dnblob2sid(struct tldap_context *ld, DATA_BLOB *dnblob,
1223                                struct dom_sid *psid)
1224 {
1225         const char *attrs[1] = { "objectSid" };
1226         struct tldap_message **msg;
1227         char *dn;
1228         size_t len;
1229         int rc;
1230         bool ret;
1231
1232         if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
1233                                    dnblob->data, dnblob->length, &dn, &len,
1234                                    false)) {
1235                 return false;
1236         }
1237         rc = tldap_search_fmt(ld, dn, TLDAP_SCOPE_BASE,
1238                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1239                               &msg, "(objectclass=*)");
1240         TALLOC_FREE(dn);
1241         if (talloc_array_length(msg) != 1) {
1242                 DEBUG(10, ("Got %d objects, expected one\n",
1243                            (int)talloc_array_length(msg)));
1244                 TALLOC_FREE(msg);
1245                 return false;
1246         }
1247
1248         ret = tldap_pull_binsid(msg[0], "objectSid", psid);
1249         TALLOC_FREE(msg);
1250         return ret;
1251 }
1252
1253 static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
1254                                       const DOM_SID *alias,
1255                                       TALLOC_CTX *mem_ctx,
1256                                       DOM_SID **pmembers,
1257                                       size_t *pnum_members)
1258 {
1259         struct pdb_ads_state *state = talloc_get_type_abort(
1260                 m->private_data, struct pdb_ads_state);
1261         const char *attrs[1] = { "member" };
1262         char *sidstr;
1263         struct tldap_message **msg;
1264         int i, rc, num_members;
1265         DATA_BLOB *blobs;
1266         struct dom_sid *members;
1267
1268         sidstr = sid_binstring(talloc_tos(), alias);
1269         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1270
1271         rc = tldap_search_fmt(state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1272                               attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
1273                               "(objectsid=%s)", sidstr);
1274         TALLOC_FREE(sidstr);
1275         if (rc != TLDAP_SUCCESS) {
1276                 DEBUG(10, ("ldap_search failed %s\n",
1277                            tldap_errstr(debug_ctx(), state->ld, rc)));
1278                 return NT_STATUS_LDAP(rc);
1279         }
1280         switch talloc_array_length(msg) {
1281         case 0:
1282                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1283                 break;
1284         case 1:
1285                 break;
1286         default:
1287                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1288                 break;
1289         }
1290
1291         if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) {
1292                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1293         }
1294
1295         members = talloc_array(mem_ctx, struct dom_sid, num_members);
1296         if (members == NULL) {
1297                 return NT_STATUS_NO_MEMORY;
1298         }
1299
1300         for (i=0; i<num_members; i++) {
1301                 if (!pdb_ads_dnblob2sid(state->ld, &blobs[i], &members[i])) {
1302                         TALLOC_FREE(members);
1303                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1304                 }
1305         }
1306
1307         *pmembers = members;
1308         *pnum_members = num_members;
1309         return NT_STATUS_OK;
1310 }
1311
1312 static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
1313                                                TALLOC_CTX *mem_ctx,
1314                                                const DOM_SID *domain_sid,
1315                                                const DOM_SID *members,
1316                                                size_t num_members,
1317                                                uint32 **pp_alias_rids,
1318                                                size_t *p_num_alias_rids)
1319 {
1320         return NT_STATUS_NOT_IMPLEMENTED;
1321 }
1322
1323 static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
1324                                     const DOM_SID *domain_sid,
1325                                     int num_rids,
1326                                     uint32 *rids,
1327                                     const char **pp_names,
1328                                     enum lsa_SidType *attrs)
1329 {
1330         return NT_STATUS_NOT_IMPLEMENTED;
1331 }
1332
1333 static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
1334                                      const DOM_SID *domain_sid,
1335                                      int num_names,
1336                                      const char **pp_names,
1337                                      uint32 *rids,
1338                                      enum lsa_SidType *attrs)
1339 {
1340         return NT_STATUS_NOT_IMPLEMENTED;
1341 }
1342
1343 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
1344                                            int policy_index, uint32 *value)
1345 {
1346         return account_policy_get(policy_index, value)
1347                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1348 }
1349
1350 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
1351                                            int policy_index, uint32 value)
1352 {
1353         return account_policy_set(policy_index, value)
1354                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1355 }
1356
1357 static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
1358                                     time_t *seq_num)
1359 {
1360         return NT_STATUS_NOT_IMPLEMENTED;
1361 }
1362
1363 struct pdb_ads_search_state {
1364         uint32_t acct_flags;
1365         struct samr_displayentry *entries;
1366         uint32_t num_entries;
1367         ssize_t array_size;
1368         uint32_t current;
1369 };
1370
1371 static bool pdb_ads_next_entry(struct pdb_search *search,
1372                                struct samr_displayentry *entry)
1373 {
1374         struct pdb_ads_search_state *state = talloc_get_type_abort(
1375                 search->private_data, struct pdb_ads_search_state);
1376
1377         if (state->current == state->num_entries) {
1378                 return false;
1379         }
1380
1381         entry->idx = state->entries[state->current].idx;
1382         entry->rid = state->entries[state->current].rid;
1383         entry->acct_flags = state->entries[state->current].acct_flags;
1384
1385         entry->account_name = talloc_strdup(
1386                 search, state->entries[state->current].account_name);
1387         entry->fullname = talloc_strdup(
1388                 search, state->entries[state->current].fullname);
1389         entry->description = talloc_strdup(
1390                 search, state->entries[state->current].description);
1391
1392         if ((entry->account_name == NULL) || (entry->fullname == NULL)
1393             || (entry->description == NULL)) {
1394                 DEBUG(0, ("talloc_strdup failed\n"));
1395                 return false;
1396         }
1397
1398         state->current += 1;
1399         return true;
1400 }
1401
1402 static void pdb_ads_search_end(struct pdb_search *search)
1403 {
1404         struct pdb_ads_search_state *state = talloc_get_type_abort(
1405                 search->private_data, struct pdb_ads_search_state);
1406         TALLOC_FREE(state);
1407 }
1408
1409 static bool pdb_ads_search_filter(struct pdb_methods *m,
1410                                   struct pdb_search *search,
1411                                   const char *filter,
1412                                   struct pdb_ads_search_state **pstate)
1413 {
1414         struct pdb_ads_state *state = talloc_get_type_abort(
1415                 m->private_data, struct pdb_ads_state);
1416         struct pdb_ads_search_state *sstate;
1417         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1418                                  "userAccountControl", "description" };
1419         struct tldap_message **users;
1420         int i, rc, num_users;
1421
1422         sstate = talloc_zero(search, struct pdb_ads_search_state);
1423         if (sstate == NULL) {
1424                 return false;
1425         }
1426
1427         rc = tldap_search_fmt(
1428                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1429                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
1430                 "%s", filter);
1431         if (rc != TLDAP_SUCCESS) {
1432                 DEBUG(10, ("ldap_search_ext_s failed: %s\n",
1433                            tldap_errstr(debug_ctx(), state->ld, rc)));
1434                 return false;
1435         }
1436
1437         num_users = talloc_array_length(users);
1438
1439         sstate->entries = talloc_array(sstate, struct samr_displayentry,
1440                                        num_users);
1441         if (sstate->entries == NULL) {
1442                 DEBUG(10, ("talloc failed\n"));
1443                 return false;
1444         }
1445
1446         sstate->num_entries = 0;
1447
1448         for (i=0; i<num_users; i++) {
1449                 struct samr_displayentry *e;
1450                 struct dom_sid sid;
1451
1452                 e = &sstate->entries[sstate->num_entries];
1453
1454                 e->idx = sstate->num_entries;
1455                 if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
1456                         DEBUG(10, ("Could not pull sid\n"));
1457                         continue;
1458                 }
1459                 sid_peek_rid(&sid, &e->rid);
1460                 e->acct_flags = ACB_NORMAL;
1461                 e->account_name = tldap_talloc_single_attribute(
1462                         users[i], "samAccountName", sstate->entries);
1463                 if (e->account_name == NULL) {
1464                         return false;
1465                 }
1466                 e->fullname = tldap_talloc_single_attribute(
1467                         users[i], "displayName", sstate->entries);
1468                 if (e->fullname == NULL) {
1469                         e->fullname = "";
1470                 }
1471                 e->description = tldap_talloc_single_attribute(
1472                         users[i], "description", sstate->entries);
1473                 if (e->description == NULL) {
1474                         e->description = "";
1475                 }
1476
1477                 sstate->num_entries += 1;
1478                 if (sstate->num_entries >= num_users) {
1479                         break;
1480                 }
1481         }
1482
1483         search->private_data = sstate;
1484         search->next_entry = pdb_ads_next_entry;
1485         search->search_end = pdb_ads_search_end;
1486         *pstate = sstate;
1487         return true;
1488 }
1489
1490 static bool pdb_ads_search_users(struct pdb_methods *m,
1491                                  struct pdb_search *search,
1492                                  uint32 acct_flags)
1493 {
1494         struct pdb_ads_search_state *sstate;
1495         bool ret;
1496
1497         ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate);
1498         if (!ret) {
1499                 return false;
1500         }
1501         sstate->acct_flags = acct_flags;
1502         return true;
1503 }
1504
1505 static bool pdb_ads_search_groups(struct pdb_methods *m,
1506                                   struct pdb_search *search)
1507 {
1508         struct pdb_ads_search_state *sstate;
1509         char *filter;
1510         bool ret;
1511
1512         filter = talloc_asprintf(talloc_tos(),
1513                                  "(&(grouptype=%d)(objectclass=group))",
1514                                  GTYPE_SECURITY_GLOBAL_GROUP);
1515         if (filter == NULL) {
1516                 return false;
1517         }
1518         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1519         TALLOC_FREE(filter);
1520         if (!ret) {
1521                 return false;
1522         }
1523         sstate->acct_flags = 0;
1524         return true;
1525 }
1526
1527 static bool pdb_ads_search_aliases(struct pdb_methods *m,
1528                                    struct pdb_search *search,
1529                                    const DOM_SID *sid)
1530 {
1531         struct pdb_ads_search_state *sstate;
1532         char *filter;
1533         bool ret;
1534
1535         filter = talloc_asprintf(
1536                 talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
1537                 sid_check_is_builtin(sid)
1538                 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1539                 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1540
1541         if (filter == NULL) {
1542                 return false;
1543         }
1544         ret = pdb_ads_search_filter(m, search, filter, &sstate);
1545         TALLOC_FREE(filter);
1546         if (!ret) {
1547                 return false;
1548         }
1549         sstate->acct_flags = 0;
1550         return true;
1551 }
1552
1553 static bool pdb_ads_uid_to_rid(struct pdb_methods *m, uid_t uid,
1554                                uint32 *rid)
1555 {
1556         return false;
1557 }
1558
1559 static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
1560                                DOM_SID *sid)
1561 {
1562         struct pdb_ads_state *state = talloc_get_type_abort(
1563                 m->private_data, struct pdb_ads_state);
1564         sid_compose(sid, &state->domainsid, uid);
1565         return true;
1566 }
1567
1568 static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
1569                                DOM_SID *sid)
1570 {
1571         struct pdb_ads_state *state = talloc_get_type_abort(
1572                 m->private_data, struct pdb_ads_state);
1573         sid_compose(sid, &state->domainsid, gid);
1574         return true;
1575 }
1576
1577 static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid,
1578                               union unid_t *id, enum lsa_SidType *type)
1579 {
1580         struct pdb_ads_state *state = talloc_get_type_abort(
1581                 m->private_data, struct pdb_ads_state);
1582         struct tldap_message **msg;
1583         char *sidstr;
1584         uint32_t rid;
1585         int rc;
1586
1587         /*
1588          * This is a big, big hack: Just hard-code the rid as uid/gid.
1589          */
1590
1591         sid_peek_rid(sid, &rid);
1592
1593         sidstr = sid_binstring(talloc_tos(), sid);
1594         if (sidstr == NULL) {
1595                 return false;
1596         }
1597
1598         rc = tldap_search_fmt(
1599                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1600                 NULL, 0, 0, talloc_tos(), &msg,
1601                 "(&(objectsid=%s)(objectclass=user))", sidstr);
1602         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1603                 id->uid = rid;
1604                 *type = SID_NAME_USER;
1605                 TALLOC_FREE(sidstr);
1606                 return true;
1607         }
1608
1609         rc = tldap_search_fmt(
1610                 state->ld, state->domaindn, TLDAP_SCOPE_SUB,
1611                 NULL, 0, 0, talloc_tos(), &msg,
1612                 "(&(objectsid=%s)(objectclass=group))", sidstr);
1613         if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) {
1614                 id->gid = rid;
1615                 *type = SID_NAME_DOM_GRP;
1616                 TALLOC_FREE(sidstr);
1617                 return true;
1618         }
1619
1620         TALLOC_FREE(sidstr);
1621         return false;
1622 }
1623
1624 static bool pdb_ads_rid_algorithm(struct pdb_methods *m)
1625 {
1626         return false;
1627 }
1628
1629 static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
1630 {
1631         return false;
1632 }
1633
1634 static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
1635                                       const char *domain, char** pwd,
1636                                       DOM_SID *sid,
1637                                       time_t *pass_last_set_time)
1638 {
1639         return false;
1640 }
1641
1642 static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
1643                                       const char* domain, const char* pwd,
1644                                       const DOM_SID *sid)
1645 {
1646         return false;
1647 }
1648
1649 static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
1650                                       const char *domain)
1651 {
1652         return false;
1653 }
1654
1655 static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
1656                                          TALLOC_CTX *mem_ctx,
1657                                          uint32 *num_domains,
1658                                          struct trustdom_info ***domains)
1659 {
1660         return NT_STATUS_NOT_IMPLEMENTED;
1661 }
1662
1663 static void pdb_ads_init_methods(struct pdb_methods *m)
1664 {
1665         m->name = "ads";
1666         m->getsampwnam = pdb_ads_getsampwnam;
1667         m->getsampwsid = pdb_ads_getsampwsid;
1668         m->create_user = pdb_ads_create_user;
1669         m->delete_user = pdb_ads_delete_user;
1670         m->add_sam_account = pdb_ads_add_sam_account;
1671         m->update_sam_account = pdb_ads_update_sam_account;
1672         m->delete_sam_account = pdb_ads_delete_sam_account;
1673         m->rename_sam_account = pdb_ads_rename_sam_account;
1674         m->update_login_attempts = pdb_ads_update_login_attempts;
1675         m->getgrsid = pdb_ads_getgrsid;
1676         m->getgrgid = pdb_ads_getgrgid;
1677         m->getgrnam = pdb_ads_getgrnam;
1678         m->create_dom_group = pdb_ads_create_dom_group;
1679         m->delete_dom_group = pdb_ads_delete_dom_group;
1680         m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
1681         m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
1682         m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry;
1683         m->enum_group_mapping = pdb_ads_enum_group_mapping;
1684         m->enum_group_members = pdb_ads_enum_group_members;
1685         m->enum_group_memberships = pdb_ads_enum_group_memberships;
1686         m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
1687         m->add_groupmem = pdb_ads_add_groupmem;
1688         m->del_groupmem = pdb_ads_del_groupmem;
1689         m->create_alias = pdb_ads_create_alias;
1690         m->delete_alias = pdb_ads_delete_alias;
1691         m->get_aliasinfo = pdb_ads_get_aliasinfo;
1692         m->set_aliasinfo = pdb_ads_set_aliasinfo;
1693         m->add_aliasmem = pdb_ads_add_aliasmem;
1694         m->del_aliasmem = pdb_ads_del_aliasmem;
1695         m->enum_aliasmem = pdb_ads_enum_aliasmem;
1696         m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
1697         m->lookup_rids = pdb_ads_lookup_rids;
1698         m->lookup_names = pdb_ads_lookup_names;
1699         m->get_account_policy = pdb_ads_get_account_policy;
1700         m->set_account_policy = pdb_ads_set_account_policy;
1701         m->get_seq_num = pdb_ads_get_seq_num;
1702         m->search_users = pdb_ads_search_users;
1703         m->search_groups = pdb_ads_search_groups;
1704         m->search_aliases = pdb_ads_search_aliases;
1705         m->uid_to_rid = pdb_ads_uid_to_rid;
1706         m->uid_to_sid = pdb_ads_uid_to_sid;
1707         m->gid_to_sid = pdb_ads_gid_to_sid;
1708         m->sid_to_id = pdb_ads_sid_to_id;
1709         m->rid_algorithm = pdb_ads_rid_algorithm;
1710         m->new_rid = pdb_ads_new_rid;
1711         m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
1712         m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
1713         m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
1714         m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
1715 }
1716
1717 static void free_private_data(void **vp)
1718 {
1719         struct pdb_ads_state *state = talloc_get_type_abort(
1720                 *vp, struct pdb_ads_state);
1721
1722         TALLOC_FREE(state->ld);
1723         return;
1724 }
1725
1726 static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
1727                                 const char *location)
1728 {
1729         const char *rootdse_attrs[2] = {
1730                 "defaultNamingContext", "configurationNamingContext" };
1731         const char *domain_attrs[1] = { "objectSid" };
1732         const char *ncname_attrs[1] = { "netbiosname" };
1733         struct tldap_message **rootdse, **domain, **ncname;
1734         TALLOC_CTX *frame = talloc_stackframe();
1735         struct sockaddr_un sunaddr;
1736         NTSTATUS status;
1737         int num_domains;
1738         int fd, rc;
1739
1740         ZERO_STRUCT(sunaddr);
1741         sunaddr.sun_family = AF_UNIX;
1742         strncpy(sunaddr.sun_path, location, sizeof(sunaddr.sun_path) - 1);
1743
1744         status = open_socket_out((struct sockaddr_storage *)(void *)&sunaddr,
1745                                  0, 0, &fd);
1746         if (!NT_STATUS_IS_OK(status)) {
1747                 DEBUG(10, ("Could not connect to %s: %s\n", location,
1748                            nt_errstr(status)));
1749                 goto done;
1750         }
1751
1752         state->ld = tldap_context_create(state, fd);
1753         if (state->ld == NULL) {
1754                 close(fd);
1755                 status = NT_STATUS_NO_MEMORY;
1756                 goto done;
1757         }
1758
1759         rc = tldap_search_fmt(
1760                 state->ld, "", TLDAP_SCOPE_BASE,
1761                 rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0,
1762                 talloc_tos(), &rootdse, "(objectclass=*)");
1763         if (rc != TLDAP_SUCCESS) {
1764                 DEBUG(10, ("Could not retrieve rootdse: %s\n",
1765                            tldap_errstr(debug_ctx(), state->ld, rc)));
1766                 status = NT_STATUS_LDAP(rc);
1767                 goto done;
1768         }
1769         if (talloc_array_length(rootdse) != 1) {
1770                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1771                 goto done;
1772         }
1773
1774         state->domaindn = tldap_talloc_single_attribute(
1775                 rootdse[0], "defaultNamingContext", state);
1776         if (state->domaindn == NULL) {
1777                 DEBUG(10, ("Could not get defaultNamingContext\n"));
1778                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1779                 goto done;
1780         }
1781         DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
1782
1783         state->configdn = tldap_talloc_single_attribute(
1784                 rootdse[0], "configurationNamingContext", state);
1785         if (state->domaindn == NULL) {
1786                 DEBUG(10, ("Could not get configurationNamingContext\n"));
1787                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1788                 goto done;
1789         }
1790         DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
1791
1792         /*
1793          * Figure out our domain's SID
1794          */
1795         rc = tldap_search_fmt(
1796                 state->ld, state->domaindn, TLDAP_SCOPE_BASE,
1797                 domain_attrs, ARRAY_SIZE(domain_attrs), 0,
1798                 talloc_tos(), &domain, "(objectclass=*)");
1799         if (rc != TLDAP_SUCCESS) {
1800                 DEBUG(10, ("Could not retrieve domain: %s\n",
1801                            tldap_errstr(debug_ctx(), state->ld, rc)));
1802                 status = NT_STATUS_LDAP(rc);
1803                 goto done;
1804         }
1805
1806         num_domains = talloc_array_length(domain);
1807         if (num_domains != 1) {
1808                 DEBUG(10, ("Got %d domains, expected one\n", num_domains));
1809                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1810                 goto done;
1811         }
1812         if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
1813                 DEBUG(10, ("Could not retrieve domain SID\n"));
1814                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1815                 goto done;
1816         }
1817         DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
1818
1819         /*
1820          * Figure out our domain's short name
1821          */
1822         rc = tldap_search_fmt(
1823                 state->ld, state->configdn, TLDAP_SCOPE_SUB,
1824                 ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
1825                 talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
1826         if (rc != TLDAP_SUCCESS) {
1827                 DEBUG(10, ("Could not retrieve ncname: %s\n",
1828                            tldap_errstr(debug_ctx(), state->ld, rc)));
1829                 status = NT_STATUS_LDAP(rc);
1830                 goto done;
1831         }
1832         if (talloc_array_length(ncname) != 1) {
1833                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1834                 goto done;
1835         }
1836
1837         state->netbiosname = tldap_talloc_single_attribute(
1838                 ncname[0], "netbiosname", state);
1839         if (state->netbiosname == NULL) {
1840                 DEBUG(10, ("Could not get netbiosname\n"));
1841                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1842                 goto done;
1843         }
1844         DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
1845
1846         if (!strequal(lp_workgroup(), state->netbiosname)) {
1847                 DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
1848                           state->netbiosname, lp_workgroup()));
1849                 status = NT_STATUS_NO_SUCH_DOMAIN;
1850                 goto done;
1851         }
1852
1853         secrets_store_domain_sid(state->netbiosname, &state->domainsid);
1854
1855         status = NT_STATUS_OK;
1856 done:
1857         TALLOC_FREE(frame);
1858         return status;
1859 }
1860
1861 static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
1862                              const char *location)
1863 {
1864         struct pdb_methods *m;
1865         struct pdb_ads_state *state;
1866         char *tmp = NULL;
1867         NTSTATUS status;
1868
1869         m = talloc(talloc_autofree_context(), struct pdb_methods);
1870         if (m == NULL) {
1871                 return NT_STATUS_NO_MEMORY;
1872         }
1873         state = talloc(m, struct pdb_ads_state);
1874         if (state == NULL) {
1875                 goto nomem;
1876         }
1877         m->private_data = state;
1878         m->free_private_data = free_private_data;
1879         pdb_ads_init_methods(m);
1880
1881         if (location == NULL) {
1882                 tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
1883                                       lp_private_dir());
1884                 location = tmp;
1885         }
1886         if (location == NULL) {
1887                 goto nomem;
1888         }
1889
1890         status = pdb_ads_connect(state, location);
1891         if (!NT_STATUS_IS_OK(status)) {
1892                 DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
1893                 goto fail;
1894         }
1895
1896         *pdb_method = m;
1897         return NT_STATUS_OK;
1898 nomem:
1899         status = NT_STATUS_NO_MEMORY;
1900 fail:
1901         TALLOC_FREE(m);
1902         return status;
1903 }
1904
1905 NTSTATUS pdb_ads_init(void);
1906 NTSTATUS pdb_ads_init(void)
1907 {
1908         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
1909                                    pdb_init_ads);
1910 }