passdb: Do not routinely clear the global memory returned by get_global_sam_sid()
[bbaumbach/samba-autobuild/.git] / source3 / passdb / pdb_samba_dsdb.c
1 /*
2    Unix SMB/CIFS implementation.
3    pdb glue module for direct access to the dsdb via LDB APIs
4    Copyright (C) Volker Lendecke 2009-2011
5    Copyright (C) Andrew Bartlett 2010-2012
6    Copyright (C) Matthias Dieter Wallnöfer                 2009
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 /* This module, is a port of Volker's pdb_ads to ldb and DSDB APIs */
23
24 #include "includes.h"
25 #include "source3/include/passdb.h"
26 #include "source4/dsdb/samdb/samdb.h"
27 #include "ldb_errors.h"
28 #include "libcli/security/dom_sid.h"
29 #include "source4/winbind/idmap.h"
30 #include "librpc/gen_ndr/ndr_security.h"
31 #include "libds/common/flag_mapping.h"
32 #include "source4/lib/events/events.h"
33 #include "source4/auth/session.h"
34 #include "source4/auth/system_session_proto.h"
35 #include "lib/param/param.h"
36 #include "source4/dsdb/common/util.h"
37 #include "source3/include/secrets.h"
38
39 struct pdb_samba_dsdb_state {
40         struct tevent_context *ev;
41         struct ldb_context *ldb;
42         struct idmap_context *idmap_ctx;
43         struct loadparm_context *lp_ctx;
44 };
45
46 static NTSTATUS pdb_samba_dsdb_getsampwsid(struct pdb_methods *m,
47                                     struct samu *sam_acct,
48                                     const struct dom_sid *sid);
49 static NTSTATUS pdb_samba_dsdb_getsamupriv(struct pdb_samba_dsdb_state *state,
50                                     const char *filter,
51                                     TALLOC_CTX *mem_ctx,
52                                     struct ldb_message **pmsg);
53 static bool pdb_samba_dsdb_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
54                                  struct unixid *id);
55
56 static bool pdb_samba_dsdb_pull_time(struct ldb_message *msg, const char *attr,
57                               time_t *ptime)
58 {
59         uint64_t tmp;
60         if (! ldb_msg_find_element(msg, attr)) {
61                 return false;
62         }
63         tmp = ldb_msg_find_attr_as_uint64(msg, attr, 0);
64         *ptime = nt_time_to_unix(tmp);
65         return true;
66 }
67
68 static struct pdb_domain_info *pdb_samba_dsdb_get_domain_info(
69         struct pdb_methods *m, TALLOC_CTX *mem_ctx)
70 {
71         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
72                 m->private_data, struct pdb_samba_dsdb_state);
73         struct pdb_domain_info *info;
74         struct dom_sid *domain_sid;
75         struct ldb_dn *forest_dn, *domain_dn;
76         struct ldb_result *dom_res = NULL;
77         const char *dom_attrs[] = {
78                 "objectSid",
79                 "objectGUID",
80                 "fSMORoleOwner",
81                 NULL
82         };
83         char *p;
84         int ret;
85
86         info = talloc(mem_ctx, struct pdb_domain_info);
87         if (info == NULL) {
88                 return NULL;
89         }
90
91         domain_dn = ldb_get_default_basedn(state->ldb);
92
93         ret = ldb_search(state->ldb, info, &dom_res,
94                          domain_dn, LDB_SCOPE_BASE, dom_attrs, NULL);
95         if (ret != LDB_SUCCESS) {
96                 goto fail;
97         }
98         if (dom_res->count != 1) {
99                 goto fail;
100         }
101
102         info->guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
103
104         domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
105         if (!domain_sid) {
106                 goto fail;
107         }
108         info->sid = *domain_sid;
109
110         TALLOC_FREE(dom_res);
111
112         info->name = talloc_strdup(info, lpcfg_sam_name(state->lp_ctx));
113         info->dns_domain = ldb_dn_canonical_string(info, domain_dn);
114
115         if (!info->dns_domain) {
116                 goto fail;
117         }
118         p = strchr(info->dns_domain, '/');
119         if (p) {
120                 *p = '\0';
121         }
122
123         forest_dn = ldb_get_root_basedn(state->ldb);
124         if (!forest_dn) {
125                 goto fail;
126         }
127
128         info->dns_forest = ldb_dn_canonical_string(info, forest_dn);
129         if (!info->dns_forest) {
130                 goto fail;
131         }
132         p = strchr(info->dns_forest, '/');
133         if (p) {
134                 *p = '\0';
135         }
136
137         return info;
138
139 fail:
140         TALLOC_FREE(dom_res);
141         TALLOC_FREE(info);
142         return NULL;
143 }
144
145 static struct ldb_message *pdb_samba_dsdb_get_samu_private(
146         struct pdb_methods *m, struct samu *sam)
147 {
148         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
149                 m->private_data, struct pdb_samba_dsdb_state);
150         struct ldb_message *msg;
151         char *sidstr, *filter;
152         NTSTATUS status;
153
154         msg = (struct ldb_message *)
155                 pdb_get_backend_private_data(sam, m);
156
157         if (msg != NULL) {
158                 return talloc_get_type_abort(msg, struct ldb_message);
159         }
160
161         sidstr = dom_sid_string(talloc_tos(), pdb_get_user_sid(sam));
162         if (sidstr == NULL) {
163                 return NULL;
164         }
165
166         filter = talloc_asprintf(
167                 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
168         TALLOC_FREE(sidstr);
169         if (filter == NULL) {
170                 return NULL;
171         }
172
173         status = pdb_samba_dsdb_getsamupriv(state, filter, sam, &msg);
174         TALLOC_FREE(filter);
175         if (!NT_STATUS_IS_OK(status)) {
176                 return NULL;
177         }
178
179         return msg;
180 }
181
182 static NTSTATUS pdb_samba_dsdb_init_sam_from_priv(struct pdb_methods *m,
183                                            struct samu *sam,
184                                            struct ldb_message *msg)
185 {
186         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
187                 m->private_data, struct pdb_samba_dsdb_state);
188         TALLOC_CTX *frame = talloc_stackframe();
189         NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
190         const char *str;
191         time_t tmp_time;
192         struct dom_sid *sid, group_sid;
193         uint64_t n;
194         const DATA_BLOB *blob;
195
196         str = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
197         if (str == NULL) {
198                 DEBUG(10, ("no samAccountName\n"));
199                 goto fail;
200         }
201         pdb_set_username(sam, str, PDB_SET);
202
203         if (pdb_samba_dsdb_pull_time(msg, "lastLogon", &tmp_time)) {
204                 pdb_set_logon_time(sam, tmp_time, PDB_SET);
205         }
206         if (pdb_samba_dsdb_pull_time(msg, "lastLogoff", &tmp_time)) {
207                 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
208         }
209         if (pdb_samba_dsdb_pull_time(msg, "pwdLastSet", &tmp_time)) {
210                 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
211         }
212         if (pdb_samba_dsdb_pull_time(msg, "accountExpires", &tmp_time)) {
213                 pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
214         }
215
216         str = ldb_msg_find_attr_as_string(msg, "displayName",
217                                             NULL);
218         if (str != NULL) {
219                 pdb_set_fullname(sam, str, PDB_SET);
220         }
221
222         str = ldb_msg_find_attr_as_string(msg, "homeDirectory",
223                                             NULL);
224         if (str != NULL) {
225                 pdb_set_homedir(sam, str, PDB_SET);
226         }
227
228         str = ldb_msg_find_attr_as_string(msg, "homeDrive", NULL);
229         if (str != NULL) {
230                 pdb_set_dir_drive(sam, str, PDB_SET);
231         }
232
233         str = ldb_msg_find_attr_as_string(msg, "scriptPath", NULL);
234         if (str != NULL) {
235                 pdb_set_logon_script(sam, str, PDB_SET);
236         }
237
238         str = ldb_msg_find_attr_as_string(msg, "profilePath",
239                                             NULL);
240         if (str != NULL) {
241                 pdb_set_profile_path(sam, str, PDB_SET);
242         }
243
244         str = ldb_msg_find_attr_as_string(msg, "comment",
245                                             NULL);
246         if (str != NULL) {
247                 pdb_set_comment(sam, str, PDB_SET);
248         }
249
250         str = ldb_msg_find_attr_as_string(msg, "description",
251                                             NULL);
252         if (str != NULL) {
253                 pdb_set_acct_desc(sam, str, PDB_SET);
254         }
255
256         str = ldb_msg_find_attr_as_string(msg, "userWorkstations",
257                                             NULL);
258         if (str != NULL) {
259                 pdb_set_workstations(sam, str, PDB_SET);
260         }
261
262         str = ldb_msg_find_attr_as_string(msg, "userParameters",
263                                             NULL);
264         if (str != NULL) {
265                 pdb_set_munged_dial(sam, str, PDB_SET);
266         }
267
268         sid = samdb_result_dom_sid(talloc_tos(), msg, "objectSid");
269         if (!sid) {
270                 DEBUG(10, ("Could not pull SID\n"));
271                 goto fail;
272         }
273         pdb_set_user_sid(sam, sid, PDB_SET);
274
275         n = samdb_result_acct_flags(msg, "msDS-User-Account-Control-Computed");
276         if (n == 0) {
277                 DEBUG(10, ("Could not pull userAccountControl\n"));
278                 goto fail;
279         }
280         pdb_set_acct_ctrl(sam, n, PDB_SET);
281
282         blob = ldb_msg_find_ldb_val(msg, "unicodePwd");
283         if (blob) {
284                 if (blob->length != NT_HASH_LEN) {
285                         DEBUG(0, ("Got NT hash of length %d, expected %d\n",
286                                   (int)blob->length, NT_HASH_LEN));
287                         goto fail;
288                 }
289                 pdb_set_nt_passwd(sam, blob->data, PDB_SET);
290         }
291
292         blob = ldb_msg_find_ldb_val(msg, "dBCSPwd");
293         if (blob) {
294                 if (blob->length != LM_HASH_LEN) {
295                         DEBUG(0, ("Got LM hash of length %d, expected %d\n",
296                                   (int)blob->length, LM_HASH_LEN));
297                         goto fail;
298                 }
299                 pdb_set_lanman_passwd(sam, blob->data, PDB_SET);
300         }
301
302         n = ldb_msg_find_attr_as_uint(msg, "primaryGroupID", 0);
303         if (n == 0) {
304                 DEBUG(10, ("Could not pull primaryGroupID\n"));
305                 goto fail;
306         }
307         sid_compose(&group_sid, samdb_domain_sid(state->ldb), n);
308         pdb_set_group_sid(sam, &group_sid, PDB_SET);
309
310         status = NT_STATUS_OK;
311 fail:
312         TALLOC_FREE(frame);
313         return status;
314 }
315
316 static bool pdb_samba_dsdb_add_time(struct ldb_message *msg,
317                                 const char *attrib, time_t t)
318 {
319         uint64_t nt_time;
320
321         unix_to_nt_time(&nt_time, t);
322
323         return ldb_msg_add_fmt(msg, attrib, "%llu", (unsigned long long) nt_time);
324 }
325
326 static int pdb_samba_dsdb_replace_by_sam(struct pdb_samba_dsdb_state *state,
327                                      bool (*need_update)(const struct samu *,
328                                                          enum pdb_elements),
329                                      struct ldb_dn *dn,
330                                      struct samu *sam)
331 {
332         TALLOC_CTX *frame = talloc_stackframe();
333         int ret = LDB_SUCCESS;
334         const char *pw;
335         struct ldb_message *msg;
336         struct ldb_request *req;
337         uint32_t dsdb_flags = 0;
338         /* TODO: All fields :-) */
339
340         msg = ldb_msg_new(frame);
341         if (!msg) {
342                 talloc_free(frame);
343                 return false;
344         }
345
346         msg->dn = dn;
347
348         /* build modify request */
349         ret = ldb_build_mod_req(&req, state->ldb, frame, msg, NULL, NULL,
350                                 ldb_op_default_callback,
351                                 NULL);
352         if (ret != LDB_SUCCESS) {
353                 talloc_free(frame);
354                 return ret;
355         }
356
357         /* If we set a plaintext password, the system will
358          * force the pwdLastSet to now() */
359         if (need_update(sam, PDB_PASSLASTSET)) {
360                 dsdb_flags = DSDB_PASSWORD_BYPASS_LAST_SET;
361
362                 ret |= pdb_samba_dsdb_add_time(msg, "pwdLastSet",
363                                            pdb_get_pass_last_set_time(sam));
364         }
365
366         pw = pdb_get_plaintext_passwd(sam);
367         if (need_update(sam, PDB_PLAINTEXT_PW)) {
368                 struct ldb_val pw_utf16;
369                 if (pw == NULL) {
370                         talloc_free(frame);
371                         return LDB_ERR_OPERATIONS_ERROR;
372                 }
373
374                 if (!convert_string_talloc(msg,
375                                            CH_UNIX, CH_UTF16,
376                                            pw, strlen(pw),
377                                            (void *)&pw_utf16.data,
378                                            &pw_utf16.length)) {
379                         talloc_free(frame);
380                         return LDB_ERR_OPERATIONS_ERROR;
381                 }
382                 ret |= ldb_msg_add_value(msg, "clearTextPassword", &pw_utf16, NULL);
383         } else {
384                 bool changed_lm_pw = false;
385                 bool changed_nt_pw = false;
386                 bool changed_history = false;
387                 if (need_update(sam, PDB_LMPASSWD)) {
388                         struct ldb_val val;
389                         val.data = discard_const_p(uint8_t, pdb_get_lanman_passwd(sam));
390                         if (!val.data) {
391                                 samdb_msg_add_delete(state->ldb, msg, msg,
392                                                      "dBCSPwd");
393                         } else {
394                                 val.length = LM_HASH_LEN;
395                                 ret |= ldb_msg_add_value(msg, "dBCSPwd", &val, NULL);
396                         }
397                         changed_lm_pw = true;
398                 }
399                 if (need_update(sam, PDB_NTPASSWD)) {
400                         struct ldb_val val;
401                         val.data = discard_const_p(uint8_t, pdb_get_nt_passwd(sam));
402                         if (!val.data) {
403                                 samdb_msg_add_delete(state->ldb, msg, msg,
404                                                      "unicodePwd");
405                         } else {
406                                 val.length = NT_HASH_LEN;
407                                 ret |= ldb_msg_add_value(msg, "unicodePwd", &val, NULL);
408                         }
409                         changed_nt_pw = true;
410                 }
411
412                 /* Try to ensure we don't get out of sync */
413                 if (changed_lm_pw && !changed_nt_pw) {
414                         samdb_msg_add_delete(state->ldb, msg, msg,
415                                              "unicodePwd");
416                 } else if (changed_nt_pw && !changed_lm_pw) {
417                         samdb_msg_add_delete(state->ldb, msg, msg,
418                                              "dBCSPwd");
419                 }
420                 if (changed_lm_pw || changed_nt_pw) {
421                         samdb_msg_add_delete(state->ldb, msg, msg,
422                                              "supplementalCredentials");
423
424                 }
425
426                 if (need_update(sam, PDB_PWHISTORY)) {
427                         uint32_t current_hist_len;
428                         const uint8_t *history = pdb_get_pw_history(sam, &current_hist_len);
429
430                         bool invalid_history = false;
431                         struct samr_Password *history_hashes = talloc_array(talloc_tos(), struct samr_Password,
432                                                                             current_hist_len);
433                         if (!history) {
434                                 invalid_history = true;
435                         } else {
436                                 unsigned int i;
437                                 static const uint8_t zeros[16];
438                                 /* Parse the history into the correct format */
439                                 for (i = 0; i < current_hist_len; i++) {
440                                         if (memcmp(&history[i*PW_HISTORY_ENTRY_LEN], zeros, 16) != 0) {
441                                                 /* If the history is in the old format, with a salted hash, then we can't migrate it to AD format */
442                                                 invalid_history = true;
443                                                 break;
444                                         }
445                                         /* Copy out the 2nd 16 bytes of the 32 byte password history, containing the NT hash */
446                                         memcpy(history_hashes[i].hash,
447                                                &history[(i*PW_HISTORY_ENTRY_LEN) + PW_HISTORY_SALT_LEN],
448                                                sizeof(history_hashes[i].hash));
449                                 }
450                         }
451                         if (invalid_history) {
452                                 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
453                                                      "ntPwdHistory");
454
455                                 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
456                                                      "lmPwdHistory");
457                         } else {
458                                 ret |= samdb_msg_add_hashes(state->ldb, msg, msg,
459                                                             "ntPwdHistory",
460                                                             history_hashes,
461                                                             current_hist_len);
462                         }
463                         changed_history = true;
464                 }
465                 if (changed_lm_pw || changed_nt_pw || changed_history) {
466                         /* These attributes can only be modified directly by using a special control */
467                         dsdb_flags = DSDB_BYPASS_PASSWORD_HASH;
468                 }
469         }
470
471         /* PDB_USERSID is only allowed on ADD, handled in caller */
472         if (need_update(sam, PDB_GROUPSID)) {
473                 const struct dom_sid *sid = pdb_get_group_sid(sam);
474                 uint32_t rid;
475                 NTSTATUS status = dom_sid_split_rid(NULL, sid, NULL, &rid);
476                 if (!NT_STATUS_IS_OK(status)) {
477                         talloc_free(frame);
478                         return LDB_ERR_OPERATIONS_ERROR;
479                 }
480                 if (!dom_sid_in_domain(samdb_domain_sid(state->ldb), sid)) {
481                         talloc_free(frame);
482                         return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
483                 }
484                 ret |= samdb_msg_add_uint(state->ldb, msg, msg, "primaryGroupID", rid);
485         }
486         if (need_update(sam, PDB_FULLNAME)) {
487                 ret |= ldb_msg_add_string(msg, "displayName", pdb_get_fullname(sam));
488         }
489
490         if (need_update(sam, PDB_SMBHOME)) {
491                 ret |= ldb_msg_add_string(msg, "homeDirectory",
492                                           pdb_get_homedir(sam));
493         }
494
495         if (need_update(sam, PDB_PROFILE)) {
496                 ret |= ldb_msg_add_string(msg, "profilePath",
497                                           pdb_get_profile_path(sam));
498         }
499
500         if (need_update(sam, PDB_DRIVE)) {
501                 ret |= ldb_msg_add_string(msg, "homeDrive",
502                                           pdb_get_dir_drive(sam));
503         }
504
505         if (need_update(sam, PDB_LOGONSCRIPT)) {
506                 ret |= ldb_msg_add_string(msg, "scriptPath",
507                                           pdb_get_logon_script(sam));
508         }
509
510         if (need_update(sam, PDB_KICKOFFTIME)) {
511                 ret |= pdb_samba_dsdb_add_time(msg, "accountExpires",
512                                         pdb_get_kickoff_time(sam));
513         }
514
515         if (need_update(sam, PDB_LOGONTIME)) {
516                 ret |= pdb_samba_dsdb_add_time(msg, "lastLogon",
517                                         pdb_get_logon_time(sam));
518         }
519
520         if (need_update(sam, PDB_LOGOFFTIME)) {
521                 ret |= pdb_samba_dsdb_add_time(msg, "lastLogoff",
522                                         pdb_get_logoff_time(sam));
523         }
524
525         if (need_update(sam, PDB_USERNAME)) {
526                 ret |= ldb_msg_add_string(msg, "samAccountName",
527                                           pdb_get_username(sam));
528         }
529
530         if (need_update(sam, PDB_HOURSLEN) || need_update(sam, PDB_HOURS)) {
531                 struct ldb_val hours = data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam));
532                 ret |= ldb_msg_add_value(msg, "logonHours",
533                                          &hours, NULL);
534         }
535
536         if (need_update(sam, PDB_ACCTCTRL)) {
537                 ret |= samdb_msg_add_acct_flags(state->ldb, msg, msg,
538                                                 "userAccountControl", pdb_get_acct_ctrl(sam));
539         }
540
541         if (need_update(sam, PDB_COMMENT)) {
542                 ret |= ldb_msg_add_string(msg, "comment",
543                                           pdb_get_comment(sam));
544         }
545
546         if (need_update(sam, PDB_ACCTDESC)) {
547                 ret |= ldb_msg_add_string(msg, "description",
548                                           pdb_get_acct_desc(sam));
549         }
550
551         if (need_update(sam, PDB_WORKSTATIONS)) {
552                 ret |= ldb_msg_add_string(msg, "userWorkstations",
553                                           pdb_get_workstations(sam));
554         }
555
556         /* This will need work, it is actually a UTF8 'string' with internal NULLs, to handle TS parameters */
557         if (need_update(sam, PDB_MUNGEDDIAL)) {
558                 ret |= ldb_msg_add_string(msg, "userParameters",
559                                           pdb_get_munged_dial(sam));
560         }
561
562         if (need_update(sam, PDB_COUNTRY_CODE)) {
563                 ret |= ldb_msg_add_fmt(msg, "countryCode",
564                                        "%i", (int)pdb_get_country_code(sam));
565         }
566
567         if (need_update(sam, PDB_CODE_PAGE)) {
568                 ret |= ldb_msg_add_fmt(msg, "codePage",
569                                        "%i", (int)pdb_get_code_page(sam));
570         }
571
572         /* Not yet handled here or not meaningful for modifies on a Samba_Dsdb backend:
573         PDB_BAD_PASSWORD_TIME,
574         PDB_CANCHANGETIME, - these are calculated per policy, not stored
575         PDB_DOMAIN,
576         PDB_NTUSERNAME, - this makes no sense, and never really did
577         PDB_LOGONDIVS,
578         PDB_USERSID, - Handled in pdb_samba_dsdb_add_sam_account()
579         PDB_FIELDS_PRESENT,
580         PDB_BAD_PASSWORD_COUNT,
581         PDB_LOGON_COUNT,
582         PDB_UNKNOWN6,
583         PDB_BACKEND_PRIVATE_DATA,
584
585  */
586         if (ret != LDB_SUCCESS) {
587                 talloc_free(frame);
588                 return LDB_ERR_OPERATIONS_ERROR;
589         }
590
591         if (msg->num_elements == 0) {
592                 talloc_free(frame);
593                 /* Nothing to do, just return success */
594                 return LDB_SUCCESS;
595         }
596
597         ret = dsdb_replace(state->ldb, msg, dsdb_flags);
598
599         if (ret != LDB_SUCCESS) {
600                 DEBUG(0,("Failed to modify account record %s to set user attributes: %s\n",
601                          ldb_dn_get_linearized(msg->dn),
602                          ldb_errstring(state->ldb)));
603         }
604
605         talloc_free(frame);
606         return ret;
607 }
608
609 static NTSTATUS pdb_samba_dsdb_getsamupriv(struct pdb_samba_dsdb_state *state,
610                                     const char *filter,
611                                     TALLOC_CTX *mem_ctx,
612                                     struct ldb_message **msg)
613 {
614         const char * attrs[] = {
615                 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
616                 "sAMAccountName", "displayName", "homeDirectory",
617                 "homeDrive", "scriptPath", "profilePath", "description",
618                 "userWorkstations", "comment", "userParameters", "objectSid",
619                 "primaryGroupID", "userAccountControl",
620                 "msDS-User-Account-Control-Computed", "logonHours",
621                 "badPwdCount", "logonCount", "countryCode", "codePage",
622                 "unicodePwd", "dBCSPwd", NULL };
623
624         int rc = dsdb_search_one(state->ldb, mem_ctx, msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", filter);
625         if (rc != LDB_SUCCESS) {
626                 DEBUG(10, ("ldap_search failed %s\n",
627                            ldb_errstring(state->ldb)));
628                 return NT_STATUS_LDAP(rc);
629         }
630
631         return NT_STATUS_OK;
632 }
633
634 static NTSTATUS pdb_samba_dsdb_getsampwfilter(struct pdb_methods *m,
635                                           struct pdb_samba_dsdb_state *state,
636                                           struct samu *sam_acct,
637                                           const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
638 {
639         struct ldb_message *priv;
640         NTSTATUS status;
641         va_list ap;
642         char *expression = NULL;
643         TALLOC_CTX *tmp_ctx = talloc_new(state);
644         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
645
646         va_start(ap, exp_fmt);
647         expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
648         va_end(ap);
649
650         if (!expression) {
651                 talloc_free(tmp_ctx);
652                 return NT_STATUS_NO_MEMORY;
653         }
654
655         status = pdb_samba_dsdb_getsamupriv(state, expression, sam_acct, &priv);
656         talloc_free(tmp_ctx);
657         if (!NT_STATUS_IS_OK(status)) {
658                 DEBUG(10, ("pdb_samba_dsdb_getsamupriv failed: %s\n",
659                            nt_errstr(status)));
660                 return status;
661         }
662
663         status = pdb_samba_dsdb_init_sam_from_priv(m, sam_acct, priv);
664         if (!NT_STATUS_IS_OK(status)) {
665                 DEBUG(10, ("pdb_samba_dsdb_init_sam_from_priv failed: %s\n",
666                            nt_errstr(status)));
667                 TALLOC_FREE(priv);
668                 return status;
669         }
670
671         pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
672         return NT_STATUS_OK;
673 }
674
675 static NTSTATUS pdb_samba_dsdb_getsampwnam(struct pdb_methods *m,
676                                     struct samu *sam_acct,
677                                     const char *username)
678 {
679         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
680                 m->private_data, struct pdb_samba_dsdb_state);
681
682         return pdb_samba_dsdb_getsampwfilter(m, state, sam_acct,
683                                          "(&(samaccountname=%s)(objectclass=user))",
684                                          username);
685 }
686
687 static NTSTATUS pdb_samba_dsdb_getsampwsid(struct pdb_methods *m,
688                                     struct samu *sam_acct,
689                                     const struct dom_sid *sid)
690 {
691         NTSTATUS status;
692         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
693                 m->private_data, struct pdb_samba_dsdb_state);
694         char *sidstr;
695
696         sidstr = dom_sid_string(talloc_tos(), sid);
697         NT_STATUS_HAVE_NO_MEMORY(sidstr);
698
699         status = pdb_samba_dsdb_getsampwfilter(m, state, sam_acct,
700                                            "(&(objectsid=%s)(objectclass=user))",
701                                            sidstr);
702         talloc_free(sidstr);
703         return status;
704 }
705
706 static NTSTATUS pdb_samba_dsdb_create_user(struct pdb_methods *m,
707                                     TALLOC_CTX *mem_ctx,
708                                     const char *name, uint32 acct_flags,
709                                     uint32 *rid)
710 {
711         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
712                 m->private_data, struct pdb_samba_dsdb_state);
713         struct dom_sid *sid;
714         struct ldb_dn *dn;
715         NTSTATUS status;
716         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
717         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
718
719         /* Internally this uses transactions to ensure all the steps
720          * happen or fail as one */
721         status = dsdb_add_user(state->ldb, tmp_ctx, name, acct_flags, NULL,
722                                &sid, &dn);
723         if (!NT_STATUS_IS_OK(status)) {
724                 talloc_free(tmp_ctx);
725                 return status;
726         }
727         sid_peek_rid(sid, rid);
728         talloc_free(tmp_ctx);
729         return NT_STATUS_OK;
730 }
731
732 static NTSTATUS pdb_samba_dsdb_delete_user(struct pdb_methods *m,
733                                        TALLOC_CTX *mem_ctx,
734                                        struct samu *sam)
735 {
736         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
737                 m->private_data, struct pdb_samba_dsdb_state);
738         struct ldb_dn *dn;
739         int rc;
740         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
741         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
742
743         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, pdb_get_user_sid(sam)));
744         if (!dn || !ldb_dn_validate(dn)) {
745                 talloc_free(tmp_ctx);
746                 return NT_STATUS_NO_MEMORY;
747         }
748         rc = ldb_delete(state->ldb, dn);
749
750         if (rc != LDB_SUCCESS) {
751                 DEBUG(10, ("ldb_delete for %s failed: %s\n", ldb_dn_get_linearized(dn),
752                            ldb_errstring(state->ldb)));
753                 talloc_free(tmp_ctx);
754                 return NT_STATUS_LDAP(rc);
755         }
756         talloc_free(tmp_ctx);
757         return NT_STATUS_OK;
758 }
759
760 /* This interface takes a fully populated struct samu and places it in
761  * the database.  This is not implemented at this time as we need to
762  * be careful around the creation of arbitary SIDs (ie, we must ensrue
763  * they are not left in a RID pool */
764 static NTSTATUS pdb_samba_dsdb_add_sam_account(struct pdb_methods *m,
765                                         struct samu *sampass)
766 {
767         int ret;
768         NTSTATUS status;
769         struct ldb_dn *dn;
770         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
771                 m->private_data, struct pdb_samba_dsdb_state);
772         uint32_t acb_flags = pdb_get_acct_ctrl(sampass);
773         const char *username = pdb_get_username(sampass);
774         const struct dom_sid *user_sid = pdb_get_user_sid(sampass);
775         TALLOC_CTX *tframe = talloc_stackframe();
776
777         acb_flags &= (ACB_NORMAL|ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST);
778
779         ret = ldb_transaction_start(state->ldb);
780         if (ret != LDB_SUCCESS) {
781                 talloc_free(tframe);
782                 return NT_STATUS_LOCK_NOT_GRANTED;
783         }
784
785         status = dsdb_add_user(state->ldb, talloc_tos(), username,
786                                acb_flags, user_sid, NULL, &dn);
787         if (!NT_STATUS_IS_OK(status)) {
788                 ldb_transaction_cancel(state->ldb);
789                 talloc_free(tframe);
790                 return status;
791         }
792
793         ret = pdb_samba_dsdb_replace_by_sam(state, pdb_element_is_set_or_changed,
794                                         dn, sampass);
795         if (ret != LDB_SUCCESS) {
796                 ldb_transaction_cancel(state->ldb);
797                 talloc_free(tframe);
798                 return dsdb_ldb_err_to_ntstatus(ret);
799         }
800
801         ret = ldb_transaction_commit(state->ldb);
802         if (ret != LDB_SUCCESS) {
803                 DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
804                          ldb_dn_get_linearized(dn),
805                          ldb_errstring(state->ldb)));
806                 talloc_free(tframe);
807                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
808         }
809         talloc_free(tframe);
810         return NT_STATUS_OK;
811 }
812
813 /*
814  * Update the Samba_Dsdb LDB with the changes from a struct samu.
815  *
816  * This takes care not to update elements that have not been changed
817  * by the caller
818  */
819 static NTSTATUS pdb_samba_dsdb_update_sam_account(struct pdb_methods *m,
820                                            struct samu *sam)
821 {
822         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
823                 m->private_data, struct pdb_samba_dsdb_state);
824         struct ldb_message *msg = pdb_samba_dsdb_get_samu_private(
825                 m, sam);
826         int ret;
827
828         ret = pdb_samba_dsdb_replace_by_sam(state, pdb_element_is_changed, msg->dn,
829                                         sam);
830         return dsdb_ldb_err_to_ntstatus(ret);
831 }
832
833 static NTSTATUS pdb_samba_dsdb_delete_sam_account(struct pdb_methods *m,
834                                            struct samu *username)
835 {
836         NTSTATUS status;
837         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
838         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
839         status = pdb_samba_dsdb_delete_user(m, tmp_ctx, username);
840         talloc_free(tmp_ctx);
841         return status;
842 }
843
844 static NTSTATUS pdb_samba_dsdb_rename_sam_account(struct pdb_methods *m,
845                                            struct samu *oldname,
846                                            const char *newname)
847 {
848         return NT_STATUS_NOT_IMPLEMENTED;
849 }
850
851 /* This is not implemented, as this module is exptected to be used
852  * with auth_samba_dsdb, and this is responible for login counters etc
853  *
854  */
855 static NTSTATUS pdb_samba_dsdb_update_login_attempts(struct pdb_methods *m,
856                                               struct samu *sam_acct,
857                                               bool success)
858 {
859         return NT_STATUS_NOT_IMPLEMENTED;
860 }
861
862 static NTSTATUS pdb_samba_dsdb_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
863                                     const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
864 {
865         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
866                 m->private_data, struct pdb_samba_dsdb_state);
867         const char *attrs[] = { "objectSid", "description", "samAccountName", "groupType",
868                                 NULL };
869         struct ldb_message *msg;
870         va_list ap;
871         char *expression = NULL;
872         struct dom_sid *sid;
873         const char *str;
874         int rc;
875         struct id_map id_map;
876         struct id_map *id_maps[2];
877         TALLOC_CTX *tmp_ctx = talloc_stackframe();
878         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
879
880         va_start(ap, exp_fmt);
881         expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
882         va_end(ap);
883
884         if (!expression) {
885                 talloc_free(tmp_ctx);
886                 return NT_STATUS_NO_MEMORY;
887         }
888
889         rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
890         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
891                 talloc_free(tmp_ctx);
892                 return NT_STATUS_NO_SUCH_GROUP;
893         } else if (rc != LDB_SUCCESS) {
894                 talloc_free(tmp_ctx);
895                 DEBUG(10, ("dsdb_search_one failed %s\n",
896                            ldb_errstring(state->ldb)));
897                 return NT_STATUS_LDAP(rc);
898         }
899
900         sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
901         if (!sid) {
902                 talloc_free(tmp_ctx);
903                 DEBUG(10, ("Could not pull SID\n"));
904                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
905         }
906
907         map->sid = *sid;
908
909         if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
910                 NTSTATUS status;
911                 uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
912                 switch (grouptype) {
913                 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
914                 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
915                         map->sid_name_use = SID_NAME_ALIAS;
916                         break;
917                 case GTYPE_SECURITY_GLOBAL_GROUP:
918                         map->sid_name_use = SID_NAME_DOM_GRP;
919                         break;
920                 default:
921                         talloc_free(tmp_ctx);
922                         DEBUG(10, ("Could not pull groupType\n"));
923                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
924                 }
925
926                 map->sid_name_use = SID_NAME_DOM_GRP;
927
928                 ZERO_STRUCT(id_map);
929                 id_map.sid = sid;
930                 id_maps[0] = &id_map;
931                 id_maps[1] = NULL;
932
933                 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
934                 talloc_free(tmp_ctx);
935                 if (!NT_STATUS_IS_OK(status)) {
936                         talloc_free(tmp_ctx);
937                         return status;
938                 }
939                 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
940                         map->gid = id_map.xid.id;
941                 } else {
942                         DEBUG(1, (__location__ "Did not get GUID when mapping SID for %s", expression));
943                         talloc_free(tmp_ctx);
944                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
945                 }
946         } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
947                 DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
948                 talloc_free(tmp_ctx);
949                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
950         }
951
952         str = ldb_msg_find_attr_as_string(msg, "samAccountName",
953                                           NULL);
954         if (str == NULL) {
955                 talloc_free(tmp_ctx);
956                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
957         }
958         map->nt_name = talloc_strdup(map, str);
959         if (!map->nt_name) {
960                 talloc_free(tmp_ctx);
961                 return NT_STATUS_NO_MEMORY;
962         }
963
964         str = ldb_msg_find_attr_as_string(msg, "description",
965                                             NULL);
966         if (str != NULL) {
967                 map->comment = talloc_strdup(map, str);
968         } else {
969                 map->comment = talloc_strdup(map, "");
970         }
971         if (!map->comment) {
972                 talloc_free(tmp_ctx);
973                 return NT_STATUS_NO_MEMORY;
974         }
975
976         talloc_free(tmp_ctx);
977         return NT_STATUS_OK;
978 }
979
980 static NTSTATUS pdb_samba_dsdb_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
981                                  struct dom_sid sid)
982 {
983         char *filter;
984         NTSTATUS status;
985
986         filter = talloc_asprintf(talloc_tos(),
987                                  "(&(objectsid=%s)(objectclass=group))",
988                                  sid_string_talloc(talloc_tos(), &sid));
989         if (filter == NULL) {
990                 return NT_STATUS_NO_MEMORY;
991         }
992
993         status = pdb_samba_dsdb_getgrfilter(m, map, filter);
994         TALLOC_FREE(filter);
995         return status;
996 }
997
998 static NTSTATUS pdb_samba_dsdb_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
999                                  gid_t gid)
1000 {
1001         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1002                 m->private_data, struct pdb_samba_dsdb_state);
1003         NTSTATUS status;
1004         struct id_map id_map;
1005         struct id_map *id_maps[2];
1006         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1007         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1008
1009         id_map.xid.id = gid;
1010         id_map.xid.type = ID_TYPE_GID;
1011         id_maps[0] = &id_map;
1012         id_maps[1] = NULL;
1013
1014         status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1015         if (!NT_STATUS_IS_OK(status)) {
1016                 talloc_free(tmp_ctx);
1017                 return status;
1018         }
1019         status = pdb_samba_dsdb_getgrsid(m, map, *id_map.sid);
1020         talloc_free(tmp_ctx);
1021         return status;
1022 }
1023
1024 static NTSTATUS pdb_samba_dsdb_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
1025                                  const char *name)
1026 {
1027         char *filter;
1028         NTSTATUS status;
1029
1030         filter = talloc_asprintf(talloc_tos(),
1031                                  "(&(samaccountname=%s)(objectclass=group))",
1032                                  name);
1033         if (filter == NULL) {
1034                 return NT_STATUS_NO_MEMORY;
1035         }
1036
1037         status = pdb_samba_dsdb_getgrfilter(m, map, filter);
1038         TALLOC_FREE(filter);
1039         return status;
1040 }
1041
1042 static NTSTATUS pdb_samba_dsdb_create_dom_group(struct pdb_methods *m,
1043                                          TALLOC_CTX *mem_ctx, const char *name,
1044                                          uint32 *rid)
1045 {
1046         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1047                 m->private_data, struct pdb_samba_dsdb_state);
1048         NTSTATUS status;
1049         struct dom_sid *sid;
1050         struct ldb_dn *dn;
1051         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1052         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1053
1054         status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
1055         if (!NT_STATUS_IS_OK(status)) {
1056                 talloc_free(tmp_ctx);
1057                 return status;
1058         }
1059
1060         sid_peek_rid(sid, rid);
1061         talloc_free(tmp_ctx);
1062         return NT_STATUS_OK;
1063 }
1064
1065 static NTSTATUS pdb_samba_dsdb_delete_dom_group(struct pdb_methods *m,
1066                                          TALLOC_CTX *mem_ctx, uint32 rid)
1067 {
1068         const char *attrs[] = { NULL };
1069         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1070                 m->private_data, struct pdb_samba_dsdb_state);
1071         struct dom_sid sid;
1072         struct ldb_message *msg;
1073         struct ldb_dn *dn;
1074         int rc;
1075         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1076         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1077
1078         sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
1079
1080         if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1081                 DEBUG(0, ("Unable to start transaction in pdb_samba_dsdb_delete_dom_group()\n"));
1082                 return NT_STATUS_INTERNAL_ERROR;
1083         }
1084
1085         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
1086         if (!dn || !ldb_dn_validate(dn)) {
1087                 talloc_free(tmp_ctx);
1088                 ldb_transaction_cancel(state->ldb);
1089                 return NT_STATUS_NO_MEMORY;
1090         }
1091         rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
1092         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1093                 talloc_free(tmp_ctx);
1094                 ldb_transaction_cancel(state->ldb);
1095                 return NT_STATUS_NO_SUCH_GROUP;
1096         }
1097         rc = ldb_delete(state->ldb, dn);
1098         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1099                 talloc_free(tmp_ctx);
1100                 ldb_transaction_cancel(state->ldb);
1101                 return NT_STATUS_NO_SUCH_GROUP;
1102         } else if (rc != LDB_SUCCESS) {
1103                 DEBUG(10, ("ldb_delete failed %s\n",
1104                            ldb_errstring(state->ldb)));
1105                 ldb_transaction_cancel(state->ldb);
1106                 return NT_STATUS_LDAP(rc);
1107         }
1108
1109         if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1110                 DEBUG(0, ("Unable to commit transaction in pdb_samba_dsdb_delete_dom_group()\n"));
1111                 return NT_STATUS_INTERNAL_ERROR;
1112         }
1113         return NT_STATUS_OK;
1114 }
1115
1116 static NTSTATUS pdb_samba_dsdb_add_group_mapping_entry(struct pdb_methods *m,
1117                                                 GROUP_MAP *map)
1118 {
1119         return NT_STATUS_NOT_IMPLEMENTED;
1120 }
1121
1122 static NTSTATUS pdb_samba_dsdb_update_group_mapping_entry(struct pdb_methods *m,
1123                                                    GROUP_MAP *map)
1124 {
1125         return NT_STATUS_NOT_IMPLEMENTED;
1126 }
1127
1128 static NTSTATUS pdb_samba_dsdb_delete_group_mapping_entry(struct pdb_methods *m,
1129                                                    struct dom_sid sid)
1130 {
1131         return NT_STATUS_NOT_IMPLEMENTED;
1132 }
1133
1134 static NTSTATUS pdb_samba_dsdb_enum_group_mapping(struct pdb_methods *m,
1135                                            const struct dom_sid *sid,
1136                                            enum lsa_SidType sid_name_use,
1137                                            GROUP_MAP ***pp_rmap,
1138                                            size_t *p_num_entries,
1139                                            bool unix_only)
1140 {
1141         return NT_STATUS_NOT_IMPLEMENTED;
1142 }
1143
1144 static NTSTATUS pdb_samba_dsdb_enum_group_members(struct pdb_methods *m,
1145                                            TALLOC_CTX *mem_ctx,
1146                                            const struct dom_sid *group,
1147                                            uint32_t **pmembers,
1148                                            size_t *pnum_members)
1149 {
1150         unsigned int i, num_sids, num_members;
1151         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1152                 m->private_data, struct pdb_samba_dsdb_state);
1153         struct dom_sid *members_as_sids;
1154         struct dom_sid *dom_sid;
1155         uint32_t *members;
1156         struct ldb_dn *dn;
1157         NTSTATUS status;
1158
1159         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1160         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1161
1162         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
1163         if (!dn || !ldb_dn_validate(dn)) {
1164                 return NT_STATUS_NO_MEMORY;
1165         }
1166
1167         status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
1168         if (!NT_STATUS_IS_OK(status)) {
1169                 talloc_free(tmp_ctx);
1170                 return status;
1171         }
1172         status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
1173         if (!NT_STATUS_IS_OK(status)) {
1174                 talloc_free(tmp_ctx);
1175                 return status;
1176         }
1177
1178         *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
1179         if (*pmembers == NULL) {
1180                 TALLOC_FREE(tmp_ctx);
1181                 return NT_STATUS_NO_MEMORY;
1182         }
1183         num_members = 0;
1184
1185         for (i = 0; i < num_sids; i++) {
1186                 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
1187                         continue;
1188                 }
1189                 status = dom_sid_split_rid(NULL, &members_as_sids[i],
1190                                            NULL, &members[num_members]);
1191                 if (!NT_STATUS_IS_OK(status)) {
1192                         talloc_free(tmp_ctx);
1193                         return status;
1194                 }
1195                 num_members++;
1196         }
1197         *pnum_members = num_members;
1198         return NT_STATUS_OK;
1199 }
1200
1201 /* Just convert the primary group SID into a group */
1202 static NTSTATUS fake_enum_group_memberships(struct pdb_samba_dsdb_state *state,
1203                                             TALLOC_CTX *mem_ctx,
1204                                             struct samu *user,
1205                                             struct dom_sid **pp_sids,
1206                                             gid_t **pp_gids,
1207                                             uint32_t *p_num_groups)
1208 {
1209         NTSTATUS status;
1210         size_t num_groups = 0;
1211         struct dom_sid *group_sids = NULL;
1212         gid_t *gids = NULL;
1213         TALLOC_CTX *tmp_ctx;
1214
1215         tmp_ctx = talloc_new(mem_ctx);
1216         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1217
1218         if (user->group_sid) {
1219                 struct id_map *id_maps[2];
1220                 struct id_map id_map;
1221
1222                 num_groups = 1;
1223
1224                 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1225                 if (group_sids == NULL) {
1226                         talloc_free(tmp_ctx);
1227                         return NT_STATUS_NO_MEMORY;
1228                 }
1229                 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1230                 if (gids == NULL) {
1231                         talloc_free(tmp_ctx);
1232                         return NT_STATUS_NO_MEMORY;
1233                 }
1234
1235                 group_sids[0] = *user->group_sid;
1236
1237                 ZERO_STRUCT(id_map);
1238                 id_map.sid = &group_sids[0];
1239                 id_maps[0] = &id_map;
1240                 id_maps[1] = NULL;
1241
1242                 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1243                 if (!NT_STATUS_IS_OK(status)) {
1244                         talloc_free(tmp_ctx);
1245                         return status;
1246                 }
1247                 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1248                         gids[0] = id_map.xid.id;
1249                 } else {
1250                         DEBUG(1, (__location__
1251                                   "Group %s, of which %s is a member, could not be converted to a GID\n",
1252                                   dom_sid_string(tmp_ctx, &group_sids[0]),
1253                                   dom_sid_string(tmp_ctx, &user->user_sid)));
1254                         talloc_free(tmp_ctx);
1255                         /* We must error out, otherwise a user might
1256                          * avoid a DENY acl based on a group they
1257                          * missed out on */
1258                         return NT_STATUS_NO_SUCH_GROUP;
1259                 }
1260         }
1261
1262         *pp_sids = talloc_steal(mem_ctx, group_sids);
1263         *pp_gids = talloc_steal(mem_ctx, gids);
1264         *p_num_groups = num_groups;
1265         talloc_free(tmp_ctx);
1266         return NT_STATUS_OK;
1267 }
1268
1269 static NTSTATUS pdb_samba_dsdb_enum_group_memberships(struct pdb_methods *m,
1270                                                TALLOC_CTX *mem_ctx,
1271                                                struct samu *user,
1272                                                struct dom_sid **pp_sids,
1273                                                gid_t **pp_gids,
1274                                                uint32_t *p_num_groups)
1275 {
1276         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1277                 m->private_data, struct pdb_samba_dsdb_state);
1278         struct ldb_message *msg = pdb_samba_dsdb_get_samu_private(
1279                 m, user);
1280         const char *attrs[] = { "tokenGroups", NULL};
1281         struct ldb_message *tokengroups_msg;
1282         struct ldb_message_element *tokengroups;
1283         int i, rc;
1284         NTSTATUS status;
1285         unsigned int count = 0;
1286         size_t num_groups;
1287         struct dom_sid *group_sids;
1288         gid_t *gids;
1289         TALLOC_CTX *tmp_ctx;
1290
1291         if (msg == NULL) {
1292                 /* Fake up some things here */
1293                 return fake_enum_group_memberships(state,
1294                                                    mem_ctx,
1295                                                    user, pp_sids,
1296                                                    pp_gids, p_num_groups);
1297         }
1298
1299         tmp_ctx = talloc_new(mem_ctx);
1300         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1301
1302         rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1303
1304         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1305                 talloc_free(tmp_ctx);
1306                 return NT_STATUS_NO_SUCH_USER;
1307         } else if (rc != LDB_SUCCESS) {
1308                 DEBUG(10, ("dsdb_search_one failed %s\n",
1309                            ldb_errstring(state->ldb)));
1310                 talloc_free(tmp_ctx);
1311                 return NT_STATUS_LDAP(rc);
1312         }
1313
1314         tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1315
1316         if (tokengroups) {
1317                 count = tokengroups->num_values;
1318         }
1319
1320         group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1321         if (group_sids == NULL) {
1322                 talloc_free(tmp_ctx);
1323                 return NT_STATUS_NO_MEMORY;
1324         }
1325         gids = talloc_array(tmp_ctx, gid_t, count);
1326         if (gids == NULL) {
1327                 talloc_free(tmp_ctx);
1328                 return NT_STATUS_NO_MEMORY;
1329         }
1330         num_groups = 0;
1331
1332         for (i=0; i<count; i++) {
1333                 struct id_map *id_maps[2];
1334                 struct id_map id_map;
1335                 struct ldb_val *v = &tokengroups->values[i];
1336                 enum ndr_err_code ndr_err
1337                         = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1338                                                (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1339                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1340                         talloc_free(tmp_ctx);
1341                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1342                 }
1343
1344                 ZERO_STRUCT(id_map);
1345                 id_map.sid = &group_sids[num_groups];
1346                 id_maps[0] = &id_map;
1347                 id_maps[1] = NULL;
1348
1349                 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1350                 if (!NT_STATUS_IS_OK(status)) {
1351                         talloc_free(tmp_ctx);
1352                         return status;
1353                 }
1354                 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1355                         gids[num_groups] = id_map.xid.id;
1356                 } else {
1357                         DEBUG(1, (__location__
1358                                   "Group %s, of which %s is a member, could not be converted to a GID\n",
1359                                   dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1360                                   ldb_dn_get_linearized(msg->dn)));
1361                         talloc_free(tmp_ctx);
1362                         /* We must error out, otherwise a user might
1363                          * avoid a DENY acl based on a group they
1364                          * missed out on */
1365                         return NT_STATUS_NO_SUCH_GROUP;
1366                 }
1367
1368                 num_groups += 1;
1369                 if (num_groups == count) {
1370                         break;
1371                 }
1372         }
1373
1374         *pp_sids = talloc_steal(mem_ctx, group_sids);
1375         *pp_gids = talloc_steal(mem_ctx, gids);
1376         *p_num_groups = num_groups;
1377         talloc_free(tmp_ctx);
1378         return NT_STATUS_OK;
1379 }
1380
1381 static NTSTATUS pdb_samba_dsdb_set_unix_primary_group(struct pdb_methods *m,
1382                                                TALLOC_CTX *mem_ctx,
1383                                                struct samu *user)
1384 {
1385         return NT_STATUS_NOT_IMPLEMENTED;
1386 }
1387
1388 static NTSTATUS pdb_samba_dsdb_mod_groupmem_by_sid(struct pdb_methods *m,
1389                                                TALLOC_CTX *mem_ctx,
1390                                                const struct dom_sid *groupsid,
1391                                                const struct dom_sid *membersid,
1392                                                int mod_op)
1393 {
1394         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1395                 m->private_data, struct pdb_samba_dsdb_state);
1396         struct ldb_message *msg;
1397         int ret;
1398         struct ldb_message_element *el;
1399         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1400         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1401         msg = ldb_msg_new(tmp_ctx);
1402         if (msg == NULL) {
1403                 TALLOC_FREE(tmp_ctx);
1404                 return NT_STATUS_NO_MEMORY;
1405         }
1406
1407         msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1408         if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1409                 talloc_free(tmp_ctx);
1410                 return NT_STATUS_NO_MEMORY;
1411         }
1412         ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1413         if (ret != LDB_SUCCESS) {
1414                 talloc_free(tmp_ctx);
1415                 return NT_STATUS_NO_MEMORY;
1416         }
1417         el = ldb_msg_find_element(msg, "member");
1418         el->flags = mod_op;
1419
1420         /* No need for transactions here, the ldb auto-transaction
1421          * code will handle things for the single operation */
1422         ret = ldb_modify(state->ldb, msg);
1423         talloc_free(tmp_ctx);
1424         if (ret != LDB_SUCCESS) {
1425                 DEBUG(10, ("ldb_modify failed: %s\n",
1426                            ldb_errstring(state->ldb)));
1427                 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1428                         return NT_STATUS_MEMBER_IN_GROUP;
1429                 }
1430                 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1431                         return NT_STATUS_MEMBER_NOT_IN_GROUP;
1432                 }
1433                 return NT_STATUS_LDAP(ret);
1434         }
1435
1436         return NT_STATUS_OK;
1437 }
1438
1439 static NTSTATUS pdb_samba_dsdb_mod_groupmem(struct pdb_methods *m,
1440                                      TALLOC_CTX *mem_ctx,
1441                                      uint32 grouprid, uint32 memberrid,
1442                                      int mod_op)
1443 {
1444         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1445                 m->private_data, struct pdb_samba_dsdb_state);
1446         const struct dom_sid *dom_sid, *groupsid, *membersid;
1447         NTSTATUS status;
1448         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1449         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1450
1451         dom_sid = samdb_domain_sid(state->ldb);
1452
1453         groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1454         if (groupsid == NULL) {
1455                 TALLOC_FREE(tmp_ctx);
1456                 return NT_STATUS_NO_MEMORY;
1457         }
1458         membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1459         if (membersid == NULL) {
1460                 TALLOC_FREE(tmp_ctx);
1461                 return NT_STATUS_NO_MEMORY;
1462         }
1463         status = pdb_samba_dsdb_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1464         talloc_free(tmp_ctx);
1465         return status;
1466 }
1467
1468 static NTSTATUS pdb_samba_dsdb_add_groupmem(struct pdb_methods *m,
1469                                      TALLOC_CTX *mem_ctx,
1470                                      uint32 group_rid, uint32 member_rid)
1471 {
1472         return pdb_samba_dsdb_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1473                                     LDB_FLAG_MOD_ADD);
1474 }
1475
1476 static NTSTATUS pdb_samba_dsdb_del_groupmem(struct pdb_methods *m,
1477                                      TALLOC_CTX *mem_ctx,
1478                                      uint32 group_rid, uint32 member_rid)
1479 {
1480         return pdb_samba_dsdb_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1481                                        LDB_FLAG_MOD_DELETE);
1482 }
1483
1484 static NTSTATUS pdb_samba_dsdb_create_alias(struct pdb_methods *m,
1485                                      const char *name, uint32 *rid)
1486 {
1487         TALLOC_CTX *frame = talloc_stackframe();
1488         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1489                 m->private_data, struct pdb_samba_dsdb_state);
1490         struct dom_sid *sid;
1491
1492         struct ldb_dn *dn;
1493         NTSTATUS status;
1494
1495         /* Internally this uses transactions to ensure all the steps
1496          * happen or fail as one */
1497         status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1498         if (!NT_STATUS_IS_OK(status)) {
1499                 TALLOC_FREE(frame);
1500         }
1501
1502         sid_peek_rid(sid, rid);
1503         TALLOC_FREE(frame);
1504         return NT_STATUS_OK;
1505 }
1506
1507 static NTSTATUS pdb_samba_dsdb_delete_alias(struct pdb_methods *m,
1508                                      const struct dom_sid *sid)
1509 {
1510         const char *attrs[] = { NULL };
1511         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1512                 m->private_data, struct pdb_samba_dsdb_state);
1513         struct ldb_message *msg;
1514         struct ldb_dn *dn;
1515         int rc;
1516         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1517         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1518
1519         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1520         if (!dn || !ldb_dn_validate(dn)) {
1521                 talloc_free(tmp_ctx);
1522                 return NT_STATUS_NO_MEMORY;
1523         }
1524
1525         if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1526                 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1527                 talloc_free(tmp_ctx);
1528                 return NT_STATUS_INTERNAL_ERROR;
1529         }
1530
1531         rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1532                              "(|(grouptype=%d)(grouptype=%d)))",
1533                              GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1534                              GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1535         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1536                 talloc_free(tmp_ctx);
1537                 ldb_transaction_cancel(state->ldb);
1538                 return NT_STATUS_NO_SUCH_ALIAS;
1539         }
1540         rc = ldb_delete(state->ldb, dn);
1541         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1542                 talloc_free(tmp_ctx);
1543                 ldb_transaction_cancel(state->ldb);
1544                 return NT_STATUS_NO_SUCH_ALIAS;
1545         } else if (rc != LDB_SUCCESS) {
1546                 DEBUG(10, ("ldb_delete failed %s\n",
1547                            ldb_errstring(state->ldb)));
1548                 ldb_transaction_cancel(state->ldb);
1549                 talloc_free(tmp_ctx);
1550                 return NT_STATUS_LDAP(rc);
1551         }
1552
1553         if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1554                 DEBUG(0, ("Failed to commit transaction in pdb_samba_dsdb_delete_alias(): %s\n",
1555                           ldb_errstring(state->ldb)));
1556                 talloc_free(tmp_ctx);
1557                 return NT_STATUS_INTERNAL_ERROR;
1558         }
1559
1560         talloc_free(tmp_ctx);
1561         return NT_STATUS_OK;
1562 }
1563
1564 #if 0
1565 static NTSTATUS pdb_samba_dsdb_set_aliasinfo(struct pdb_methods *m,
1566                                       const struct dom_sid *sid,
1567                                       struct acct_info *info)
1568 {
1569         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1570                 m->private_data, struct pdb_samba_dsdb_state);
1571         struct tldap_context *ld;
1572         const char *attrs[3] = { "objectSid", "description",
1573                                  "samAccountName" };
1574         struct ldb_message **msg;
1575         char *sidstr, *dn;
1576         int rc;
1577         struct tldap_mod *mods;
1578         int num_mods;
1579         bool ok;
1580
1581         ld = pdb_samba_dsdb_ld(state);
1582         if (ld == NULL) {
1583                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1584         }
1585
1586         sidstr = sid_binstring(talloc_tos(), sid);
1587         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1588
1589         rc = pdb_samba_dsdb_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1590                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1591                                 &msg, "(&(objectSid=%s)(objectclass=group)"
1592                                 "(|(grouptype=%d)(grouptype=%d)))",
1593                                 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1594                                 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1595         TALLOC_FREE(sidstr)
1596         if (rc != LDB_SUCCESS) {
1597                 DEBUG(10, ("ldap_search failed %s\n",
1598                            ldb_errstring(state->ldb)));
1599                 return NT_STATUS_LDAP(rc);
1600         }
1601         switch talloc_array_length(msg) {
1602         case 0:
1603                 return NT_STATUS_NO_SUCH_ALIAS;
1604         case 1:
1605                 break;
1606         default:
1607                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1608         }
1609
1610         if (!tldap_entry_dn(msg[0], &dn)) {
1611                 TALLOC_FREE(msg);
1612                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1613         }
1614
1615         mods = NULL;
1616         num_mods = 0;
1617         ok = true;
1618
1619         ok &= tldap_make_mod_fmt(
1620                 msg[0], msg, &num_mods, &mods, "description",
1621                 "%s", info->acct_desc);
1622         ok &= tldap_make_mod_fmt(
1623                 msg[0], msg, &num_mods, &mods, "samAccountName",
1624                 "%s", info->acct_name);
1625         if (!ok) {
1626                 TALLOC_FREE(msg);
1627                 return NT_STATUS_NO_MEMORY;
1628         }
1629         if (num_mods == 0) {
1630                 /* no change */
1631                 TALLOC_FREE(msg);
1632                 return NT_STATUS_OK;
1633         }
1634
1635         rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1636         TALLOC_FREE(msg);
1637         if (rc != LDB_SUCCESS) {
1638                 DEBUG(10, ("ldap_modify failed: %s\n",
1639                            ldb_errstring(state->ldb)));
1640                 return NT_STATUS_LDAP(rc);
1641         }
1642         return NT_STATUS_OK;
1643 }
1644 #endif
1645 static NTSTATUS pdb_samba_dsdb_add_aliasmem(struct pdb_methods *m,
1646                                      const struct dom_sid *alias,
1647                                      const struct dom_sid *member)
1648 {
1649         NTSTATUS status;
1650         TALLOC_CTX *frame = talloc_stackframe();
1651         status = pdb_samba_dsdb_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1652         talloc_free(frame);
1653         return status;
1654 }
1655
1656 static NTSTATUS pdb_samba_dsdb_del_aliasmem(struct pdb_methods *m,
1657                                      const struct dom_sid *alias,
1658                                      const struct dom_sid *member)
1659 {
1660         NTSTATUS status;
1661         TALLOC_CTX *frame = talloc_stackframe();
1662         status = pdb_samba_dsdb_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1663         talloc_free(frame);
1664         return status;
1665 }
1666
1667 static NTSTATUS pdb_samba_dsdb_enum_aliasmem(struct pdb_methods *m,
1668                                       const struct dom_sid *alias,
1669                                       TALLOC_CTX *mem_ctx,
1670                                       struct dom_sid **pmembers,
1671                                       size_t *pnum_members)
1672 {
1673         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1674                 m->private_data, struct pdb_samba_dsdb_state);
1675         struct ldb_dn *dn;
1676         unsigned int num_members;
1677         NTSTATUS status;
1678         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1679         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1680
1681         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1682         if (!dn || !ldb_dn_validate(dn)) {
1683                 return NT_STATUS_NO_MEMORY;
1684         }
1685
1686         status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1687         *pnum_members = num_members;
1688         if (NT_STATUS_IS_OK(status)) {
1689                 talloc_steal(mem_ctx, pmembers);
1690         }
1691         talloc_free(tmp_ctx);
1692         return status;
1693 }
1694
1695 static NTSTATUS pdb_samba_dsdb_enum_alias_memberships(struct pdb_methods *m,
1696                                                TALLOC_CTX *mem_ctx,
1697                                                const struct dom_sid *domain_sid,
1698                                                const struct dom_sid *members,
1699                                                size_t num_members,
1700                                                uint32_t **palias_rids,
1701                                                size_t *pnum_alias_rids)
1702 {
1703         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1704                 m->private_data, struct pdb_samba_dsdb_state);
1705         uint32_t *alias_rids = NULL;
1706         size_t num_alias_rids = 0;
1707         int i;
1708         struct dom_sid *groupSIDs = NULL;
1709         unsigned int num_groupSIDs = 0;
1710         char *filter;
1711         NTSTATUS status;
1712         const char *sid_string;
1713         const char *sid_dn;
1714         DATA_BLOB sid_blob;
1715
1716         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1717         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1718         /*
1719          * TODO: Get the filter right so that we only get the aliases from
1720          * either the SAM or BUILTIN
1721          */
1722
1723         filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1724                                  GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1725         if (filter == NULL) {
1726                 return NT_STATUS_NO_MEMORY;
1727         }
1728
1729         for (i = 0; i < num_members; i++) {
1730                 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1731                 if (sid_string == NULL) {
1732                         TALLOC_FREE(tmp_ctx);
1733                         return NT_STATUS_NO_MEMORY;
1734                 }
1735
1736                 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1737                 if (sid_dn == NULL) {
1738                         TALLOC_FREE(tmp_ctx);
1739                         return NT_STATUS_NO_MEMORY;
1740                 }
1741
1742                 sid_blob = data_blob_string_const(sid_dn);
1743
1744                 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1745                                                    tmp_ctx, &groupSIDs, &num_groupSIDs);
1746                 if (!NT_STATUS_IS_OK(status)) {
1747                         talloc_free(tmp_ctx);
1748                         return status;
1749                 }
1750         }
1751
1752         alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1753         if (alias_rids == NULL) {
1754                 talloc_free(tmp_ctx);
1755                 return NT_STATUS_NO_MEMORY;
1756         }
1757
1758         for (i=0; i<num_groupSIDs; i++) {
1759                 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1760                                        &alias_rids[num_alias_rids])) {
1761                         num_alias_rids++;;
1762                 }
1763         }
1764
1765         *palias_rids = alias_rids;
1766         *pnum_alias_rids = num_alias_rids;
1767         return NT_STATUS_OK;
1768 }
1769
1770 static NTSTATUS pdb_samba_dsdb_lookup_rids(struct pdb_methods *m,
1771                                     const struct dom_sid *domain_sid,
1772                                     int num_rids,
1773                                     uint32 *rids,
1774                                     const char **names,
1775                                     enum lsa_SidType *lsa_attrs)
1776 {
1777         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1778                 m->private_data, struct pdb_samba_dsdb_state);
1779         NTSTATUS status;
1780
1781         TALLOC_CTX *tmp_ctx;
1782
1783         if (num_rids == 0) {
1784                 return NT_STATUS_NONE_MAPPED;
1785         }
1786
1787         tmp_ctx = talloc_stackframe();
1788         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1789
1790         status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1791         talloc_free(tmp_ctx);
1792         return status;
1793 }
1794
1795 static NTSTATUS pdb_samba_dsdb_lookup_names(struct pdb_methods *m,
1796                                      const struct dom_sid *domain_sid,
1797                                      int num_names,
1798                                      const char **pp_names,
1799                                      uint32 *rids,
1800                                      enum lsa_SidType *attrs)
1801 {
1802         return NT_STATUS_NOT_IMPLEMENTED;
1803 }
1804
1805 static NTSTATUS pdb_samba_dsdb_get_account_policy(struct pdb_methods *m,
1806                                            enum pdb_policy_type type,
1807                                            uint32_t *value)
1808 {
1809         return account_policy_get(type, value)
1810                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1811 }
1812
1813 static NTSTATUS pdb_samba_dsdb_set_account_policy(struct pdb_methods *m,
1814                                            enum pdb_policy_type type,
1815                                            uint32_t value)
1816 {
1817         return account_policy_set(type, value)
1818                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1819 }
1820
1821 static NTSTATUS pdb_samba_dsdb_get_seq_num(struct pdb_methods *m,
1822                                     time_t *seq_num_out)
1823 {
1824         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1825                 m->private_data, struct pdb_samba_dsdb_state);
1826         uint64_t seq_num;
1827         int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1828         if (ret == LDB_SUCCESS) {
1829                 *seq_num_out = seq_num;
1830                 return NT_STATUS_OK;
1831         } else {
1832                 return NT_STATUS_UNSUCCESSFUL;
1833         }
1834 }
1835
1836 struct pdb_samba_dsdb_search_state {
1837         uint32_t acct_flags;
1838         struct samr_displayentry *entries;
1839         uint32_t num_entries;
1840         ssize_t array_size;
1841         uint32_t current;
1842 };
1843
1844 static bool pdb_samba_dsdb_next_entry(struct pdb_search *search,
1845                                struct samr_displayentry *entry)
1846 {
1847         struct pdb_samba_dsdb_search_state *state = talloc_get_type_abort(
1848                 search->private_data, struct pdb_samba_dsdb_search_state);
1849
1850         if (state->current == state->num_entries) {
1851                 return false;
1852         }
1853
1854         entry->idx = state->entries[state->current].idx;
1855         entry->rid = state->entries[state->current].rid;
1856         entry->acct_flags = state->entries[state->current].acct_flags;
1857
1858         entry->account_name = talloc_strdup(
1859                 search, state->entries[state->current].account_name);
1860         entry->fullname = talloc_strdup(
1861                 search, state->entries[state->current].fullname);
1862         entry->description = talloc_strdup(
1863                 search, state->entries[state->current].description);
1864
1865         state->current += 1;
1866         return true;
1867 }
1868
1869 static void pdb_samba_dsdb_search_end(struct pdb_search *search)
1870 {
1871         struct pdb_samba_dsdb_search_state *state = talloc_get_type_abort(
1872                 search->private_data, struct pdb_samba_dsdb_search_state);
1873         talloc_free(state);
1874 }
1875
1876 static bool pdb_samba_dsdb_search_filter(struct pdb_methods *m,
1877                                      struct pdb_search *search,
1878                                      struct pdb_samba_dsdb_search_state **pstate,
1879                                      const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1880 {
1881         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1882                 m->private_data, struct pdb_samba_dsdb_state);
1883         struct pdb_samba_dsdb_search_state *sstate;
1884         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1885                                  "userAccountControl", "description", NULL };
1886         struct ldb_result *res;
1887         int i, rc, num_users;
1888
1889         va_list ap;
1890         char *expression = NULL;
1891
1892         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1893         if (!tmp_ctx) {
1894                 return false;
1895         }
1896
1897         va_start(ap, exp_fmt);
1898         expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1899         va_end(ap);
1900
1901         if (!expression) {
1902                 talloc_free(tmp_ctx);
1903                 return LDB_ERR_OPERATIONS_ERROR;
1904         }
1905
1906         sstate = talloc_zero(tmp_ctx, struct pdb_samba_dsdb_search_state);
1907         if (sstate == NULL) {
1908                 talloc_free(tmp_ctx);
1909                 return false;
1910         }
1911
1912         rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1913         if (rc != LDB_SUCCESS) {
1914                 talloc_free(tmp_ctx);
1915                 DEBUG(10, ("dsdb_search failed: %s\n",
1916                            ldb_errstring(state->ldb)));
1917                 return false;
1918         }
1919
1920         num_users = res->count;
1921
1922         sstate->entries = talloc_array(sstate, struct samr_displayentry,
1923                                        num_users);
1924         if (sstate->entries == NULL) {
1925                 talloc_free(tmp_ctx);
1926                 DEBUG(10, ("talloc failed\n"));
1927                 return false;
1928         }
1929
1930         sstate->num_entries = 0;
1931
1932         for (i=0; i<num_users; i++) {
1933                 struct samr_displayentry *e;
1934                 struct dom_sid *sid;
1935
1936                 e = &sstate->entries[sstate->num_entries];
1937
1938                 e->idx = sstate->num_entries;
1939                 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1940                 if (!sid) {
1941                         talloc_free(tmp_ctx);
1942                         DEBUG(10, ("Could not pull SID\n"));
1943                         return false;
1944                 }
1945                 sid_peek_rid(sid, &e->rid);
1946
1947                 e->acct_flags = samdb_result_acct_flags(res->msgs[i], "userAccountControl");
1948                 e->account_name = ldb_msg_find_attr_as_string(
1949                         res->msgs[i], "samAccountName", NULL);
1950                 if (e->account_name == NULL) {
1951                         talloc_free(tmp_ctx);
1952                         return false;
1953                 }
1954                 e->fullname = ldb_msg_find_attr_as_string(
1955                         res->msgs[i], "displayName", "");
1956                 e->description = ldb_msg_find_attr_as_string(
1957                         res->msgs[i], "description", "");
1958
1959                 sstate->num_entries += 1;
1960                 if (sstate->num_entries >= num_users) {
1961                         break;
1962                 }
1963         }
1964         talloc_steal(sstate->entries, res->msgs);
1965         search->private_data = talloc_steal(search, sstate);
1966         search->next_entry = pdb_samba_dsdb_next_entry;
1967         search->search_end = pdb_samba_dsdb_search_end;
1968         *pstate = sstate;
1969         talloc_free(tmp_ctx);
1970         return true;
1971 }
1972
1973 static bool pdb_samba_dsdb_search_users(struct pdb_methods *m,
1974                                  struct pdb_search *search,
1975                                  uint32 acct_flags)
1976 {
1977         struct pdb_samba_dsdb_search_state *sstate;
1978         bool ret;
1979
1980         ret = pdb_samba_dsdb_search_filter(m, search, &sstate, "(objectclass=user)");
1981         if (!ret) {
1982                 return false;
1983         }
1984         sstate->acct_flags = acct_flags;
1985         return true;
1986 }
1987
1988 static bool pdb_samba_dsdb_search_groups(struct pdb_methods *m,
1989                                   struct pdb_search *search)
1990 {
1991         struct pdb_samba_dsdb_search_state *sstate;
1992         bool ret;
1993
1994         ret = pdb_samba_dsdb_search_filter(m, search, &sstate,
1995                                        "(&(grouptype=%d)(objectclass=group))",
1996                                        GTYPE_SECURITY_GLOBAL_GROUP);
1997         if (!ret) {
1998                 return false;
1999         }
2000         sstate->acct_flags = 0;
2001         return true;
2002 }
2003
2004 static bool pdb_samba_dsdb_search_aliases(struct pdb_methods *m,
2005                                    struct pdb_search *search,
2006                                    const struct dom_sid *sid)
2007 {
2008         struct pdb_samba_dsdb_search_state *sstate;
2009         bool ret;
2010
2011         ret = pdb_samba_dsdb_search_filter(m, search, &sstate,
2012                                        "(&(grouptype=%d)(objectclass=group))",
2013                                        sid_check_is_builtin(sid)
2014                                        ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2015                                        : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
2016         if (!ret) {
2017                 return false;
2018         }
2019         sstate->acct_flags = 0;
2020         return true;
2021 }
2022
2023 static bool pdb_samba_dsdb_uid_to_sid(struct pdb_methods *m, uid_t uid,
2024                                struct dom_sid *sid)
2025 {
2026         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2027                 m->private_data, struct pdb_samba_dsdb_state);
2028         NTSTATUS status;
2029         struct id_map id_map;
2030         struct id_map *id_maps[2];
2031         TALLOC_CTX *tmp_ctx = talloc_stackframe();
2032         if (!tmp_ctx) {
2033                 return false;
2034         }
2035
2036         id_map.xid.id = uid;
2037         id_map.xid.type = ID_TYPE_UID;
2038         id_maps[0] = &id_map;
2039         id_maps[1] = NULL;
2040
2041         status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2042         if (!NT_STATUS_IS_OK(status)) {
2043                 talloc_free(tmp_ctx);
2044                 return false;
2045         }
2046         *sid = *id_map.sid;
2047         talloc_free(tmp_ctx);
2048         return true;
2049 }
2050
2051 static bool pdb_samba_dsdb_gid_to_sid(struct pdb_methods *m, gid_t gid,
2052                                struct dom_sid *sid)
2053 {
2054         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2055                 m->private_data, struct pdb_samba_dsdb_state);
2056         NTSTATUS status;
2057         struct id_map id_map;
2058         struct id_map *id_maps[2];
2059         TALLOC_CTX *tmp_ctx = talloc_stackframe();
2060         if (!tmp_ctx) {
2061                 return false;
2062         }
2063
2064         id_map.xid.id = gid;
2065         id_map.xid.type = ID_TYPE_GID;
2066         id_maps[0] = &id_map;
2067         id_maps[1] = NULL;
2068
2069         status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2070         if (!NT_STATUS_IS_OK(status)) {
2071                 talloc_free(tmp_ctx);
2072                 return false;
2073         }
2074         *sid = *id_map.sid;
2075         talloc_free(tmp_ctx);
2076         return true;
2077 }
2078
2079 static bool pdb_samba_dsdb_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2080                                  struct unixid *id)
2081 {
2082         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2083                 m->private_data, struct pdb_samba_dsdb_state);
2084         struct id_map id_map;
2085         struct id_map *id_maps[2];
2086         NTSTATUS status;
2087         TALLOC_CTX *tmp_ctx = talloc_stackframe();
2088         if (!tmp_ctx) {
2089                 return false;
2090         }
2091
2092         ZERO_STRUCT(id_map);
2093         id_map.sid = discard_const_p(struct dom_sid, sid);
2094         id_maps[0] = &id_map;
2095         id_maps[1] = NULL;
2096
2097         status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2098         talloc_free(tmp_ctx);
2099         if (!NT_STATUS_IS_OK(status)) {
2100                 return false;
2101         }
2102         if (id_map.xid.type != ID_TYPE_NOT_SPECIFIED) {
2103                 *id = id_map.xid;
2104                 return true;
2105         }
2106         return false;
2107 }
2108
2109 static uint32_t pdb_samba_dsdb_capabilities(struct pdb_methods *m)
2110 {
2111         return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2112 }
2113
2114 static bool pdb_samba_dsdb_new_rid(struct pdb_methods *m, uint32 *rid)
2115 {
2116         return false;
2117 }
2118
2119 static bool pdb_samba_dsdb_get_trusteddom_pw(struct pdb_methods *m,
2120                                       const char *domain, char** pwd,
2121                                       struct dom_sid *sid,
2122                                       time_t *pass_last_set_time)
2123 {
2124         return false;
2125 }
2126
2127 static bool pdb_samba_dsdb_set_trusteddom_pw(struct pdb_methods *m,
2128                                       const char* domain, const char* pwd,
2129                                       const struct dom_sid *sid)
2130 {
2131         return false;
2132 }
2133
2134 static bool pdb_samba_dsdb_del_trusteddom_pw(struct pdb_methods *m,
2135                                       const char *domain)
2136 {
2137         return false;
2138 }
2139
2140 static NTSTATUS pdb_samba_dsdb_enum_trusteddoms(struct pdb_methods *m,
2141                                          TALLOC_CTX *mem_ctx,
2142                                          uint32 *num_domains,
2143                                          struct trustdom_info ***domains)
2144 {
2145         *num_domains = 0;
2146         *domains = NULL;
2147         return NT_STATUS_OK;
2148 }
2149
2150 static bool pdb_samba_dsdb_is_responsible_for_wellknown(struct pdb_methods *m)
2151 {
2152         return true;
2153 }
2154
2155 static void pdb_samba_dsdb_init_methods(struct pdb_methods *m)
2156 {
2157         m->name = "samba_dsdb";
2158         m->get_domain_info = pdb_samba_dsdb_get_domain_info;
2159         m->getsampwnam = pdb_samba_dsdb_getsampwnam;
2160         m->getsampwsid = pdb_samba_dsdb_getsampwsid;
2161         m->create_user = pdb_samba_dsdb_create_user;
2162         m->delete_user = pdb_samba_dsdb_delete_user;
2163         m->add_sam_account = pdb_samba_dsdb_add_sam_account;
2164         m->update_sam_account = pdb_samba_dsdb_update_sam_account;
2165         m->delete_sam_account = pdb_samba_dsdb_delete_sam_account;
2166         m->rename_sam_account = pdb_samba_dsdb_rename_sam_account;
2167         m->update_login_attempts = pdb_samba_dsdb_update_login_attempts;
2168         m->getgrsid = pdb_samba_dsdb_getgrsid;
2169         m->getgrgid = pdb_samba_dsdb_getgrgid;
2170         m->getgrnam = pdb_samba_dsdb_getgrnam;
2171         m->create_dom_group = pdb_samba_dsdb_create_dom_group;
2172         m->delete_dom_group = pdb_samba_dsdb_delete_dom_group;
2173         m->add_group_mapping_entry = pdb_samba_dsdb_add_group_mapping_entry;
2174         m->update_group_mapping_entry = pdb_samba_dsdb_update_group_mapping_entry;
2175         m->delete_group_mapping_entry = pdb_samba_dsdb_delete_group_mapping_entry;
2176         m->enum_group_mapping = pdb_samba_dsdb_enum_group_mapping;
2177         m->enum_group_members = pdb_samba_dsdb_enum_group_members;
2178         m->enum_group_memberships = pdb_samba_dsdb_enum_group_memberships;
2179         m->set_unix_primary_group = pdb_samba_dsdb_set_unix_primary_group;
2180         m->add_groupmem = pdb_samba_dsdb_add_groupmem;
2181         m->del_groupmem = pdb_samba_dsdb_del_groupmem;
2182         m->create_alias = pdb_samba_dsdb_create_alias;
2183         m->delete_alias = pdb_samba_dsdb_delete_alias;
2184         m->get_aliasinfo = pdb_default_get_aliasinfo;
2185         m->add_aliasmem = pdb_samba_dsdb_add_aliasmem;
2186         m->del_aliasmem = pdb_samba_dsdb_del_aliasmem;
2187         m->enum_aliasmem = pdb_samba_dsdb_enum_aliasmem;
2188         m->enum_alias_memberships = pdb_samba_dsdb_enum_alias_memberships;
2189         m->lookup_rids = pdb_samba_dsdb_lookup_rids;
2190         m->lookup_names = pdb_samba_dsdb_lookup_names;
2191         m->get_account_policy = pdb_samba_dsdb_get_account_policy;
2192         m->set_account_policy = pdb_samba_dsdb_set_account_policy;
2193         m->get_seq_num = pdb_samba_dsdb_get_seq_num;
2194         m->search_users = pdb_samba_dsdb_search_users;
2195         m->search_groups = pdb_samba_dsdb_search_groups;
2196         m->search_aliases = pdb_samba_dsdb_search_aliases;
2197         m->uid_to_sid = pdb_samba_dsdb_uid_to_sid;
2198         m->gid_to_sid = pdb_samba_dsdb_gid_to_sid;
2199         m->sid_to_id = pdb_samba_dsdb_sid_to_id;
2200         m->capabilities = pdb_samba_dsdb_capabilities;
2201         m->new_rid = pdb_samba_dsdb_new_rid;
2202         m->get_trusteddom_pw = pdb_samba_dsdb_get_trusteddom_pw;
2203         m->set_trusteddom_pw = pdb_samba_dsdb_set_trusteddom_pw;
2204         m->del_trusteddom_pw = pdb_samba_dsdb_del_trusteddom_pw;
2205         m->enum_trusteddoms = pdb_samba_dsdb_enum_trusteddoms;
2206         m->is_responsible_for_wellknown =
2207                                 pdb_samba_dsdb_is_responsible_for_wellknown;
2208 }
2209
2210 static void free_private_data(void **vp)
2211 {
2212         struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2213                 *vp, struct pdb_samba_dsdb_state);
2214         talloc_unlink(state, state->ldb);
2215         return;
2216 }
2217
2218 static NTSTATUS pdb_samba_dsdb_init_secrets(struct pdb_methods *m)
2219 {
2220         struct pdb_domain_info *dom_info;
2221         struct dom_sid stored_sid;
2222         struct GUID stored_guid;
2223         bool sid_exists_and_matches = false;
2224         bool guid_exists_and_matches = false;
2225         bool ret;
2226
2227         dom_info = pdb_samba_dsdb_get_domain_info(m, m);
2228         if (!dom_info) {
2229                 return NT_STATUS_UNSUCCESSFUL;
2230         }
2231
2232         ret = secrets_fetch_domain_sid(dom_info->name, &stored_sid);
2233         if (ret) {
2234                 if (dom_sid_equal(&stored_sid, &dom_info->sid)) {
2235                         sid_exists_and_matches = true;
2236                 }
2237         }
2238
2239         if (sid_exists_and_matches == false) {
2240                 secrets_clear_domain_protection(dom_info->name);
2241                 ret = secrets_store_domain_sid(dom_info->name,
2242                                                &dom_info->sid);
2243                 ret &= secrets_mark_domain_protected(dom_info->name);
2244                 if (!ret) {
2245                         goto done;
2246                 }
2247         }
2248
2249         ret = secrets_fetch_domain_guid(dom_info->name, &stored_guid);
2250         if (ret) {
2251                 if (GUID_equal(&stored_guid, &dom_info->guid)) {
2252                         guid_exists_and_matches = true;
2253                 }
2254         }
2255
2256         if (guid_exists_and_matches == false) {
2257                 secrets_clear_domain_protection(dom_info->name);
2258                 ret = secrets_store_domain_guid(dom_info->name,
2259                                                &dom_info->guid);
2260                 ret &= secrets_mark_domain_protected(dom_info->name);
2261                 if (!ret) {
2262                         goto done;
2263                 }
2264         }
2265
2266 done:
2267         TALLOC_FREE(dom_info);
2268         if (!ret) {
2269                 return NT_STATUS_UNSUCCESSFUL;
2270         }
2271         return NT_STATUS_OK;
2272 }
2273
2274 static NTSTATUS pdb_init_samba_dsdb(struct pdb_methods **pdb_method,
2275                              const char *location)
2276 {
2277         struct pdb_methods *m;
2278         struct pdb_samba_dsdb_state *state;
2279         NTSTATUS status;
2280
2281         if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2282                 return status;
2283         }
2284
2285         state = talloc_zero(m, struct pdb_samba_dsdb_state);
2286         if (state == NULL) {
2287                 goto nomem;
2288         }
2289         m->private_data = state;
2290         m->free_private_data = free_private_data;
2291         pdb_samba_dsdb_init_methods(m);
2292
2293         state->ev = s4_event_context_init(state);
2294         if (!state->ev) {
2295                 DEBUG(0, ("s4_event_context_init failed\n"));
2296                 goto nomem;
2297         }
2298
2299         state->lp_ctx = loadparm_init_s3(state, loadparm_s3_helpers());
2300         if (state->lp_ctx == NULL) {
2301                 DEBUG(0, ("loadparm_init_s3 failed\n"));
2302                 goto nomem;
2303         }
2304
2305         if (location) {
2306                 state->ldb = samdb_connect_url(state,
2307                                    state->ev,
2308                                    state->lp_ctx,
2309                                    system_session(state->lp_ctx),
2310                                    0, location);
2311         } else {
2312                 state->ldb = samdb_connect(state,
2313                                    state->ev,
2314                                    state->lp_ctx,
2315                                    system_session(state->lp_ctx), 0);
2316         }
2317
2318         if (!state->ldb) {
2319                 DEBUG(0, ("samdb_connect failed\n"));
2320                 status = NT_STATUS_INTERNAL_ERROR;
2321                 goto fail;
2322         }
2323
2324         state->idmap_ctx = idmap_init(state, state->ev,
2325                                       state->lp_ctx);
2326         if (!state->idmap_ctx) {
2327                 DEBUG(0, ("idmap failed\n"));
2328                 status = NT_STATUS_INTERNAL_ERROR;
2329                 goto fail;
2330         }
2331
2332         status = pdb_samba_dsdb_init_secrets(m);
2333         if (!NT_STATUS_IS_OK(status)) {
2334                 DEBUG(10, ("pdb_samba_dsdb_init_secrets failed!\n"));
2335                 goto fail;
2336         }
2337
2338         *pdb_method = m;
2339         return NT_STATUS_OK;
2340 nomem:
2341         status = NT_STATUS_NO_MEMORY;
2342 fail:
2343         TALLOC_FREE(m);
2344         return status;
2345 }
2346
2347 NTSTATUS pdb_samba_dsdb_init(void);
2348 NTSTATUS pdb_samba_dsdb_init(void)
2349 {
2350         NTSTATUS status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba_dsdb",
2351                                               pdb_init_samba_dsdb);
2352         if (!NT_STATUS_IS_OK(status)) {
2353                 return status;
2354         }
2355         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
2356                                    pdb_init_samba_dsdb);
2357 }