torture: fix whitespace/tab mixup in internal_torture_run_test()
[Samba.git] / source3 / passdb / pdb_samba_dsdb.c
blob465cc24dfd14045d88ccdc4249feab7b9763b442
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
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.
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.
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/>.
22 /* This module, is a port of Volker's pdb_ads to ldb and DSDB APIs */
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 "librpc/gen_ndr/ndr_drsblobs.h"
32 #include "librpc/gen_ndr/ndr_lsa.h"
33 #include "libds/common/flag_mapping.h"
34 #include "source4/lib/events/events.h"
35 #include "source4/auth/session.h"
36 #include "source4/auth/system_session_proto.h"
37 #include "lib/param/param.h"
38 #include "source4/dsdb/common/util.h"
39 #include "source3/include/secrets.h"
40 #include "source4/auth/auth_sam.h"
42 struct pdb_samba_dsdb_state {
43 struct tevent_context *ev;
44 struct ldb_context *ldb;
45 struct idmap_context *idmap_ctx;
46 struct loadparm_context *lp_ctx;
49 static NTSTATUS pdb_samba_dsdb_getsampwsid(struct pdb_methods *m,
50 struct samu *sam_acct,
51 const struct dom_sid *sid);
52 static NTSTATUS pdb_samba_dsdb_getsamupriv(struct pdb_samba_dsdb_state *state,
53 const char *filter,
54 TALLOC_CTX *mem_ctx,
55 struct ldb_message **pmsg);
56 static bool pdb_samba_dsdb_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
57 struct unixid *id);
59 static bool pdb_samba_dsdb_pull_time(struct ldb_message *msg, const char *attr,
60 time_t *ptime)
62 uint64_t tmp;
63 if (! ldb_msg_find_element(msg, attr)) {
64 return false;
66 tmp = ldb_msg_find_attr_as_uint64(msg, attr, 0);
67 *ptime = nt_time_to_unix(tmp);
68 return true;
71 static struct pdb_domain_info *pdb_samba_dsdb_get_domain_info(
72 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
74 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
75 m->private_data, struct pdb_samba_dsdb_state);
76 struct pdb_domain_info *info;
77 struct dom_sid *domain_sid;
78 struct ldb_dn *forest_dn, *domain_dn;
79 struct ldb_result *dom_res = NULL;
80 const char *dom_attrs[] = {
81 "objectSid",
82 "objectGUID",
83 "fSMORoleOwner",
84 NULL
86 char *p;
87 int ret;
89 info = talloc(mem_ctx, struct pdb_domain_info);
90 if (info == NULL) {
91 return NULL;
94 domain_dn = ldb_get_default_basedn(state->ldb);
96 ret = ldb_search(state->ldb, info, &dom_res,
97 domain_dn, LDB_SCOPE_BASE, dom_attrs, NULL);
98 if (ret != LDB_SUCCESS) {
99 goto fail;
101 if (dom_res->count != 1) {
102 goto fail;
105 info->guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
107 domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
108 if (!domain_sid) {
109 goto fail;
111 info->sid = *domain_sid;
113 TALLOC_FREE(dom_res);
115 info->name = talloc_strdup(info, lpcfg_sam_name(state->lp_ctx));
116 info->dns_domain = ldb_dn_canonical_string(info, domain_dn);
118 if (!info->dns_domain) {
119 goto fail;
121 p = strchr(info->dns_domain, '/');
122 if (p) {
123 *p = '\0';
126 forest_dn = ldb_get_root_basedn(state->ldb);
127 if (!forest_dn) {
128 goto fail;
131 info->dns_forest = ldb_dn_canonical_string(info, forest_dn);
132 if (!info->dns_forest) {
133 goto fail;
135 p = strchr(info->dns_forest, '/');
136 if (p) {
137 *p = '\0';
140 return info;
142 fail:
143 TALLOC_FREE(dom_res);
144 TALLOC_FREE(info);
145 return NULL;
148 static struct ldb_message *pdb_samba_dsdb_get_samu_private(
149 struct pdb_methods *m, struct samu *sam)
151 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
152 m->private_data, struct pdb_samba_dsdb_state);
153 struct ldb_message *msg;
154 char *sidstr, *filter;
155 NTSTATUS status;
157 msg = (struct ldb_message *)
158 pdb_get_backend_private_data(sam, m);
160 if (msg != NULL) {
161 return talloc_get_type_abort(msg, struct ldb_message);
164 sidstr = dom_sid_string(talloc_tos(), pdb_get_user_sid(sam));
165 if (sidstr == NULL) {
166 return NULL;
169 filter = talloc_asprintf(
170 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
171 TALLOC_FREE(sidstr);
172 if (filter == NULL) {
173 return NULL;
176 status = pdb_samba_dsdb_getsamupriv(state, filter, sam, &msg);
177 TALLOC_FREE(filter);
178 if (!NT_STATUS_IS_OK(status)) {
179 return NULL;
182 return msg;
185 static NTSTATUS pdb_samba_dsdb_init_sam_from_priv(struct pdb_methods *m,
186 struct samu *sam,
187 struct ldb_message *msg)
189 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
190 m->private_data, struct pdb_samba_dsdb_state);
191 TALLOC_CTX *frame = talloc_stackframe();
192 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
193 const char *str;
194 time_t tmp_time;
195 struct dom_sid *sid, group_sid;
196 uint64_t n;
197 const DATA_BLOB *blob;
199 str = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
200 if (str == NULL) {
201 DEBUG(10, ("no samAccountName\n"));
202 goto fail;
204 pdb_set_username(sam, str, PDB_SET);
206 if (pdb_samba_dsdb_pull_time(msg, "lastLogon", &tmp_time)) {
207 pdb_set_logon_time(sam, tmp_time, PDB_SET);
209 if (pdb_samba_dsdb_pull_time(msg, "lastLogoff", &tmp_time)) {
210 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
212 if (pdb_samba_dsdb_pull_time(msg, "pwdLastSet", &tmp_time)) {
213 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
215 if (pdb_samba_dsdb_pull_time(msg, "accountExpires", &tmp_time)) {
216 pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
219 str = ldb_msg_find_attr_as_string(msg, "displayName",
220 NULL);
221 if (str != NULL) {
222 pdb_set_fullname(sam, str, PDB_SET);
225 str = ldb_msg_find_attr_as_string(msg, "homeDirectory",
226 NULL);
227 if (str != NULL) {
228 pdb_set_homedir(sam, str, PDB_SET);
231 str = ldb_msg_find_attr_as_string(msg, "homeDrive", NULL);
232 if (str != NULL) {
233 pdb_set_dir_drive(sam, str, PDB_SET);
236 str = ldb_msg_find_attr_as_string(msg, "scriptPath", NULL);
237 if (str != NULL) {
238 pdb_set_logon_script(sam, str, PDB_SET);
241 str = ldb_msg_find_attr_as_string(msg, "profilePath",
242 NULL);
243 if (str != NULL) {
244 pdb_set_profile_path(sam, str, PDB_SET);
247 str = ldb_msg_find_attr_as_string(msg, "comment",
248 NULL);
249 if (str != NULL) {
250 pdb_set_comment(sam, str, PDB_SET);
253 str = ldb_msg_find_attr_as_string(msg, "description",
254 NULL);
255 if (str != NULL) {
256 pdb_set_acct_desc(sam, str, PDB_SET);
259 str = ldb_msg_find_attr_as_string(msg, "userWorkstations",
260 NULL);
261 if (str != NULL) {
262 pdb_set_workstations(sam, str, PDB_SET);
265 blob = ldb_msg_find_ldb_val(msg, "userParameters");
266 if (blob != NULL) {
267 str = base64_encode_data_blob(frame, *blob);
268 if (str == NULL) {
269 DEBUG(0, ("base64_encode_data_blob() failed\n"));
270 goto fail;
272 pdb_set_munged_dial(sam, str, PDB_SET);
275 sid = samdb_result_dom_sid(talloc_tos(), msg, "objectSid");
276 if (!sid) {
277 DEBUG(10, ("Could not pull SID\n"));
278 goto fail;
280 pdb_set_user_sid(sam, sid, PDB_SET);
282 n = samdb_result_acct_flags(msg, "msDS-User-Account-Control-Computed");
283 if (n == 0) {
284 DEBUG(10, ("Could not pull userAccountControl\n"));
285 goto fail;
287 pdb_set_acct_ctrl(sam, n, PDB_SET);
289 blob = ldb_msg_find_ldb_val(msg, "unicodePwd");
290 if (blob) {
291 if (blob->length != NT_HASH_LEN) {
292 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
293 (int)blob->length, NT_HASH_LEN));
294 goto fail;
296 pdb_set_nt_passwd(sam, blob->data, PDB_SET);
299 blob = ldb_msg_find_ldb_val(msg, "dBCSPwd");
300 if (blob) {
301 if (blob->length != LM_HASH_LEN) {
302 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
303 (int)blob->length, LM_HASH_LEN));
304 goto fail;
306 pdb_set_lanman_passwd(sam, blob->data, PDB_SET);
309 n = ldb_msg_find_attr_as_uint(msg, "primaryGroupID", 0);
310 if (n == 0) {
311 DEBUG(10, ("Could not pull primaryGroupID\n"));
312 goto fail;
314 sid_compose(&group_sid, samdb_domain_sid(state->ldb), n);
315 pdb_set_group_sid(sam, &group_sid, PDB_SET);
317 status = NT_STATUS_OK;
318 fail:
319 TALLOC_FREE(frame);
320 return status;
323 static bool pdb_samba_dsdb_add_time(struct ldb_message *msg,
324 const char *attrib, time_t t)
326 uint64_t nt_time;
328 unix_to_nt_time(&nt_time, t);
330 return ldb_msg_add_fmt(msg, attrib, "%llu", (unsigned long long) nt_time);
333 static int pdb_samba_dsdb_replace_by_sam(struct pdb_samba_dsdb_state *state,
334 bool (*need_update)(const struct samu *,
335 enum pdb_elements),
336 struct ldb_dn *dn,
337 struct samu *sam)
339 TALLOC_CTX *frame = talloc_stackframe();
340 int ret = LDB_SUCCESS;
341 const char *pw;
342 struct ldb_message *msg;
343 struct ldb_request *req;
344 uint32_t dsdb_flags = 0;
345 /* TODO: All fields :-) */
347 msg = ldb_msg_new(frame);
348 if (!msg) {
349 talloc_free(frame);
350 return false;
353 msg->dn = dn;
355 /* build modify request */
356 ret = ldb_build_mod_req(&req, state->ldb, frame, msg, NULL, NULL,
357 ldb_op_default_callback,
358 NULL);
359 if (ret != LDB_SUCCESS) {
360 talloc_free(frame);
361 return ret;
364 /* If we set a plaintext password, the system will
365 * force the pwdLastSet to now() */
366 if (need_update(sam, PDB_PASSLASTSET)) {
367 dsdb_flags = DSDB_PASSWORD_BYPASS_LAST_SET;
369 ret |= pdb_samba_dsdb_add_time(msg, "pwdLastSet",
370 pdb_get_pass_last_set_time(sam));
373 pw = pdb_get_plaintext_passwd(sam);
374 if (need_update(sam, PDB_PLAINTEXT_PW)) {
375 struct ldb_val pw_utf16;
376 if (pw == NULL) {
377 talloc_free(frame);
378 return LDB_ERR_OPERATIONS_ERROR;
381 if (!convert_string_talloc(msg,
382 CH_UNIX, CH_UTF16,
383 pw, strlen(pw),
384 (void *)&pw_utf16.data,
385 &pw_utf16.length)) {
386 talloc_free(frame);
387 return LDB_ERR_OPERATIONS_ERROR;
389 ret |= ldb_msg_add_value(msg, "clearTextPassword", &pw_utf16, NULL);
390 } else {
391 bool changed_lm_pw = false;
392 bool changed_nt_pw = false;
393 bool changed_history = false;
394 if (need_update(sam, PDB_LMPASSWD)) {
395 struct ldb_val val;
396 val.data = discard_const_p(uint8_t, pdb_get_lanman_passwd(sam));
397 if (!val.data) {
398 samdb_msg_add_delete(state->ldb, msg, msg,
399 "dBCSPwd");
400 } else {
401 val.length = LM_HASH_LEN;
402 ret |= ldb_msg_add_value(msg, "dBCSPwd", &val, NULL);
404 changed_lm_pw = true;
406 if (need_update(sam, PDB_NTPASSWD)) {
407 struct ldb_val val;
408 val.data = discard_const_p(uint8_t, pdb_get_nt_passwd(sam));
409 if (!val.data) {
410 samdb_msg_add_delete(state->ldb, msg, msg,
411 "unicodePwd");
412 } else {
413 val.length = NT_HASH_LEN;
414 ret |= ldb_msg_add_value(msg, "unicodePwd", &val, NULL);
416 changed_nt_pw = true;
419 /* Try to ensure we don't get out of sync */
420 if (changed_lm_pw && !changed_nt_pw) {
421 samdb_msg_add_delete(state->ldb, msg, msg,
422 "unicodePwd");
423 } else if (changed_nt_pw && !changed_lm_pw) {
424 samdb_msg_add_delete(state->ldb, msg, msg,
425 "dBCSPwd");
427 if (changed_lm_pw || changed_nt_pw) {
428 samdb_msg_add_delete(state->ldb, msg, msg,
429 "supplementalCredentials");
433 if (need_update(sam, PDB_PWHISTORY)) {
434 uint32_t current_hist_len;
435 const uint8_t *history = pdb_get_pw_history(sam, &current_hist_len);
437 bool invalid_history = false;
438 struct samr_Password *history_hashes = talloc_array(talloc_tos(), struct samr_Password,
439 current_hist_len);
440 if (!history) {
441 invalid_history = true;
442 } else {
443 unsigned int i;
444 static const uint8_t zeros[16];
445 /* Parse the history into the correct format */
446 for (i = 0; i < current_hist_len; i++) {
447 if (memcmp(&history[i*PW_HISTORY_ENTRY_LEN], zeros, 16) != 0) {
448 /* If the history is in the old format, with a salted hash, then we can't migrate it to AD format */
449 invalid_history = true;
450 break;
452 /* Copy out the 2nd 16 bytes of the 32 byte password history, containing the NT hash */
453 memcpy(history_hashes[i].hash,
454 &history[(i*PW_HISTORY_ENTRY_LEN) + PW_HISTORY_SALT_LEN],
455 sizeof(history_hashes[i].hash));
458 if (invalid_history) {
459 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
460 "ntPwdHistory");
462 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
463 "lmPwdHistory");
464 } else {
465 ret |= samdb_msg_add_hashes(state->ldb, msg, msg,
466 "ntPwdHistory",
467 history_hashes,
468 current_hist_len);
470 changed_history = true;
472 if (changed_lm_pw || changed_nt_pw || changed_history) {
473 /* These attributes can only be modified directly by using a special control */
474 dsdb_flags = DSDB_BYPASS_PASSWORD_HASH;
478 /* PDB_USERSID is only allowed on ADD, handled in caller */
479 if (need_update(sam, PDB_GROUPSID)) {
480 const struct dom_sid *sid = pdb_get_group_sid(sam);
481 uint32_t rid;
482 NTSTATUS status = dom_sid_split_rid(NULL, sid, NULL, &rid);
483 if (!NT_STATUS_IS_OK(status)) {
484 talloc_free(frame);
485 return LDB_ERR_OPERATIONS_ERROR;
487 if (!dom_sid_in_domain(samdb_domain_sid(state->ldb), sid)) {
488 talloc_free(frame);
489 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
491 ret |= samdb_msg_add_uint(state->ldb, msg, msg, "primaryGroupID", rid);
493 if (need_update(sam, PDB_FULLNAME)) {
494 ret |= ldb_msg_add_string(msg, "displayName", pdb_get_fullname(sam));
497 if (need_update(sam, PDB_SMBHOME)) {
498 ret |= ldb_msg_add_string(msg, "homeDirectory",
499 pdb_get_homedir(sam));
502 if (need_update(sam, PDB_PROFILE)) {
503 ret |= ldb_msg_add_string(msg, "profilePath",
504 pdb_get_profile_path(sam));
507 if (need_update(sam, PDB_DRIVE)) {
508 ret |= ldb_msg_add_string(msg, "homeDrive",
509 pdb_get_dir_drive(sam));
512 if (need_update(sam, PDB_LOGONSCRIPT)) {
513 ret |= ldb_msg_add_string(msg, "scriptPath",
514 pdb_get_logon_script(sam));
517 if (need_update(sam, PDB_KICKOFFTIME)) {
518 ret |= pdb_samba_dsdb_add_time(msg, "accountExpires",
519 pdb_get_kickoff_time(sam));
522 if (need_update(sam, PDB_LOGONTIME)) {
523 ret |= pdb_samba_dsdb_add_time(msg, "lastLogon",
524 pdb_get_logon_time(sam));
527 if (need_update(sam, PDB_LOGOFFTIME)) {
528 ret |= pdb_samba_dsdb_add_time(msg, "lastLogoff",
529 pdb_get_logoff_time(sam));
532 if (need_update(sam, PDB_USERNAME)) {
533 ret |= ldb_msg_add_string(msg, "samAccountName",
534 pdb_get_username(sam));
537 if (need_update(sam, PDB_HOURSLEN) || need_update(sam, PDB_HOURS)) {
538 struct ldb_val hours = data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam));
539 ret |= ldb_msg_add_value(msg, "logonHours",
540 &hours, NULL);
543 if (need_update(sam, PDB_ACCTCTRL)) {
544 ret |= samdb_msg_add_acct_flags(state->ldb, msg, msg,
545 "userAccountControl", pdb_get_acct_ctrl(sam));
548 if (need_update(sam, PDB_COMMENT)) {
549 ret |= ldb_msg_add_string(msg, "comment",
550 pdb_get_comment(sam));
553 if (need_update(sam, PDB_ACCTDESC)) {
554 ret |= ldb_msg_add_string(msg, "description",
555 pdb_get_acct_desc(sam));
558 if (need_update(sam, PDB_WORKSTATIONS)) {
559 ret |= ldb_msg_add_string(msg, "userWorkstations",
560 pdb_get_workstations(sam));
563 /* This will need work, it is actually a UTF8 'string' with internal NULLs, to handle TS parameters */
564 if (need_update(sam, PDB_MUNGEDDIAL)) {
565 const char *base64_munged_dial = NULL;
567 base64_munged_dial = pdb_get_munged_dial(sam);
568 if (base64_munged_dial != NULL && strlen(base64_munged_dial) > 0) {
569 struct ldb_val blob;
571 blob = base64_decode_data_blob_talloc(msg,
572 base64_munged_dial);
573 if (blob.data == NULL) {
574 DEBUG(0, ("Failed to decode userParameters from "
575 "munged dialback string[%s] for %s\n",
576 base64_munged_dial,
577 ldb_dn_get_linearized(msg->dn)));
578 talloc_free(frame);
579 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
581 ret |= ldb_msg_add_steal_value(msg, "userParameters",
582 &blob);
586 if (need_update(sam, PDB_COUNTRY_CODE)) {
587 ret |= ldb_msg_add_fmt(msg, "countryCode",
588 "%i", (int)pdb_get_country_code(sam));
591 if (need_update(sam, PDB_CODE_PAGE)) {
592 ret |= ldb_msg_add_fmt(msg, "codePage",
593 "%i", (int)pdb_get_code_page(sam));
596 /* Not yet handled here or not meaningful for modifies on a Samba_Dsdb backend:
597 PDB_BAD_PASSWORD_TIME,
598 PDB_CANCHANGETIME, - these are calculated per policy, not stored
599 PDB_DOMAIN,
600 PDB_NTUSERNAME, - this makes no sense, and never really did
601 PDB_LOGONDIVS,
602 PDB_USERSID, - Handled in pdb_samba_dsdb_add_sam_account()
603 PDB_FIELDS_PRESENT,
604 PDB_BAD_PASSWORD_COUNT,
605 PDB_LOGON_COUNT,
606 PDB_UNKNOWN6,
607 PDB_BACKEND_PRIVATE_DATA,
610 if (ret != LDB_SUCCESS) {
611 talloc_free(frame);
612 return LDB_ERR_OPERATIONS_ERROR;
615 if (msg->num_elements == 0) {
616 talloc_free(frame);
617 /* Nothing to do, just return success */
618 return LDB_SUCCESS;
621 ret = dsdb_replace(state->ldb, msg, dsdb_flags);
623 if (ret != LDB_SUCCESS) {
624 DEBUG(0,("Failed to modify account record %s to set user attributes: %s\n",
625 ldb_dn_get_linearized(msg->dn),
626 ldb_errstring(state->ldb)));
629 talloc_free(frame);
630 return ret;
633 static NTSTATUS pdb_samba_dsdb_getsamupriv(struct pdb_samba_dsdb_state *state,
634 const char *filter,
635 TALLOC_CTX *mem_ctx,
636 struct ldb_message **msg)
638 const char * attrs[] = {
639 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
640 "sAMAccountName", "displayName", "homeDirectory",
641 "homeDrive", "scriptPath", "profilePath", "description",
642 "userWorkstations", "comment", "userParameters", "objectSid",
643 "primaryGroupID", "userAccountControl",
644 "msDS-User-Account-Control-Computed", "logonHours",
645 "badPwdCount", "logonCount", "countryCode", "codePage",
646 "unicodePwd", "dBCSPwd", NULL };
648 int rc = dsdb_search_one(state->ldb, mem_ctx, msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", filter);
649 if (rc != LDB_SUCCESS) {
650 DEBUG(10, ("ldap_search failed %s\n",
651 ldb_errstring(state->ldb)));
652 return NT_STATUS_LDAP(rc);
655 return NT_STATUS_OK;
658 static NTSTATUS pdb_samba_dsdb_getsampwfilter(struct pdb_methods *m,
659 struct pdb_samba_dsdb_state *state,
660 struct samu *sam_acct,
661 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
663 struct ldb_message *priv;
664 NTSTATUS status;
665 va_list ap;
666 char *expression = NULL;
667 TALLOC_CTX *tmp_ctx = talloc_new(state);
668 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
670 va_start(ap, exp_fmt);
671 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
672 va_end(ap);
674 if (!expression) {
675 talloc_free(tmp_ctx);
676 return NT_STATUS_NO_MEMORY;
679 status = pdb_samba_dsdb_getsamupriv(state, expression, sam_acct, &priv);
680 talloc_free(tmp_ctx);
681 if (!NT_STATUS_IS_OK(status)) {
682 DEBUG(10, ("pdb_samba_dsdb_getsamupriv failed: %s\n",
683 nt_errstr(status)));
684 return status;
687 status = pdb_samba_dsdb_init_sam_from_priv(m, sam_acct, priv);
688 if (!NT_STATUS_IS_OK(status)) {
689 DEBUG(10, ("pdb_samba_dsdb_init_sam_from_priv failed: %s\n",
690 nt_errstr(status)));
691 TALLOC_FREE(priv);
692 return status;
695 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
696 return NT_STATUS_OK;
699 static NTSTATUS pdb_samba_dsdb_getsampwnam(struct pdb_methods *m,
700 struct samu *sam_acct,
701 const char *username)
703 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
704 m->private_data, struct pdb_samba_dsdb_state);
706 return pdb_samba_dsdb_getsampwfilter(m, state, sam_acct,
707 "(&(samaccountname=%s)(objectclass=user))",
708 username);
711 static NTSTATUS pdb_samba_dsdb_getsampwsid(struct pdb_methods *m,
712 struct samu *sam_acct,
713 const struct dom_sid *sid)
715 NTSTATUS status;
716 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
717 m->private_data, struct pdb_samba_dsdb_state);
718 char *sidstr;
720 sidstr = dom_sid_string(talloc_tos(), sid);
721 NT_STATUS_HAVE_NO_MEMORY(sidstr);
723 status = pdb_samba_dsdb_getsampwfilter(m, state, sam_acct,
724 "(&(objectsid=%s)(objectclass=user))",
725 sidstr);
726 talloc_free(sidstr);
727 return status;
730 static NTSTATUS pdb_samba_dsdb_create_user(struct pdb_methods *m,
731 TALLOC_CTX *mem_ctx,
732 const char *name, uint32 acct_flags,
733 uint32 *rid)
735 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
736 m->private_data, struct pdb_samba_dsdb_state);
737 struct dom_sid *sid;
738 struct ldb_dn *dn;
739 NTSTATUS status;
740 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
741 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
743 /* Internally this uses transactions to ensure all the steps
744 * happen or fail as one */
745 status = dsdb_add_user(state->ldb, tmp_ctx, name, acct_flags, NULL,
746 &sid, &dn);
747 if (!NT_STATUS_IS_OK(status)) {
748 talloc_free(tmp_ctx);
749 return status;
751 sid_peek_rid(sid, rid);
752 talloc_free(tmp_ctx);
753 return NT_STATUS_OK;
756 static NTSTATUS pdb_samba_dsdb_delete_user(struct pdb_methods *m,
757 TALLOC_CTX *mem_ctx,
758 struct samu *sam)
760 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
761 m->private_data, struct pdb_samba_dsdb_state);
762 struct ldb_dn *dn;
763 int rc;
764 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
765 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
767 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, pdb_get_user_sid(sam)));
768 if (!dn || !ldb_dn_validate(dn)) {
769 talloc_free(tmp_ctx);
770 return NT_STATUS_NO_MEMORY;
772 rc = ldb_delete(state->ldb, dn);
774 if (rc != LDB_SUCCESS) {
775 DEBUG(10, ("ldb_delete for %s failed: %s\n", ldb_dn_get_linearized(dn),
776 ldb_errstring(state->ldb)));
777 talloc_free(tmp_ctx);
778 return NT_STATUS_LDAP(rc);
780 talloc_free(tmp_ctx);
781 return NT_STATUS_OK;
784 /* This interface takes a fully populated struct samu and places it in
785 * the database. This is not implemented at this time as we need to
786 * be careful around the creation of arbitary SIDs (ie, we must ensrue
787 * they are not left in a RID pool */
788 static NTSTATUS pdb_samba_dsdb_add_sam_account(struct pdb_methods *m,
789 struct samu *sampass)
791 int ret;
792 NTSTATUS status;
793 struct ldb_dn *dn;
794 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
795 m->private_data, struct pdb_samba_dsdb_state);
796 uint32_t acb_flags = pdb_get_acct_ctrl(sampass);
797 const char *username = pdb_get_username(sampass);
798 const struct dom_sid *user_sid = pdb_get_user_sid(sampass);
799 TALLOC_CTX *tframe = talloc_stackframe();
801 acb_flags &= (ACB_NORMAL|ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST);
803 ret = ldb_transaction_start(state->ldb);
804 if (ret != LDB_SUCCESS) {
805 talloc_free(tframe);
806 return NT_STATUS_LOCK_NOT_GRANTED;
809 status = dsdb_add_user(state->ldb, talloc_tos(), username,
810 acb_flags, user_sid, NULL, &dn);
811 if (!NT_STATUS_IS_OK(status)) {
812 ldb_transaction_cancel(state->ldb);
813 talloc_free(tframe);
814 return status;
817 ret = pdb_samba_dsdb_replace_by_sam(state, pdb_element_is_set_or_changed,
818 dn, sampass);
819 if (ret != LDB_SUCCESS) {
820 ldb_transaction_cancel(state->ldb);
821 talloc_free(tframe);
822 return dsdb_ldb_err_to_ntstatus(ret);
825 ret = ldb_transaction_commit(state->ldb);
826 if (ret != LDB_SUCCESS) {
827 DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
828 ldb_dn_get_linearized(dn),
829 ldb_errstring(state->ldb)));
830 talloc_free(tframe);
831 return NT_STATUS_INTERNAL_DB_CORRUPTION;
833 talloc_free(tframe);
834 return NT_STATUS_OK;
838 * Update the Samba_Dsdb LDB with the changes from a struct samu.
840 * This takes care not to update elements that have not been changed
841 * by the caller
843 static NTSTATUS pdb_samba_dsdb_update_sam_account(struct pdb_methods *m,
844 struct samu *sam)
846 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
847 m->private_data, struct pdb_samba_dsdb_state);
848 struct ldb_message *msg = pdb_samba_dsdb_get_samu_private(
849 m, sam);
850 int ret;
852 ret = pdb_samba_dsdb_replace_by_sam(state, pdb_element_is_changed, msg->dn,
853 sam);
854 return dsdb_ldb_err_to_ntstatus(ret);
857 static NTSTATUS pdb_samba_dsdb_delete_sam_account(struct pdb_methods *m,
858 struct samu *username)
860 NTSTATUS status;
861 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
862 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
863 status = pdb_samba_dsdb_delete_user(m, tmp_ctx, username);
864 talloc_free(tmp_ctx);
865 return status;
868 static NTSTATUS pdb_samba_dsdb_rename_sam_account(struct pdb_methods *m,
869 struct samu *oldname,
870 const char *newname)
872 return NT_STATUS_NOT_IMPLEMENTED;
875 /* This is not implemented, as this module is exptected to be used
876 * with auth_samba_dsdb, and this is responible for login counters etc
879 static NTSTATUS pdb_samba_dsdb_update_login_attempts(struct pdb_methods *m,
880 struct samu *sam_acct,
881 bool success)
883 return NT_STATUS_NOT_IMPLEMENTED;
886 static NTSTATUS pdb_samba_dsdb_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
887 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
889 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
890 m->private_data, struct pdb_samba_dsdb_state);
891 const char *attrs[] = { "objectClass", "objectSid", "description", "samAccountName", "groupType",
892 NULL };
893 struct ldb_message *msg;
894 va_list ap;
895 char *expression = NULL;
896 struct dom_sid *sid;
897 const char *str;
898 int rc;
899 struct id_map id_map;
900 struct id_map *id_maps[2];
901 TALLOC_CTX *tmp_ctx = talloc_stackframe();
902 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
904 va_start(ap, exp_fmt);
905 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
906 va_end(ap);
908 if (!expression) {
909 talloc_free(tmp_ctx);
910 return NT_STATUS_NO_MEMORY;
913 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
914 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
915 talloc_free(tmp_ctx);
916 return NT_STATUS_NO_SUCH_GROUP;
917 } else if (rc != LDB_SUCCESS) {
918 talloc_free(tmp_ctx);
919 DEBUG(10, ("dsdb_search_one failed %s\n",
920 ldb_errstring(state->ldb)));
921 return NT_STATUS_LDAP(rc);
924 sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
925 if (!sid) {
926 talloc_free(tmp_ctx);
927 DEBUG(10, ("Could not pull SID\n"));
928 return NT_STATUS_INTERNAL_DB_CORRUPTION;
931 map->sid = *sid;
933 if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
934 NTSTATUS status;
935 uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
936 switch (grouptype) {
937 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
938 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
939 map->sid_name_use = SID_NAME_ALIAS;
940 break;
941 case GTYPE_SECURITY_GLOBAL_GROUP:
942 map->sid_name_use = SID_NAME_DOM_GRP;
943 break;
944 default:
945 talloc_free(tmp_ctx);
946 DEBUG(10, ("Could not pull groupType\n"));
947 return NT_STATUS_INTERNAL_DB_CORRUPTION;
950 ZERO_STRUCT(id_map);
951 id_map.sid = sid;
952 id_maps[0] = &id_map;
953 id_maps[1] = NULL;
955 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
957 if (!NT_STATUS_IS_OK(status)) {
958 talloc_free(tmp_ctx);
959 return status;
961 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
962 map->gid = id_map.xid.id;
963 } else {
964 DEBUG(1, (__location__ "Did not get GUID when mapping SID for %s", expression));
965 talloc_free(tmp_ctx);
966 return NT_STATUS_INTERNAL_DB_CORRUPTION;
968 } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
969 DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
970 talloc_free(tmp_ctx);
971 return NT_STATUS_INTERNAL_DB_CORRUPTION;
974 str = ldb_msg_find_attr_as_string(msg, "samAccountName",
975 NULL);
976 if (str == NULL) {
977 talloc_free(tmp_ctx);
978 return NT_STATUS_INTERNAL_DB_CORRUPTION;
980 map->nt_name = talloc_strdup(map, str);
981 if (!map->nt_name) {
982 talloc_free(tmp_ctx);
983 return NT_STATUS_NO_MEMORY;
986 str = ldb_msg_find_attr_as_string(msg, "description",
987 NULL);
988 if (str != NULL) {
989 map->comment = talloc_strdup(map, str);
990 } else {
991 map->comment = talloc_strdup(map, "");
993 if (!map->comment) {
994 talloc_free(tmp_ctx);
995 return NT_STATUS_NO_MEMORY;
998 talloc_free(tmp_ctx);
999 return NT_STATUS_OK;
1002 static NTSTATUS pdb_samba_dsdb_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
1003 struct dom_sid sid)
1005 char *filter;
1006 NTSTATUS status;
1008 filter = talloc_asprintf(talloc_tos(),
1009 "(&(objectsid=%s)(objectclass=group))",
1010 sid_string_talloc(talloc_tos(), &sid));
1011 if (filter == NULL) {
1012 return NT_STATUS_NO_MEMORY;
1015 status = pdb_samba_dsdb_getgrfilter(m, map, filter);
1016 TALLOC_FREE(filter);
1017 return status;
1020 static NTSTATUS pdb_samba_dsdb_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
1021 gid_t gid)
1023 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1024 m->private_data, struct pdb_samba_dsdb_state);
1025 NTSTATUS status;
1026 struct id_map id_map;
1027 struct id_map *id_maps[2];
1028 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1029 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1031 id_map.xid.id = gid;
1032 id_map.xid.type = ID_TYPE_GID;
1033 id_maps[0] = &id_map;
1034 id_maps[1] = NULL;
1036 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1037 if (!NT_STATUS_IS_OK(status)) {
1038 talloc_free(tmp_ctx);
1039 return status;
1041 status = pdb_samba_dsdb_getgrsid(m, map, *id_map.sid);
1042 talloc_free(tmp_ctx);
1043 return status;
1046 static NTSTATUS pdb_samba_dsdb_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
1047 const char *name)
1049 char *filter;
1050 NTSTATUS status;
1052 filter = talloc_asprintf(talloc_tos(),
1053 "(&(samaccountname=%s)(objectclass=group))",
1054 name);
1055 if (filter == NULL) {
1056 return NT_STATUS_NO_MEMORY;
1059 status = pdb_samba_dsdb_getgrfilter(m, map, filter);
1060 TALLOC_FREE(filter);
1061 return status;
1064 static NTSTATUS pdb_samba_dsdb_create_dom_group(struct pdb_methods *m,
1065 TALLOC_CTX *mem_ctx, const char *name,
1066 uint32 *rid)
1068 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1069 m->private_data, struct pdb_samba_dsdb_state);
1070 NTSTATUS status;
1071 struct dom_sid *sid;
1072 struct ldb_dn *dn;
1073 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1074 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1076 status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
1077 if (!NT_STATUS_IS_OK(status)) {
1078 talloc_free(tmp_ctx);
1079 return status;
1082 sid_peek_rid(sid, rid);
1083 talloc_free(tmp_ctx);
1084 return NT_STATUS_OK;
1087 static NTSTATUS pdb_samba_dsdb_delete_dom_group(struct pdb_methods *m,
1088 TALLOC_CTX *mem_ctx, uint32 rid)
1090 const char *attrs[] = { NULL };
1091 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1092 m->private_data, struct pdb_samba_dsdb_state);
1093 struct dom_sid sid;
1094 struct ldb_message *msg;
1095 struct ldb_dn *dn;
1096 int rc;
1097 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1098 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1100 sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
1102 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1103 DEBUG(0, ("Unable to start transaction in pdb_samba_dsdb_delete_dom_group()\n"));
1104 return NT_STATUS_INTERNAL_ERROR;
1107 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
1108 if (!dn || !ldb_dn_validate(dn)) {
1109 talloc_free(tmp_ctx);
1110 ldb_transaction_cancel(state->ldb);
1111 return NT_STATUS_NO_MEMORY;
1113 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
1114 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1115 talloc_free(tmp_ctx);
1116 ldb_transaction_cancel(state->ldb);
1117 return NT_STATUS_NO_SUCH_GROUP;
1119 rc = ldb_delete(state->ldb, dn);
1120 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1121 talloc_free(tmp_ctx);
1122 ldb_transaction_cancel(state->ldb);
1123 return NT_STATUS_NO_SUCH_GROUP;
1124 } else if (rc != LDB_SUCCESS) {
1125 DEBUG(10, ("ldb_delete failed %s\n",
1126 ldb_errstring(state->ldb)));
1127 ldb_transaction_cancel(state->ldb);
1128 return NT_STATUS_LDAP(rc);
1131 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1132 DEBUG(0, ("Unable to commit transaction in pdb_samba_dsdb_delete_dom_group()\n"));
1133 return NT_STATUS_INTERNAL_ERROR;
1135 return NT_STATUS_OK;
1138 static NTSTATUS pdb_samba_dsdb_add_group_mapping_entry(struct pdb_methods *m,
1139 GROUP_MAP *map)
1141 return NT_STATUS_NOT_IMPLEMENTED;
1144 static NTSTATUS pdb_samba_dsdb_update_group_mapping_entry(struct pdb_methods *m,
1145 GROUP_MAP *map)
1147 return NT_STATUS_NOT_IMPLEMENTED;
1150 static NTSTATUS pdb_samba_dsdb_delete_group_mapping_entry(struct pdb_methods *m,
1151 struct dom_sid sid)
1153 return NT_STATUS_NOT_IMPLEMENTED;
1156 static NTSTATUS pdb_samba_dsdb_enum_group_mapping(struct pdb_methods *m,
1157 const struct dom_sid *sid,
1158 enum lsa_SidType sid_name_use,
1159 GROUP_MAP ***pp_rmap,
1160 size_t *p_num_entries,
1161 bool unix_only)
1163 return NT_STATUS_NOT_IMPLEMENTED;
1166 static NTSTATUS pdb_samba_dsdb_enum_group_members(struct pdb_methods *m,
1167 TALLOC_CTX *mem_ctx,
1168 const struct dom_sid *group,
1169 uint32_t **pmembers,
1170 size_t *pnum_members)
1172 unsigned int i, num_sids, num_members;
1173 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1174 m->private_data, struct pdb_samba_dsdb_state);
1175 struct dom_sid *members_as_sids;
1176 struct dom_sid *dom_sid;
1177 uint32_t *members;
1178 struct ldb_dn *dn;
1179 NTSTATUS status;
1181 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1182 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1184 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
1185 if (!dn || !ldb_dn_validate(dn)) {
1186 return NT_STATUS_NO_MEMORY;
1189 status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
1190 if (!NT_STATUS_IS_OK(status)) {
1191 talloc_free(tmp_ctx);
1192 return status;
1194 status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
1195 if (!NT_STATUS_IS_OK(status)) {
1196 talloc_free(tmp_ctx);
1197 return status;
1200 *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
1201 if (*pmembers == NULL) {
1202 TALLOC_FREE(tmp_ctx);
1203 return NT_STATUS_NO_MEMORY;
1205 num_members = 0;
1207 for (i = 0; i < num_sids; i++) {
1208 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
1209 continue;
1211 status = dom_sid_split_rid(NULL, &members_as_sids[i],
1212 NULL, &members[num_members]);
1213 if (!NT_STATUS_IS_OK(status)) {
1214 talloc_free(tmp_ctx);
1215 return status;
1217 num_members++;
1219 *pnum_members = num_members;
1220 return NT_STATUS_OK;
1223 /* Just convert the primary group SID into a group */
1224 static NTSTATUS fake_enum_group_memberships(struct pdb_samba_dsdb_state *state,
1225 TALLOC_CTX *mem_ctx,
1226 struct samu *user,
1227 struct dom_sid **pp_sids,
1228 gid_t **pp_gids,
1229 uint32_t *p_num_groups)
1231 NTSTATUS status;
1232 size_t num_groups = 0;
1233 struct dom_sid *group_sids = NULL;
1234 gid_t *gids = NULL;
1235 TALLOC_CTX *tmp_ctx;
1237 tmp_ctx = talloc_new(mem_ctx);
1238 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1240 if (user->group_sid) {
1241 struct id_map *id_maps[2];
1242 struct id_map id_map;
1244 num_groups = 1;
1246 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1247 if (group_sids == NULL) {
1248 talloc_free(tmp_ctx);
1249 return NT_STATUS_NO_MEMORY;
1251 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1252 if (gids == NULL) {
1253 talloc_free(tmp_ctx);
1254 return NT_STATUS_NO_MEMORY;
1257 group_sids[0] = *user->group_sid;
1259 ZERO_STRUCT(id_map);
1260 id_map.sid = &group_sids[0];
1261 id_maps[0] = &id_map;
1262 id_maps[1] = NULL;
1264 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1265 if (!NT_STATUS_IS_OK(status)) {
1266 talloc_free(tmp_ctx);
1267 return status;
1269 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1270 gids[0] = id_map.xid.id;
1271 } else {
1272 DEBUG(1, (__location__
1273 "Group %s, of which %s is a member, could not be converted to a GID\n",
1274 dom_sid_string(tmp_ctx, &group_sids[0]),
1275 dom_sid_string(tmp_ctx, &user->user_sid)));
1276 talloc_free(tmp_ctx);
1277 /* We must error out, otherwise a user might
1278 * avoid a DENY acl based on a group they
1279 * missed out on */
1280 return NT_STATUS_NO_SUCH_GROUP;
1284 *pp_sids = talloc_steal(mem_ctx, group_sids);
1285 *pp_gids = talloc_steal(mem_ctx, gids);
1286 *p_num_groups = num_groups;
1287 talloc_free(tmp_ctx);
1288 return NT_STATUS_OK;
1291 static NTSTATUS pdb_samba_dsdb_enum_group_memberships(struct pdb_methods *m,
1292 TALLOC_CTX *mem_ctx,
1293 struct samu *user,
1294 struct dom_sid **pp_sids,
1295 gid_t **pp_gids,
1296 uint32_t *p_num_groups)
1298 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1299 m->private_data, struct pdb_samba_dsdb_state);
1300 struct ldb_message *msg = pdb_samba_dsdb_get_samu_private(
1301 m, user);
1302 const char *attrs[] = { "tokenGroups", NULL};
1303 struct ldb_message *tokengroups_msg;
1304 struct ldb_message_element *tokengroups;
1305 int i, rc;
1306 NTSTATUS status;
1307 unsigned int count = 0;
1308 size_t num_groups;
1309 struct dom_sid *group_sids;
1310 gid_t *gids;
1311 TALLOC_CTX *tmp_ctx;
1313 if (msg == NULL) {
1314 /* Fake up some things here */
1315 return fake_enum_group_memberships(state,
1316 mem_ctx,
1317 user, pp_sids,
1318 pp_gids, p_num_groups);
1321 tmp_ctx = talloc_new(mem_ctx);
1322 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1324 rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1326 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1327 talloc_free(tmp_ctx);
1328 return NT_STATUS_NO_SUCH_USER;
1329 } else if (rc != LDB_SUCCESS) {
1330 DEBUG(10, ("dsdb_search_one failed %s\n",
1331 ldb_errstring(state->ldb)));
1332 talloc_free(tmp_ctx);
1333 return NT_STATUS_LDAP(rc);
1336 tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1338 if (tokengroups) {
1339 count = tokengroups->num_values;
1342 group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1343 if (group_sids == NULL) {
1344 talloc_free(tmp_ctx);
1345 return NT_STATUS_NO_MEMORY;
1347 gids = talloc_array(tmp_ctx, gid_t, count);
1348 if (gids == NULL) {
1349 talloc_free(tmp_ctx);
1350 return NT_STATUS_NO_MEMORY;
1352 num_groups = 0;
1354 for (i=0; i<count; i++) {
1355 struct id_map *id_maps[2];
1356 struct id_map id_map;
1357 struct ldb_val *v = &tokengroups->values[i];
1358 enum ndr_err_code ndr_err
1359 = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1360 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1361 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1362 talloc_free(tmp_ctx);
1363 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1366 ZERO_STRUCT(id_map);
1367 id_map.sid = &group_sids[num_groups];
1368 id_maps[0] = &id_map;
1369 id_maps[1] = NULL;
1371 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1372 if (!NT_STATUS_IS_OK(status)) {
1373 talloc_free(tmp_ctx);
1374 return status;
1376 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1377 gids[num_groups] = id_map.xid.id;
1378 } else {
1379 DEBUG(1, (__location__
1380 "Group %s, of which %s is a member, could not be converted to a GID\n",
1381 dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1382 ldb_dn_get_linearized(msg->dn)));
1383 talloc_free(tmp_ctx);
1384 /* We must error out, otherwise a user might
1385 * avoid a DENY acl based on a group they
1386 * missed out on */
1387 return NT_STATUS_NO_SUCH_GROUP;
1390 num_groups += 1;
1391 if (num_groups == count) {
1392 break;
1396 *pp_sids = talloc_steal(mem_ctx, group_sids);
1397 *pp_gids = talloc_steal(mem_ctx, gids);
1398 *p_num_groups = num_groups;
1399 talloc_free(tmp_ctx);
1400 return NT_STATUS_OK;
1403 static NTSTATUS pdb_samba_dsdb_set_unix_primary_group(struct pdb_methods *m,
1404 TALLOC_CTX *mem_ctx,
1405 struct samu *user)
1407 return NT_STATUS_NOT_IMPLEMENTED;
1410 static NTSTATUS pdb_samba_dsdb_mod_groupmem_by_sid(struct pdb_methods *m,
1411 TALLOC_CTX *mem_ctx,
1412 const struct dom_sid *groupsid,
1413 const struct dom_sid *membersid,
1414 int mod_op)
1416 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1417 m->private_data, struct pdb_samba_dsdb_state);
1418 struct ldb_message *msg;
1419 int ret;
1420 struct ldb_message_element *el;
1421 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1422 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1423 msg = ldb_msg_new(tmp_ctx);
1424 if (msg == NULL) {
1425 TALLOC_FREE(tmp_ctx);
1426 return NT_STATUS_NO_MEMORY;
1429 msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1430 if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1431 talloc_free(tmp_ctx);
1432 return NT_STATUS_NO_MEMORY;
1434 ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1435 if (ret != LDB_SUCCESS) {
1436 talloc_free(tmp_ctx);
1437 return NT_STATUS_NO_MEMORY;
1439 el = ldb_msg_find_element(msg, "member");
1440 el->flags = mod_op;
1442 /* No need for transactions here, the ldb auto-transaction
1443 * code will handle things for the single operation */
1444 ret = ldb_modify(state->ldb, msg);
1445 talloc_free(tmp_ctx);
1446 if (ret != LDB_SUCCESS) {
1447 DEBUG(10, ("ldb_modify failed: %s\n",
1448 ldb_errstring(state->ldb)));
1449 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1450 return NT_STATUS_MEMBER_IN_GROUP;
1452 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1453 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1455 return NT_STATUS_LDAP(ret);
1458 return NT_STATUS_OK;
1461 static NTSTATUS pdb_samba_dsdb_mod_groupmem(struct pdb_methods *m,
1462 TALLOC_CTX *mem_ctx,
1463 uint32 grouprid, uint32 memberrid,
1464 int mod_op)
1466 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1467 m->private_data, struct pdb_samba_dsdb_state);
1468 const struct dom_sid *dom_sid, *groupsid, *membersid;
1469 NTSTATUS status;
1470 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1471 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1473 dom_sid = samdb_domain_sid(state->ldb);
1475 groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1476 if (groupsid == NULL) {
1477 TALLOC_FREE(tmp_ctx);
1478 return NT_STATUS_NO_MEMORY;
1480 membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1481 if (membersid == NULL) {
1482 TALLOC_FREE(tmp_ctx);
1483 return NT_STATUS_NO_MEMORY;
1485 status = pdb_samba_dsdb_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1486 talloc_free(tmp_ctx);
1487 return status;
1490 static NTSTATUS pdb_samba_dsdb_add_groupmem(struct pdb_methods *m,
1491 TALLOC_CTX *mem_ctx,
1492 uint32 group_rid, uint32 member_rid)
1494 return pdb_samba_dsdb_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1495 LDB_FLAG_MOD_ADD);
1498 static NTSTATUS pdb_samba_dsdb_del_groupmem(struct pdb_methods *m,
1499 TALLOC_CTX *mem_ctx,
1500 uint32 group_rid, uint32 member_rid)
1502 return pdb_samba_dsdb_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1503 LDB_FLAG_MOD_DELETE);
1506 static NTSTATUS pdb_samba_dsdb_create_alias(struct pdb_methods *m,
1507 const char *name, uint32 *rid)
1509 TALLOC_CTX *frame = talloc_stackframe();
1510 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1511 m->private_data, struct pdb_samba_dsdb_state);
1512 struct dom_sid *sid;
1514 struct ldb_dn *dn;
1515 NTSTATUS status;
1517 /* Internally this uses transactions to ensure all the steps
1518 * happen or fail as one */
1519 status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1520 if (!NT_STATUS_IS_OK(status)) {
1521 TALLOC_FREE(frame);
1524 sid_peek_rid(sid, rid);
1525 TALLOC_FREE(frame);
1526 return NT_STATUS_OK;
1529 static NTSTATUS pdb_samba_dsdb_delete_alias(struct pdb_methods *m,
1530 const struct dom_sid *sid)
1532 const char *attrs[] = { NULL };
1533 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1534 m->private_data, struct pdb_samba_dsdb_state);
1535 struct ldb_message *msg;
1536 struct ldb_dn *dn;
1537 int rc;
1538 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1539 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1541 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1542 if (!dn || !ldb_dn_validate(dn)) {
1543 talloc_free(tmp_ctx);
1544 return NT_STATUS_NO_MEMORY;
1547 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1548 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1549 talloc_free(tmp_ctx);
1550 return NT_STATUS_INTERNAL_ERROR;
1553 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1554 "(|(grouptype=%d)(grouptype=%d)))",
1555 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1556 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1557 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1558 talloc_free(tmp_ctx);
1559 ldb_transaction_cancel(state->ldb);
1560 return NT_STATUS_NO_SUCH_ALIAS;
1562 rc = ldb_delete(state->ldb, dn);
1563 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1564 talloc_free(tmp_ctx);
1565 ldb_transaction_cancel(state->ldb);
1566 return NT_STATUS_NO_SUCH_ALIAS;
1567 } else if (rc != LDB_SUCCESS) {
1568 DEBUG(10, ("ldb_delete failed %s\n",
1569 ldb_errstring(state->ldb)));
1570 ldb_transaction_cancel(state->ldb);
1571 talloc_free(tmp_ctx);
1572 return NT_STATUS_LDAP(rc);
1575 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1576 DEBUG(0, ("Failed to commit transaction in pdb_samba_dsdb_delete_alias(): %s\n",
1577 ldb_errstring(state->ldb)));
1578 talloc_free(tmp_ctx);
1579 return NT_STATUS_INTERNAL_ERROR;
1582 talloc_free(tmp_ctx);
1583 return NT_STATUS_OK;
1586 #if 0
1587 static NTSTATUS pdb_samba_dsdb_set_aliasinfo(struct pdb_methods *m,
1588 const struct dom_sid *sid,
1589 struct acct_info *info)
1591 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1592 m->private_data, struct pdb_samba_dsdb_state);
1593 struct tldap_context *ld;
1594 const char *attrs[3] = { "objectSid", "description",
1595 "samAccountName" };
1596 struct ldb_message **msg;
1597 char *sidstr, *dn;
1598 int rc;
1599 struct tldap_mod *mods;
1600 int num_mods;
1601 bool ok;
1603 ld = pdb_samba_dsdb_ld(state);
1604 if (ld == NULL) {
1605 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1608 sidstr = sid_binstring(talloc_tos(), sid);
1609 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1611 rc = pdb_samba_dsdb_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1612 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1613 &msg, "(&(objectSid=%s)(objectclass=group)"
1614 "(|(grouptype=%d)(grouptype=%d)))",
1615 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1616 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1617 TALLOC_FREE(sidstr)
1618 if (rc != LDB_SUCCESS) {
1619 DEBUG(10, ("ldap_search failed %s\n",
1620 ldb_errstring(state->ldb)));
1621 return NT_STATUS_LDAP(rc);
1623 switch talloc_array_length(msg) {
1624 case 0:
1625 return NT_STATUS_NO_SUCH_ALIAS;
1626 case 1:
1627 break;
1628 default:
1629 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1632 if (!tldap_entry_dn(msg[0], &dn)) {
1633 TALLOC_FREE(msg);
1634 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1637 mods = NULL;
1638 num_mods = 0;
1639 ok = true;
1641 ok &= tldap_make_mod_fmt(
1642 msg[0], msg, &num_mods, &mods, "description",
1643 "%s", info->acct_desc);
1644 ok &= tldap_make_mod_fmt(
1645 msg[0], msg, &num_mods, &mods, "samAccountName",
1646 "%s", info->acct_name);
1647 if (!ok) {
1648 TALLOC_FREE(msg);
1649 return NT_STATUS_NO_MEMORY;
1651 if (num_mods == 0) {
1652 /* no change */
1653 TALLOC_FREE(msg);
1654 return NT_STATUS_OK;
1657 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1658 TALLOC_FREE(msg);
1659 if (rc != LDB_SUCCESS) {
1660 DEBUG(10, ("ldap_modify failed: %s\n",
1661 ldb_errstring(state->ldb)));
1662 return NT_STATUS_LDAP(rc);
1664 return NT_STATUS_OK;
1666 #endif
1667 static NTSTATUS pdb_samba_dsdb_add_aliasmem(struct pdb_methods *m,
1668 const struct dom_sid *alias,
1669 const struct dom_sid *member)
1671 NTSTATUS status;
1672 TALLOC_CTX *frame = talloc_stackframe();
1673 status = pdb_samba_dsdb_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1674 talloc_free(frame);
1675 return status;
1678 static NTSTATUS pdb_samba_dsdb_del_aliasmem(struct pdb_methods *m,
1679 const struct dom_sid *alias,
1680 const struct dom_sid *member)
1682 NTSTATUS status;
1683 TALLOC_CTX *frame = talloc_stackframe();
1684 status = pdb_samba_dsdb_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1685 talloc_free(frame);
1686 return status;
1689 static NTSTATUS pdb_samba_dsdb_enum_aliasmem(struct pdb_methods *m,
1690 const struct dom_sid *alias,
1691 TALLOC_CTX *mem_ctx,
1692 struct dom_sid **pmembers,
1693 size_t *pnum_members)
1695 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1696 m->private_data, struct pdb_samba_dsdb_state);
1697 struct ldb_dn *dn;
1698 unsigned int num_members;
1699 NTSTATUS status;
1700 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1701 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1703 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1704 if (!dn || !ldb_dn_validate(dn)) {
1705 return NT_STATUS_NO_MEMORY;
1708 status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1709 *pnum_members = num_members;
1710 if (NT_STATUS_IS_OK(status)) {
1711 talloc_steal(mem_ctx, pmembers);
1713 talloc_free(tmp_ctx);
1714 return status;
1717 static NTSTATUS pdb_samba_dsdb_enum_alias_memberships(struct pdb_methods *m,
1718 TALLOC_CTX *mem_ctx,
1719 const struct dom_sid *domain_sid,
1720 const struct dom_sid *members,
1721 size_t num_members,
1722 uint32_t **palias_rids,
1723 size_t *pnum_alias_rids)
1725 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1726 m->private_data, struct pdb_samba_dsdb_state);
1727 uint32_t *alias_rids = NULL;
1728 size_t num_alias_rids = 0;
1729 int i;
1730 struct dom_sid *groupSIDs = NULL;
1731 unsigned int num_groupSIDs = 0;
1732 char *filter;
1733 NTSTATUS status;
1734 const char *sid_string;
1735 const char *sid_dn;
1736 DATA_BLOB sid_blob;
1738 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1739 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1741 * TODO: Get the filter right so that we only get the aliases from
1742 * either the SAM or BUILTIN
1745 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1746 GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1747 if (filter == NULL) {
1748 return NT_STATUS_NO_MEMORY;
1751 for (i = 0; i < num_members; i++) {
1752 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1753 if (sid_string == NULL) {
1754 TALLOC_FREE(tmp_ctx);
1755 return NT_STATUS_NO_MEMORY;
1758 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1759 if (sid_dn == NULL) {
1760 TALLOC_FREE(tmp_ctx);
1761 return NT_STATUS_NO_MEMORY;
1764 sid_blob = data_blob_string_const(sid_dn);
1766 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1767 tmp_ctx, &groupSIDs, &num_groupSIDs);
1768 if (!NT_STATUS_IS_OK(status)) {
1769 talloc_free(tmp_ctx);
1770 return status;
1774 alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1775 if (alias_rids == NULL) {
1776 talloc_free(tmp_ctx);
1777 return NT_STATUS_NO_MEMORY;
1780 for (i=0; i<num_groupSIDs; i++) {
1781 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1782 &alias_rids[num_alias_rids])) {
1783 num_alias_rids++;;
1787 *palias_rids = alias_rids;
1788 *pnum_alias_rids = num_alias_rids;
1789 return NT_STATUS_OK;
1792 static NTSTATUS pdb_samba_dsdb_lookup_rids(struct pdb_methods *m,
1793 const struct dom_sid *domain_sid,
1794 int num_rids,
1795 uint32 *rids,
1796 const char **names,
1797 enum lsa_SidType *lsa_attrs)
1799 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1800 m->private_data, struct pdb_samba_dsdb_state);
1801 NTSTATUS status;
1803 TALLOC_CTX *tmp_ctx;
1805 if (num_rids == 0) {
1806 return NT_STATUS_NONE_MAPPED;
1809 tmp_ctx = talloc_stackframe();
1810 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1812 status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1813 talloc_free(tmp_ctx);
1814 return status;
1817 static NTSTATUS pdb_samba_dsdb_lookup_names(struct pdb_methods *m,
1818 const struct dom_sid *domain_sid,
1819 int num_names,
1820 const char **pp_names,
1821 uint32 *rids,
1822 enum lsa_SidType *attrs)
1824 return NT_STATUS_NOT_IMPLEMENTED;
1827 static NTSTATUS pdb_samba_dsdb_get_account_policy(struct pdb_methods *m,
1828 enum pdb_policy_type type,
1829 uint32_t *value)
1831 return account_policy_get(type, value)
1832 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1835 static NTSTATUS pdb_samba_dsdb_set_account_policy(struct pdb_methods *m,
1836 enum pdb_policy_type type,
1837 uint32_t value)
1839 return account_policy_set(type, value)
1840 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1843 static NTSTATUS pdb_samba_dsdb_get_seq_num(struct pdb_methods *m,
1844 time_t *seq_num_out)
1846 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1847 m->private_data, struct pdb_samba_dsdb_state);
1848 uint64_t seq_num;
1849 int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1850 if (ret == LDB_SUCCESS) {
1851 *seq_num_out = seq_num;
1852 return NT_STATUS_OK;
1853 } else {
1854 return NT_STATUS_UNSUCCESSFUL;
1858 struct pdb_samba_dsdb_search_state {
1859 uint32_t acct_flags;
1860 struct samr_displayentry *entries;
1861 uint32_t num_entries;
1862 ssize_t array_size;
1863 uint32_t current;
1866 static bool pdb_samba_dsdb_next_entry(struct pdb_search *search,
1867 struct samr_displayentry *entry)
1869 struct pdb_samba_dsdb_search_state *state = talloc_get_type_abort(
1870 search->private_data, struct pdb_samba_dsdb_search_state);
1872 if (state->current == state->num_entries) {
1873 return false;
1876 entry->idx = state->entries[state->current].idx;
1877 entry->rid = state->entries[state->current].rid;
1878 entry->acct_flags = state->entries[state->current].acct_flags;
1880 entry->account_name = talloc_strdup(
1881 search, state->entries[state->current].account_name);
1882 entry->fullname = talloc_strdup(
1883 search, state->entries[state->current].fullname);
1884 entry->description = talloc_strdup(
1885 search, state->entries[state->current].description);
1887 state->current += 1;
1888 return true;
1891 static void pdb_samba_dsdb_search_end(struct pdb_search *search)
1893 struct pdb_samba_dsdb_search_state *state = talloc_get_type_abort(
1894 search->private_data, struct pdb_samba_dsdb_search_state);
1895 talloc_free(state);
1898 static bool pdb_samba_dsdb_search_filter(struct pdb_methods *m,
1899 struct pdb_search *search,
1900 struct pdb_samba_dsdb_search_state **pstate,
1901 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1903 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1904 m->private_data, struct pdb_samba_dsdb_state);
1905 struct pdb_samba_dsdb_search_state *sstate;
1906 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1907 "userAccountControl", "description", NULL };
1908 struct ldb_result *res;
1909 int i, rc, num_users;
1911 va_list ap;
1912 char *expression = NULL;
1914 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1915 if (!tmp_ctx) {
1916 return false;
1919 va_start(ap, exp_fmt);
1920 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1921 va_end(ap);
1923 if (!expression) {
1924 talloc_free(tmp_ctx);
1925 return LDB_ERR_OPERATIONS_ERROR;
1928 sstate = talloc_zero(tmp_ctx, struct pdb_samba_dsdb_search_state);
1929 if (sstate == NULL) {
1930 talloc_free(tmp_ctx);
1931 return false;
1934 rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1935 if (rc != LDB_SUCCESS) {
1936 talloc_free(tmp_ctx);
1937 DEBUG(10, ("dsdb_search failed: %s\n",
1938 ldb_errstring(state->ldb)));
1939 return false;
1942 num_users = res->count;
1944 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1945 num_users);
1946 if (sstate->entries == NULL) {
1947 talloc_free(tmp_ctx);
1948 DEBUG(10, ("talloc failed\n"));
1949 return false;
1952 sstate->num_entries = 0;
1954 for (i=0; i<num_users; i++) {
1955 struct samr_displayentry *e;
1956 struct dom_sid *sid;
1958 e = &sstate->entries[sstate->num_entries];
1960 e->idx = sstate->num_entries;
1961 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1962 if (!sid) {
1963 talloc_free(tmp_ctx);
1964 DEBUG(10, ("Could not pull SID\n"));
1965 return false;
1967 sid_peek_rid(sid, &e->rid);
1969 e->acct_flags = samdb_result_acct_flags(res->msgs[i], "userAccountControl");
1970 e->account_name = ldb_msg_find_attr_as_string(
1971 res->msgs[i], "samAccountName", NULL);
1972 if (e->account_name == NULL) {
1973 talloc_free(tmp_ctx);
1974 return false;
1976 e->fullname = ldb_msg_find_attr_as_string(
1977 res->msgs[i], "displayName", "");
1978 e->description = ldb_msg_find_attr_as_string(
1979 res->msgs[i], "description", "");
1981 sstate->num_entries += 1;
1982 if (sstate->num_entries >= num_users) {
1983 break;
1986 talloc_steal(sstate->entries, res->msgs);
1987 search->private_data = talloc_steal(search, sstate);
1988 search->next_entry = pdb_samba_dsdb_next_entry;
1989 search->search_end = pdb_samba_dsdb_search_end;
1990 *pstate = sstate;
1991 talloc_free(tmp_ctx);
1992 return true;
1995 static bool pdb_samba_dsdb_search_users(struct pdb_methods *m,
1996 struct pdb_search *search,
1997 uint32 acct_flags)
1999 struct pdb_samba_dsdb_search_state *sstate;
2000 bool ret;
2002 ret = pdb_samba_dsdb_search_filter(m, search, &sstate, "(objectclass=user)");
2003 if (!ret) {
2004 return false;
2006 sstate->acct_flags = acct_flags;
2007 return true;
2010 static bool pdb_samba_dsdb_search_groups(struct pdb_methods *m,
2011 struct pdb_search *search)
2013 struct pdb_samba_dsdb_search_state *sstate;
2014 bool ret;
2016 ret = pdb_samba_dsdb_search_filter(m, search, &sstate,
2017 "(&(grouptype=%d)(objectclass=group))",
2018 GTYPE_SECURITY_GLOBAL_GROUP);
2019 if (!ret) {
2020 return false;
2022 sstate->acct_flags = 0;
2023 return true;
2026 static bool pdb_samba_dsdb_search_aliases(struct pdb_methods *m,
2027 struct pdb_search *search,
2028 const struct dom_sid *sid)
2030 struct pdb_samba_dsdb_search_state *sstate;
2031 bool ret;
2033 ret = pdb_samba_dsdb_search_filter(m, search, &sstate,
2034 "(&(grouptype=%d)(objectclass=group))",
2035 sid_check_is_builtin(sid)
2036 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2037 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
2038 if (!ret) {
2039 return false;
2041 sstate->acct_flags = 0;
2042 return true;
2045 static bool pdb_samba_dsdb_uid_to_sid(struct pdb_methods *m, uid_t uid,
2046 struct dom_sid *sid)
2048 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2049 m->private_data, struct pdb_samba_dsdb_state);
2050 NTSTATUS status;
2051 struct id_map id_map;
2052 struct id_map *id_maps[2];
2053 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2054 if (!tmp_ctx) {
2055 return false;
2058 id_map.xid.id = uid;
2059 id_map.xid.type = ID_TYPE_UID;
2060 id_maps[0] = &id_map;
2061 id_maps[1] = NULL;
2063 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2064 if (!NT_STATUS_IS_OK(status)) {
2065 talloc_free(tmp_ctx);
2066 return false;
2068 *sid = *id_map.sid;
2069 talloc_free(tmp_ctx);
2070 return true;
2073 static bool pdb_samba_dsdb_gid_to_sid(struct pdb_methods *m, gid_t gid,
2074 struct dom_sid *sid)
2076 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2077 m->private_data, struct pdb_samba_dsdb_state);
2078 NTSTATUS status;
2079 struct id_map id_map;
2080 struct id_map *id_maps[2];
2081 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2082 if (!tmp_ctx) {
2083 return false;
2086 id_map.xid.id = gid;
2087 id_map.xid.type = ID_TYPE_GID;
2088 id_maps[0] = &id_map;
2089 id_maps[1] = NULL;
2091 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2092 if (!NT_STATUS_IS_OK(status)) {
2093 talloc_free(tmp_ctx);
2094 return false;
2096 *sid = *id_map.sid;
2097 talloc_free(tmp_ctx);
2098 return true;
2101 static bool pdb_samba_dsdb_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2102 struct unixid *id)
2104 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2105 m->private_data, struct pdb_samba_dsdb_state);
2106 struct id_map id_map;
2107 struct id_map *id_maps[2];
2108 NTSTATUS status;
2109 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2110 if (!tmp_ctx) {
2111 return false;
2114 ZERO_STRUCT(id_map);
2115 id_map.sid = discard_const_p(struct dom_sid, sid);
2116 id_maps[0] = &id_map;
2117 id_maps[1] = NULL;
2119 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2120 talloc_free(tmp_ctx);
2121 if (!NT_STATUS_IS_OK(status)) {
2122 return false;
2124 if (id_map.xid.type != ID_TYPE_NOT_SPECIFIED) {
2125 *id = id_map.xid;
2126 return true;
2128 return false;
2131 static uint32_t pdb_samba_dsdb_capabilities(struct pdb_methods *m)
2133 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2136 static bool pdb_samba_dsdb_new_rid(struct pdb_methods *m, uint32 *rid)
2138 return false;
2141 static bool pdb_samba_dsdb_get_trusteddom_pw(struct pdb_methods *m,
2142 const char *domain, char** pwd,
2143 struct dom_sid *sid,
2144 time_t *pass_last_set_time)
2146 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2147 m->private_data, struct pdb_samba_dsdb_state);
2148 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2149 const char * const attrs[] = {
2150 "securityIdentifier",
2151 "trustPartner",
2152 "trustAuthOutgoing",
2153 "whenCreated",
2154 "msDS-SupportedEncryptionTypes",
2155 "trustAttributes",
2156 "trustDirection",
2157 "trustType",
2158 NULL
2160 struct ldb_message *msg;
2161 const struct ldb_val *password_val;
2162 int trust_direction_flags;
2163 int trust_type;
2164 int i;
2165 DATA_BLOB password_utf16;
2166 struct trustAuthInOutBlob password_blob;
2167 struct AuthenticationInformationArray *auth_array;
2168 char *password_talloc;
2169 size_t password_len;
2170 enum ndr_err_code ndr_err;
2171 NTSTATUS status;
2173 status = sam_get_results_trust(state->ldb, tmp_ctx, domain,
2174 NULL, attrs, &msg);
2175 if (!NT_STATUS_IS_OK(status)) {
2177 * This can be called to work out of a domain is
2178 * trusted, rather than just to get the password
2180 DEBUG(2, ("Failed to get trusted domain password for %s. "
2181 "It may not be a trusted domain.\n", domain));
2182 TALLOC_FREE(tmp_ctx);
2183 return false;
2186 trust_direction_flags = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
2187 if (!(trust_direction_flags & LSA_TRUST_DIRECTION_OUTBOUND)) {
2188 DEBUG(2, ("Trusted domain %s is is not an outbound trust.\n",
2189 domain));
2190 TALLOC_FREE(tmp_ctx);
2191 return false;
2194 trust_type = ldb_msg_find_attr_as_int(msg, "trustType", 0);
2195 if (trust_type == LSA_TRUST_TYPE_MIT) {
2196 DEBUG(1, ("Trusted domain %s is is not an AD trust "
2197 "(trustType == LSA_TRUST_TYPE_MIT).\n",
2198 domain));
2199 TALLOC_FREE(tmp_ctx);
2200 return false;
2203 password_val = ldb_msg_find_ldb_val(msg, "trustAuthOutgoing");
2204 if (password_val == NULL) {
2205 DEBUG(2, ("Failed to get trusted domain password for %s, "
2206 "attribute trustAuthOutgoing not returned.\n", domain));
2207 TALLOC_FREE(tmp_ctx);
2208 return false;
2211 ndr_err = ndr_pull_struct_blob(password_val, tmp_ctx, &password_blob,
2212 (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob);
2213 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2214 DEBUG(0, ("Failed to get trusted domain password for %s, "
2215 "attribute trustAuthOutgoing coult not be parsed %s.\n",
2216 domain,
2217 ndr_map_error2string(ndr_err)));
2218 TALLOC_FREE(tmp_ctx);
2219 return false;
2222 auth_array = &password_blob.current;
2224 for (i=0; i < auth_array->count; i++) {
2225 if (auth_array->array[i].AuthType == TRUST_AUTH_TYPE_CLEAR) {
2226 break;
2230 if (i == auth_array->count) {
2231 DEBUG(0, ("Trusted domain %s does not have a "
2232 "clear-text password stored\n",
2233 domain));
2234 TALLOC_FREE(tmp_ctx);
2235 return false;
2238 password_utf16 = data_blob_const(auth_array->array[i].AuthInfo.clear.password,
2239 auth_array->array[i].AuthInfo.clear.size);
2242 * In the future, make this function return a
2243 * cli_credentials that can store a MD4 hash with cli_credential_set_nt_hash()
2244 * but for now convert to UTF8 and fail if the string can not be converted.
2246 * We can't safely convert the random strings windows uses into
2247 * utf8.
2249 if (!convert_string_talloc(tmp_ctx,
2250 CH_UTF16, CH_UTF8,
2251 password_utf16.data, password_utf16.length,
2252 (void *)&password_talloc,
2253 &password_len)) {
2254 DEBUG(0, ("FIXME: Could not convert password for trusted domain %s"
2255 " to UTF8. This may be a password set from Windows.\n",
2256 domain));
2257 TALLOC_FREE(tmp_ctx);
2258 return false;
2260 *pwd = SMB_STRNDUP(password_talloc, password_len);
2261 if (pass_last_set_time) {
2262 *pass_last_set_time = nt_time_to_unix(auth_array->array[i].LastUpdateTime);
2265 TALLOC_FREE(tmp_ctx);
2266 return true;
2269 static bool pdb_samba_dsdb_set_trusteddom_pw(struct pdb_methods *m,
2270 const char* domain, const char* pwd,
2271 const struct dom_sid *sid)
2273 return false;
2276 static bool pdb_samba_dsdb_del_trusteddom_pw(struct pdb_methods *m,
2277 const char *domain)
2279 return false;
2282 static NTSTATUS pdb_samba_dsdb_enum_trusteddoms(struct pdb_methods *m,
2283 TALLOC_CTX *mem_ctx,
2284 uint32 *num_domains,
2285 struct trustdom_info ***domains)
2287 *num_domains = 0;
2288 *domains = NULL;
2289 return NT_STATUS_OK;
2292 static bool pdb_samba_dsdb_is_responsible_for_wellknown(struct pdb_methods *m)
2294 return true;
2297 static bool pdb_samba_dsdb_is_responsible_for_everything_else(struct pdb_methods *m)
2299 return true;
2302 static void pdb_samba_dsdb_init_methods(struct pdb_methods *m)
2304 m->name = "samba_dsdb";
2305 m->get_domain_info = pdb_samba_dsdb_get_domain_info;
2306 m->getsampwnam = pdb_samba_dsdb_getsampwnam;
2307 m->getsampwsid = pdb_samba_dsdb_getsampwsid;
2308 m->create_user = pdb_samba_dsdb_create_user;
2309 m->delete_user = pdb_samba_dsdb_delete_user;
2310 m->add_sam_account = pdb_samba_dsdb_add_sam_account;
2311 m->update_sam_account = pdb_samba_dsdb_update_sam_account;
2312 m->delete_sam_account = pdb_samba_dsdb_delete_sam_account;
2313 m->rename_sam_account = pdb_samba_dsdb_rename_sam_account;
2314 m->update_login_attempts = pdb_samba_dsdb_update_login_attempts;
2315 m->getgrsid = pdb_samba_dsdb_getgrsid;
2316 m->getgrgid = pdb_samba_dsdb_getgrgid;
2317 m->getgrnam = pdb_samba_dsdb_getgrnam;
2318 m->create_dom_group = pdb_samba_dsdb_create_dom_group;
2319 m->delete_dom_group = pdb_samba_dsdb_delete_dom_group;
2320 m->add_group_mapping_entry = pdb_samba_dsdb_add_group_mapping_entry;
2321 m->update_group_mapping_entry = pdb_samba_dsdb_update_group_mapping_entry;
2322 m->delete_group_mapping_entry = pdb_samba_dsdb_delete_group_mapping_entry;
2323 m->enum_group_mapping = pdb_samba_dsdb_enum_group_mapping;
2324 m->enum_group_members = pdb_samba_dsdb_enum_group_members;
2325 m->enum_group_memberships = pdb_samba_dsdb_enum_group_memberships;
2326 m->set_unix_primary_group = pdb_samba_dsdb_set_unix_primary_group;
2327 m->add_groupmem = pdb_samba_dsdb_add_groupmem;
2328 m->del_groupmem = pdb_samba_dsdb_del_groupmem;
2329 m->create_alias = pdb_samba_dsdb_create_alias;
2330 m->delete_alias = pdb_samba_dsdb_delete_alias;
2331 m->get_aliasinfo = pdb_default_get_aliasinfo;
2332 m->add_aliasmem = pdb_samba_dsdb_add_aliasmem;
2333 m->del_aliasmem = pdb_samba_dsdb_del_aliasmem;
2334 m->enum_aliasmem = pdb_samba_dsdb_enum_aliasmem;
2335 m->enum_alias_memberships = pdb_samba_dsdb_enum_alias_memberships;
2336 m->lookup_rids = pdb_samba_dsdb_lookup_rids;
2337 m->lookup_names = pdb_samba_dsdb_lookup_names;
2338 m->get_account_policy = pdb_samba_dsdb_get_account_policy;
2339 m->set_account_policy = pdb_samba_dsdb_set_account_policy;
2340 m->get_seq_num = pdb_samba_dsdb_get_seq_num;
2341 m->search_users = pdb_samba_dsdb_search_users;
2342 m->search_groups = pdb_samba_dsdb_search_groups;
2343 m->search_aliases = pdb_samba_dsdb_search_aliases;
2344 m->uid_to_sid = pdb_samba_dsdb_uid_to_sid;
2345 m->gid_to_sid = pdb_samba_dsdb_gid_to_sid;
2346 m->sid_to_id = pdb_samba_dsdb_sid_to_id;
2347 m->capabilities = pdb_samba_dsdb_capabilities;
2348 m->new_rid = pdb_samba_dsdb_new_rid;
2349 m->get_trusteddom_pw = pdb_samba_dsdb_get_trusteddom_pw;
2350 m->set_trusteddom_pw = pdb_samba_dsdb_set_trusteddom_pw;
2351 m->del_trusteddom_pw = pdb_samba_dsdb_del_trusteddom_pw;
2352 m->enum_trusteddoms = pdb_samba_dsdb_enum_trusteddoms;
2353 m->is_responsible_for_wellknown =
2354 pdb_samba_dsdb_is_responsible_for_wellknown;
2355 m->is_responsible_for_everything_else =
2356 pdb_samba_dsdb_is_responsible_for_everything_else;
2359 static void free_private_data(void **vp)
2361 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2362 *vp, struct pdb_samba_dsdb_state);
2363 talloc_unlink(state, state->ldb);
2364 return;
2367 static NTSTATUS pdb_samba_dsdb_init_secrets(struct pdb_methods *m)
2369 struct pdb_domain_info *dom_info;
2370 struct dom_sid stored_sid;
2371 struct GUID stored_guid;
2372 bool sid_exists_and_matches = false;
2373 bool guid_exists_and_matches = false;
2374 bool ret;
2376 dom_info = pdb_samba_dsdb_get_domain_info(m, m);
2377 if (!dom_info) {
2378 return NT_STATUS_UNSUCCESSFUL;
2381 ret = secrets_fetch_domain_sid(dom_info->name, &stored_sid);
2382 if (ret) {
2383 if (dom_sid_equal(&stored_sid, &dom_info->sid)) {
2384 sid_exists_and_matches = true;
2388 if (sid_exists_and_matches == false) {
2389 secrets_clear_domain_protection(dom_info->name);
2390 ret = secrets_store_domain_sid(dom_info->name,
2391 &dom_info->sid);
2392 ret &= secrets_mark_domain_protected(dom_info->name);
2393 if (!ret) {
2394 goto done;
2398 ret = secrets_fetch_domain_guid(dom_info->name, &stored_guid);
2399 if (ret) {
2400 if (GUID_equal(&stored_guid, &dom_info->guid)) {
2401 guid_exists_and_matches = true;
2405 if (guid_exists_and_matches == false) {
2406 secrets_clear_domain_protection(dom_info->name);
2407 ret = secrets_store_domain_guid(dom_info->name,
2408 &dom_info->guid);
2409 ret &= secrets_mark_domain_protected(dom_info->name);
2410 if (!ret) {
2411 goto done;
2415 done:
2416 TALLOC_FREE(dom_info);
2417 if (!ret) {
2418 return NT_STATUS_UNSUCCESSFUL;
2420 return NT_STATUS_OK;
2423 static NTSTATUS pdb_init_samba_dsdb(struct pdb_methods **pdb_method,
2424 const char *location)
2426 struct pdb_methods *m;
2427 struct pdb_samba_dsdb_state *state;
2428 NTSTATUS status;
2430 if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2431 return status;
2434 state = talloc_zero(m, struct pdb_samba_dsdb_state);
2435 if (state == NULL) {
2436 goto nomem;
2438 m->private_data = state;
2439 m->free_private_data = free_private_data;
2440 pdb_samba_dsdb_init_methods(m);
2442 state->ev = s4_event_context_init(state);
2443 if (!state->ev) {
2444 DEBUG(0, ("s4_event_context_init failed\n"));
2445 goto nomem;
2448 state->lp_ctx = loadparm_init_s3(state, loadparm_s3_helpers());
2449 if (state->lp_ctx == NULL) {
2450 DEBUG(0, ("loadparm_init_s3 failed\n"));
2451 goto nomem;
2454 if (location) {
2455 state->ldb = samdb_connect_url(state,
2456 state->ev,
2457 state->lp_ctx,
2458 system_session(state->lp_ctx),
2459 0, location);
2460 } else {
2461 state->ldb = samdb_connect(state,
2462 state->ev,
2463 state->lp_ctx,
2464 system_session(state->lp_ctx), 0);
2467 if (!state->ldb) {
2468 DEBUG(0, ("samdb_connect failed\n"));
2469 status = NT_STATUS_INTERNAL_ERROR;
2470 goto fail;
2473 state->idmap_ctx = idmap_init(state, state->ev,
2474 state->lp_ctx);
2475 if (!state->idmap_ctx) {
2476 DEBUG(0, ("idmap failed\n"));
2477 status = NT_STATUS_INTERNAL_ERROR;
2478 goto fail;
2481 status = pdb_samba_dsdb_init_secrets(m);
2482 if (!NT_STATUS_IS_OK(status)) {
2483 DEBUG(10, ("pdb_samba_dsdb_init_secrets failed!\n"));
2484 goto fail;
2487 *pdb_method = m;
2488 return NT_STATUS_OK;
2489 nomem:
2490 status = NT_STATUS_NO_MEMORY;
2491 fail:
2492 TALLOC_FREE(m);
2493 return status;
2496 NTSTATUS pdb_samba_dsdb_init(void);
2497 NTSTATUS pdb_samba_dsdb_init(void)
2499 NTSTATUS status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba_dsdb",
2500 pdb_init_samba_dsdb);
2501 if (!NT_STATUS_IS_OK(status)) {
2502 return status;
2504 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
2505 pdb_init_samba_dsdb);