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