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