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