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