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