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