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