werror: replace WERR_NO_SUCH_SHARE with WERR_BAD_NET_NAME in source3/rpc_server/srvsv...
[Samba.git] / source3 / passdb / pdb_samba_dsdb.c
blob97806c4af2575474898e75f91713cbb5cfc3c6b0
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"
41 #include "auth/credentials/credentials.h"
42 #include "lib/util/base64.h"
44 struct pdb_samba_dsdb_state {
45 struct tevent_context *ev;
46 struct ldb_context *ldb;
47 struct idmap_context *idmap_ctx;
48 struct loadparm_context *lp_ctx;
51 static NTSTATUS pdb_samba_dsdb_getsampwsid(struct pdb_methods *m,
52 struct samu *sam_acct,
53 const struct dom_sid *sid);
54 static NTSTATUS pdb_samba_dsdb_getsamupriv(struct pdb_samba_dsdb_state *state,
55 const char *filter,
56 TALLOC_CTX *mem_ctx,
57 struct ldb_message **pmsg);
58 static bool pdb_samba_dsdb_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
59 struct unixid *id);
61 static bool pdb_samba_dsdb_pull_time(struct ldb_message *msg, const char *attr,
62 time_t *ptime)
64 uint64_t tmp;
65 if (! ldb_msg_find_element(msg, attr)) {
66 return false;
68 tmp = ldb_msg_find_attr_as_uint64(msg, attr, 0);
69 *ptime = nt_time_to_unix(tmp);
70 return true;
73 static struct pdb_domain_info *pdb_samba_dsdb_get_domain_info(
74 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
76 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
77 m->private_data, struct pdb_samba_dsdb_state);
78 struct pdb_domain_info *info;
79 struct dom_sid *domain_sid;
80 struct ldb_dn *forest_dn, *domain_dn;
81 struct ldb_result *dom_res = NULL;
82 const char *dom_attrs[] = {
83 "objectSid",
84 "objectGUID",
85 "fSMORoleOwner",
86 NULL
88 char *p;
89 int ret;
91 info = talloc(mem_ctx, struct pdb_domain_info);
92 if (info == NULL) {
93 return NULL;
96 domain_dn = ldb_get_default_basedn(state->ldb);
98 ret = ldb_search(state->ldb, info, &dom_res,
99 domain_dn, LDB_SCOPE_BASE, dom_attrs, NULL);
100 if (ret != LDB_SUCCESS) {
101 goto fail;
103 if (dom_res->count != 1) {
104 goto fail;
107 info->guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
109 domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
110 if (!domain_sid) {
111 goto fail;
113 info->sid = *domain_sid;
115 TALLOC_FREE(dom_res);
117 info->name = talloc_strdup(info, lpcfg_sam_name(state->lp_ctx));
118 info->dns_domain = ldb_dn_canonical_string(info, domain_dn);
120 if (!info->dns_domain) {
121 goto fail;
123 p = strchr(info->dns_domain, '/');
124 if (p) {
125 *p = '\0';
128 forest_dn = ldb_get_root_basedn(state->ldb);
129 if (!forest_dn) {
130 goto fail;
133 info->dns_forest = ldb_dn_canonical_string(info, forest_dn);
134 if (!info->dns_forest) {
135 goto fail;
137 p = strchr(info->dns_forest, '/');
138 if (p) {
139 *p = '\0';
142 return info;
144 fail:
145 TALLOC_FREE(dom_res);
146 TALLOC_FREE(info);
147 return NULL;
150 static struct ldb_message *pdb_samba_dsdb_get_samu_private(
151 struct pdb_methods *m, struct samu *sam)
153 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
154 m->private_data, struct pdb_samba_dsdb_state);
155 struct ldb_message *msg;
156 char *sidstr, *filter;
157 NTSTATUS status;
159 msg = (struct ldb_message *)
160 pdb_get_backend_private_data(sam, m);
162 if (msg != NULL) {
163 return talloc_get_type_abort(msg, struct ldb_message);
166 sidstr = dom_sid_string(talloc_tos(), pdb_get_user_sid(sam));
167 if (sidstr == NULL) {
168 return NULL;
171 filter = talloc_asprintf(
172 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
173 TALLOC_FREE(sidstr);
174 if (filter == NULL) {
175 return NULL;
178 status = pdb_samba_dsdb_getsamupriv(state, filter, sam, &msg);
179 TALLOC_FREE(filter);
180 if (!NT_STATUS_IS_OK(status)) {
181 return NULL;
184 return msg;
187 static NTSTATUS pdb_samba_dsdb_init_sam_from_priv(struct pdb_methods *m,
188 struct samu *sam,
189 struct ldb_message *msg)
191 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
192 m->private_data, struct pdb_samba_dsdb_state);
193 TALLOC_CTX *frame = talloc_stackframe();
194 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
195 const char *str;
196 time_t tmp_time;
197 struct dom_sid *sid, group_sid;
198 uint64_t n;
199 const DATA_BLOB *blob;
201 str = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
202 if (str == NULL) {
203 DEBUG(10, ("no samAccountName\n"));
204 goto fail;
206 pdb_set_username(sam, str, PDB_SET);
208 if (pdb_samba_dsdb_pull_time(msg, "lastLogon", &tmp_time)) {
209 pdb_set_logon_time(sam, tmp_time, PDB_SET);
211 if (pdb_samba_dsdb_pull_time(msg, "lastLogoff", &tmp_time)) {
212 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
214 if (pdb_samba_dsdb_pull_time(msg, "pwdLastSet", &tmp_time)) {
215 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
217 if (pdb_samba_dsdb_pull_time(msg, "accountExpires", &tmp_time)) {
218 pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
221 str = ldb_msg_find_attr_as_string(msg, "displayName",
222 NULL);
223 if (str != NULL) {
224 pdb_set_fullname(sam, str, PDB_SET);
227 str = ldb_msg_find_attr_as_string(msg, "homeDirectory",
228 NULL);
229 if (str != NULL) {
230 pdb_set_homedir(sam, str, PDB_SET);
233 str = ldb_msg_find_attr_as_string(msg, "homeDrive", NULL);
234 if (str != NULL) {
235 pdb_set_dir_drive(sam, str, PDB_SET);
238 str = ldb_msg_find_attr_as_string(msg, "scriptPath", NULL);
239 if (str != NULL) {
240 pdb_set_logon_script(sam, str, PDB_SET);
243 str = ldb_msg_find_attr_as_string(msg, "profilePath",
244 NULL);
245 if (str != NULL) {
246 pdb_set_profile_path(sam, str, PDB_SET);
249 str = ldb_msg_find_attr_as_string(msg, "comment",
250 NULL);
251 if (str != NULL) {
252 pdb_set_comment(sam, str, PDB_SET);
255 str = ldb_msg_find_attr_as_string(msg, "description",
256 NULL);
257 if (str != NULL) {
258 pdb_set_acct_desc(sam, str, PDB_SET);
261 str = ldb_msg_find_attr_as_string(msg, "userWorkstations",
262 NULL);
263 if (str != NULL) {
264 pdb_set_workstations(sam, str, PDB_SET);
267 blob = ldb_msg_find_ldb_val(msg, "userParameters");
268 if (blob != NULL) {
269 str = base64_encode_data_blob(frame, *blob);
270 if (str == NULL) {
271 DEBUG(0, ("base64_encode_data_blob() failed\n"));
272 goto fail;
274 pdb_set_munged_dial(sam, str, PDB_SET);
277 sid = samdb_result_dom_sid(talloc_tos(), msg, "objectSid");
278 if (!sid) {
279 DEBUG(10, ("Could not pull SID\n"));
280 goto fail;
282 pdb_set_user_sid(sam, sid, PDB_SET);
284 n = samdb_result_acct_flags(msg, "msDS-User-Account-Control-Computed");
285 if (n == 0) {
286 DEBUG(10, ("Could not pull userAccountControl\n"));
287 goto fail;
289 pdb_set_acct_ctrl(sam, n, PDB_SET);
291 blob = ldb_msg_find_ldb_val(msg, "unicodePwd");
292 if (blob) {
293 if (blob->length != NT_HASH_LEN) {
294 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
295 (int)blob->length, NT_HASH_LEN));
296 goto fail;
298 pdb_set_nt_passwd(sam, blob->data, PDB_SET);
301 blob = ldb_msg_find_ldb_val(msg, "dBCSPwd");
302 if (blob) {
303 if (blob->length != LM_HASH_LEN) {
304 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
305 (int)blob->length, LM_HASH_LEN));
306 goto fail;
308 pdb_set_lanman_passwd(sam, blob->data, PDB_SET);
311 n = ldb_msg_find_attr_as_uint(msg, "primaryGroupID", 0);
312 if (n == 0) {
313 DEBUG(10, ("Could not pull primaryGroupID\n"));
314 goto fail;
316 sid_compose(&group_sid, samdb_domain_sid(state->ldb), n);
317 pdb_set_group_sid(sam, &group_sid, PDB_SET);
319 status = NT_STATUS_OK;
320 fail:
321 TALLOC_FREE(frame);
322 return status;
325 static bool pdb_samba_dsdb_add_time(struct ldb_message *msg,
326 const char *attrib, time_t t)
328 uint64_t nt_time;
330 unix_to_nt_time(&nt_time, t);
332 return ldb_msg_add_fmt(msg, attrib, "%llu", (unsigned long long) nt_time);
335 static int pdb_samba_dsdb_replace_by_sam(struct pdb_samba_dsdb_state *state,
336 bool (*need_update)(const struct samu *,
337 enum pdb_elements),
338 struct ldb_dn *dn,
339 struct samu *sam)
341 TALLOC_CTX *frame = talloc_stackframe();
342 int ret = LDB_SUCCESS;
343 const char *pw;
344 struct ldb_message *msg;
345 struct ldb_request *req;
346 uint32_t dsdb_flags = 0;
347 /* TODO: All fields :-) */
349 msg = ldb_msg_new(frame);
350 if (!msg) {
351 talloc_free(frame);
352 return false;
355 msg->dn = dn;
357 /* build modify request */
358 ret = ldb_build_mod_req(&req, state->ldb, frame, msg, NULL, NULL,
359 ldb_op_default_callback,
360 NULL);
361 if (ret != LDB_SUCCESS) {
362 talloc_free(frame);
363 return ret;
366 /* If we set a plaintext password, the system will
367 * force the pwdLastSet to now() */
368 if (need_update(sam, PDB_PASSLASTSET)) {
369 dsdb_flags |= DSDB_PASSWORD_BYPASS_LAST_SET;
371 ret |= pdb_samba_dsdb_add_time(msg, "pwdLastSet",
372 pdb_get_pass_last_set_time(sam));
375 pw = pdb_get_plaintext_passwd(sam);
376 if (need_update(sam, PDB_PLAINTEXT_PW)) {
377 struct ldb_val pw_utf16;
378 if (pw == NULL) {
379 talloc_free(frame);
380 return LDB_ERR_OPERATIONS_ERROR;
383 if (!convert_string_talloc(msg,
384 CH_UNIX, CH_UTF16,
385 pw, strlen(pw),
386 (void *)&pw_utf16.data,
387 &pw_utf16.length)) {
388 talloc_free(frame);
389 return LDB_ERR_OPERATIONS_ERROR;
391 ret |= ldb_msg_add_value(msg, "clearTextPassword", &pw_utf16, NULL);
392 } else {
393 bool changed_lm_pw = false;
394 bool changed_nt_pw = false;
395 bool changed_history = false;
396 if (need_update(sam, PDB_LMPASSWD)) {
397 struct ldb_val val;
398 val.data = discard_const_p(uint8_t, pdb_get_lanman_passwd(sam));
399 if (!val.data) {
400 samdb_msg_add_delete(state->ldb, msg, msg,
401 "dBCSPwd");
402 } else {
403 val.length = LM_HASH_LEN;
404 ret |= ldb_msg_add_value(msg, "dBCSPwd", &val, NULL);
406 changed_lm_pw = true;
408 if (need_update(sam, PDB_NTPASSWD)) {
409 struct ldb_val val;
410 val.data = discard_const_p(uint8_t, pdb_get_nt_passwd(sam));
411 if (!val.data) {
412 samdb_msg_add_delete(state->ldb, msg, msg,
413 "unicodePwd");
414 } else {
415 val.length = NT_HASH_LEN;
416 ret |= ldb_msg_add_value(msg, "unicodePwd", &val, NULL);
418 changed_nt_pw = true;
421 /* Try to ensure we don't get out of sync */
422 if (changed_lm_pw && !changed_nt_pw) {
423 samdb_msg_add_delete(state->ldb, msg, msg,
424 "unicodePwd");
425 } else if (changed_nt_pw && !changed_lm_pw) {
426 samdb_msg_add_delete(state->ldb, msg, msg,
427 "dBCSPwd");
429 if (changed_lm_pw || changed_nt_pw) {
430 samdb_msg_add_delete(state->ldb, msg, msg,
431 "supplementalCredentials");
435 if (need_update(sam, PDB_PWHISTORY)) {
436 uint32_t current_hist_len;
437 const uint8_t *history = pdb_get_pw_history(sam, &current_hist_len);
439 bool invalid_history = false;
440 struct samr_Password *history_hashes = talloc_array(talloc_tos(), struct samr_Password,
441 current_hist_len);
442 if (!history) {
443 invalid_history = true;
444 } else {
445 unsigned int i;
446 static const uint8_t zeros[16];
447 /* Parse the history into the correct format */
448 for (i = 0; i < current_hist_len; i++) {
449 if (memcmp(&history[i*PW_HISTORY_ENTRY_LEN], zeros, 16) != 0) {
450 /* If the history is in the old format, with a salted hash, then we can't migrate it to AD format */
451 invalid_history = true;
452 break;
454 /* Copy out the 2nd 16 bytes of the 32 byte password history, containing the NT hash */
455 memcpy(history_hashes[i].hash,
456 &history[(i*PW_HISTORY_ENTRY_LEN) + PW_HISTORY_SALT_LEN],
457 sizeof(history_hashes[i].hash));
460 if (invalid_history) {
461 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
462 "ntPwdHistory");
464 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
465 "lmPwdHistory");
466 } else {
467 ret |= samdb_msg_add_hashes(state->ldb, msg, msg,
468 "ntPwdHistory",
469 history_hashes,
470 current_hist_len);
472 changed_history = true;
474 if (changed_lm_pw || changed_nt_pw || changed_history) {
475 /* These attributes can only be modified directly by using a special control */
476 dsdb_flags |= DSDB_BYPASS_PASSWORD_HASH;
480 /* PDB_USERSID is only allowed on ADD, handled in caller */
481 if (need_update(sam, PDB_GROUPSID)) {
482 const struct dom_sid *sid = pdb_get_group_sid(sam);
483 uint32_t rid;
484 NTSTATUS status = dom_sid_split_rid(NULL, sid, NULL, &rid);
485 if (!NT_STATUS_IS_OK(status)) {
486 talloc_free(frame);
487 return LDB_ERR_OPERATIONS_ERROR;
489 if (!dom_sid_in_domain(samdb_domain_sid(state->ldb), sid)) {
490 talloc_free(frame);
491 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
493 ret |= samdb_msg_add_uint(state->ldb, msg, msg, "primaryGroupID", rid);
495 if (need_update(sam, PDB_FULLNAME)) {
496 ret |= ldb_msg_add_string(msg, "displayName", pdb_get_fullname(sam));
499 if (need_update(sam, PDB_SMBHOME)) {
500 ret |= ldb_msg_add_string(msg, "homeDirectory",
501 pdb_get_homedir(sam));
504 if (need_update(sam, PDB_PROFILE)) {
505 ret |= ldb_msg_add_string(msg, "profilePath",
506 pdb_get_profile_path(sam));
509 if (need_update(sam, PDB_DRIVE)) {
510 ret |= ldb_msg_add_string(msg, "homeDrive",
511 pdb_get_dir_drive(sam));
514 if (need_update(sam, PDB_LOGONSCRIPT)) {
515 ret |= ldb_msg_add_string(msg, "scriptPath",
516 pdb_get_logon_script(sam));
519 if (need_update(sam, PDB_KICKOFFTIME)) {
520 ret |= pdb_samba_dsdb_add_time(msg, "accountExpires",
521 pdb_get_kickoff_time(sam));
524 if (need_update(sam, PDB_LOGONTIME)) {
525 ret |= pdb_samba_dsdb_add_time(msg, "lastLogon",
526 pdb_get_logon_time(sam));
529 if (need_update(sam, PDB_LOGOFFTIME)) {
530 ret |= pdb_samba_dsdb_add_time(msg, "lastLogoff",
531 pdb_get_logoff_time(sam));
534 if (need_update(sam, PDB_USERNAME)) {
535 ret |= ldb_msg_add_string(msg, "samAccountName",
536 pdb_get_username(sam));
539 if (need_update(sam, PDB_HOURSLEN) || need_update(sam, PDB_HOURS)) {
540 struct ldb_val hours = data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam));
541 ret |= ldb_msg_add_value(msg, "logonHours",
542 &hours, NULL);
545 if (need_update(sam, PDB_ACCTCTRL)) {
546 ret |= samdb_msg_add_acct_flags(state->ldb, msg, msg,
547 "userAccountControl", pdb_get_acct_ctrl(sam));
550 if (need_update(sam, PDB_COMMENT)) {
551 ret |= ldb_msg_add_string(msg, "comment",
552 pdb_get_comment(sam));
555 if (need_update(sam, PDB_ACCTDESC)) {
556 ret |= ldb_msg_add_string(msg, "description",
557 pdb_get_acct_desc(sam));
560 if (need_update(sam, PDB_WORKSTATIONS)) {
561 ret |= ldb_msg_add_string(msg, "userWorkstations",
562 pdb_get_workstations(sam));
565 /* This will need work, it is actually a UTF8 'string' with internal NULLs, to handle TS parameters */
566 if (need_update(sam, PDB_MUNGEDDIAL)) {
567 const char *base64_munged_dial = NULL;
569 base64_munged_dial = pdb_get_munged_dial(sam);
570 if (base64_munged_dial != NULL && strlen(base64_munged_dial) > 0) {
571 struct ldb_val blob;
573 blob = base64_decode_data_blob_talloc(msg,
574 base64_munged_dial);
575 if (blob.data == NULL) {
576 DEBUG(0, ("Failed to decode userParameters from "
577 "munged dialback string[%s] for %s\n",
578 base64_munged_dial,
579 ldb_dn_get_linearized(msg->dn)));
580 talloc_free(frame);
581 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
583 ret |= ldb_msg_add_steal_value(msg, "userParameters",
584 &blob);
588 if (need_update(sam, PDB_COUNTRY_CODE)) {
589 ret |= ldb_msg_add_fmt(msg, "countryCode",
590 "%i", (int)pdb_get_country_code(sam));
593 if (need_update(sam, PDB_CODE_PAGE)) {
594 ret |= ldb_msg_add_fmt(msg, "codePage",
595 "%i", (int)pdb_get_code_page(sam));
598 /* Not yet handled here or not meaningful for modifies on a Samba_Dsdb backend:
599 PDB_BAD_PASSWORD_TIME,
600 PDB_CANCHANGETIME, - these are calculated per policy, not stored
601 PDB_DOMAIN,
602 PDB_NTUSERNAME, - this makes no sense, and never really did
603 PDB_LOGONDIVS,
604 PDB_USERSID, - Handled in pdb_samba_dsdb_add_sam_account()
605 PDB_FIELDS_PRESENT,
606 PDB_BAD_PASSWORD_COUNT,
607 PDB_LOGON_COUNT,
608 PDB_UNKNOWN6,
609 PDB_BACKEND_PRIVATE_DATA,
612 if (ret != LDB_SUCCESS) {
613 talloc_free(frame);
614 return LDB_ERR_OPERATIONS_ERROR;
617 if (msg->num_elements == 0) {
618 talloc_free(frame);
619 /* Nothing to do, just return success */
620 return LDB_SUCCESS;
623 ret = dsdb_replace(state->ldb, msg, dsdb_flags);
625 if (ret != LDB_SUCCESS) {
626 DEBUG(0,("Failed to modify account record %s to set user attributes: %s\n",
627 ldb_dn_get_linearized(msg->dn),
628 ldb_errstring(state->ldb)));
631 talloc_free(frame);
632 return ret;
635 static NTSTATUS pdb_samba_dsdb_getsamupriv(struct pdb_samba_dsdb_state *state,
636 const char *filter,
637 TALLOC_CTX *mem_ctx,
638 struct ldb_message **msg)
640 const char * attrs[] = {
641 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
642 "sAMAccountName", "displayName", "homeDirectory",
643 "homeDrive", "scriptPath", "profilePath", "description",
644 "userWorkstations", "comment", "userParameters", "objectSid",
645 "primaryGroupID", "userAccountControl",
646 "msDS-User-Account-Control-Computed", "logonHours",
647 "badPwdCount", "logonCount", "countryCode", "codePage",
648 "unicodePwd", "dBCSPwd", NULL };
650 int rc = dsdb_search_one(state->ldb, mem_ctx, msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", filter);
651 if (rc != LDB_SUCCESS) {
652 DEBUG(10, ("ldap_search failed %s\n",
653 ldb_errstring(state->ldb)));
654 return NT_STATUS_LDAP(rc);
657 return NT_STATUS_OK;
660 static NTSTATUS pdb_samba_dsdb_getsampwfilter(struct pdb_methods *m,
661 struct pdb_samba_dsdb_state *state,
662 struct samu *sam_acct,
663 const char *exp_fmt, ...)
664 PRINTF_ATTRIBUTE(4,5);
666 static NTSTATUS pdb_samba_dsdb_getsampwfilter(struct pdb_methods *m,
667 struct pdb_samba_dsdb_state *state,
668 struct samu *sam_acct,
669 const char *exp_fmt, ...)
671 struct ldb_message *priv;
672 NTSTATUS status;
673 va_list ap;
674 char *expression = NULL;
675 TALLOC_CTX *tmp_ctx = talloc_new(state);
676 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
678 va_start(ap, exp_fmt);
679 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
680 va_end(ap);
682 if (!expression) {
683 talloc_free(tmp_ctx);
684 return NT_STATUS_NO_MEMORY;
687 status = pdb_samba_dsdb_getsamupriv(state, expression, sam_acct, &priv);
688 talloc_free(tmp_ctx);
689 if (!NT_STATUS_IS_OK(status)) {
690 DEBUG(10, ("pdb_samba_dsdb_getsamupriv failed: %s\n",
691 nt_errstr(status)));
692 return status;
695 status = pdb_samba_dsdb_init_sam_from_priv(m, sam_acct, priv);
696 if (!NT_STATUS_IS_OK(status)) {
697 DEBUG(10, ("pdb_samba_dsdb_init_sam_from_priv failed: %s\n",
698 nt_errstr(status)));
699 TALLOC_FREE(priv);
700 return status;
703 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
704 return NT_STATUS_OK;
707 static NTSTATUS pdb_samba_dsdb_getsampwnam(struct pdb_methods *m,
708 struct samu *sam_acct,
709 const char *username)
711 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
712 m->private_data, struct pdb_samba_dsdb_state);
714 return pdb_samba_dsdb_getsampwfilter(m, state, sam_acct,
715 "(&(samaccountname=%s)(objectclass=user))",
716 username);
719 static NTSTATUS pdb_samba_dsdb_getsampwsid(struct pdb_methods *m,
720 struct samu *sam_acct,
721 const struct dom_sid *sid)
723 NTSTATUS status;
724 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
725 m->private_data, struct pdb_samba_dsdb_state);
726 char *sidstr;
728 sidstr = dom_sid_string(talloc_tos(), sid);
729 NT_STATUS_HAVE_NO_MEMORY(sidstr);
731 status = pdb_samba_dsdb_getsampwfilter(m, state, sam_acct,
732 "(&(objectsid=%s)(objectclass=user))",
733 sidstr);
734 talloc_free(sidstr);
735 return status;
738 static NTSTATUS pdb_samba_dsdb_create_user(struct pdb_methods *m,
739 TALLOC_CTX *mem_ctx,
740 const char *name, uint32_t acct_flags,
741 uint32_t *rid)
743 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
744 m->private_data, struct pdb_samba_dsdb_state);
745 struct dom_sid *sid;
746 struct ldb_dn *dn;
747 NTSTATUS status;
748 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
749 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
751 /* Internally this uses transactions to ensure all the steps
752 * happen or fail as one */
753 status = dsdb_add_user(state->ldb, tmp_ctx, name, acct_flags, NULL,
754 &sid, &dn);
755 if (!NT_STATUS_IS_OK(status)) {
756 talloc_free(tmp_ctx);
757 return status;
759 sid_peek_rid(sid, rid);
760 talloc_free(tmp_ctx);
761 return NT_STATUS_OK;
764 static NTSTATUS pdb_samba_dsdb_delete_user(struct pdb_methods *m,
765 TALLOC_CTX *mem_ctx,
766 struct samu *sam)
768 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
769 m->private_data, struct pdb_samba_dsdb_state);
770 struct ldb_dn *dn;
771 int rc;
772 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
773 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
775 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, pdb_get_user_sid(sam)));
776 if (!dn || !ldb_dn_validate(dn)) {
777 talloc_free(tmp_ctx);
778 return NT_STATUS_NO_MEMORY;
780 rc = ldb_delete(state->ldb, dn);
782 if (rc != LDB_SUCCESS) {
783 DEBUG(10, ("ldb_delete for %s failed: %s\n", ldb_dn_get_linearized(dn),
784 ldb_errstring(state->ldb)));
785 talloc_free(tmp_ctx);
786 return NT_STATUS_LDAP(rc);
788 talloc_free(tmp_ctx);
789 return NT_STATUS_OK;
792 /* This interface takes a fully populated struct samu and places it in
793 * the database. This is not implemented at this time as we need to
794 * be careful around the creation of arbitary SIDs (ie, we must ensrue
795 * they are not left in a RID pool */
796 static NTSTATUS pdb_samba_dsdb_add_sam_account(struct pdb_methods *m,
797 struct samu *sampass)
799 int ret;
800 NTSTATUS status;
801 struct ldb_dn *dn;
802 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
803 m->private_data, struct pdb_samba_dsdb_state);
804 uint32_t acb_flags = pdb_get_acct_ctrl(sampass);
805 const char *username = pdb_get_username(sampass);
806 const struct dom_sid *user_sid = pdb_get_user_sid(sampass);
807 TALLOC_CTX *tframe = talloc_stackframe();
809 acb_flags &= (ACB_NORMAL|ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST);
811 ret = ldb_transaction_start(state->ldb);
812 if (ret != LDB_SUCCESS) {
813 talloc_free(tframe);
814 return NT_STATUS_LOCK_NOT_GRANTED;
817 status = dsdb_add_user(state->ldb, talloc_tos(), username,
818 acb_flags, user_sid, NULL, &dn);
819 if (!NT_STATUS_IS_OK(status)) {
820 ldb_transaction_cancel(state->ldb);
821 talloc_free(tframe);
822 return status;
825 ret = pdb_samba_dsdb_replace_by_sam(state, pdb_element_is_set_or_changed,
826 dn, sampass);
827 if (ret != LDB_SUCCESS) {
828 ldb_transaction_cancel(state->ldb);
829 talloc_free(tframe);
830 return dsdb_ldb_err_to_ntstatus(ret);
833 ret = ldb_transaction_commit(state->ldb);
834 if (ret != LDB_SUCCESS) {
835 DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
836 ldb_dn_get_linearized(dn),
837 ldb_errstring(state->ldb)));
838 talloc_free(tframe);
839 return NT_STATUS_INTERNAL_DB_CORRUPTION;
841 talloc_free(tframe);
842 return NT_STATUS_OK;
846 * Update the Samba_Dsdb LDB with the changes from a struct samu.
848 * This takes care not to update elements that have not been changed
849 * by the caller
851 static NTSTATUS pdb_samba_dsdb_update_sam_account(struct pdb_methods *m,
852 struct samu *sam)
854 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
855 m->private_data, struct pdb_samba_dsdb_state);
856 struct ldb_message *msg = pdb_samba_dsdb_get_samu_private(
857 m, sam);
858 int ret;
860 ret = pdb_samba_dsdb_replace_by_sam(state, pdb_element_is_changed, msg->dn,
861 sam);
862 return dsdb_ldb_err_to_ntstatus(ret);
865 static NTSTATUS pdb_samba_dsdb_delete_sam_account(struct pdb_methods *m,
866 struct samu *username)
868 NTSTATUS status;
869 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
870 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
871 status = pdb_samba_dsdb_delete_user(m, tmp_ctx, username);
872 talloc_free(tmp_ctx);
873 return status;
876 static NTSTATUS pdb_samba_dsdb_rename_sam_account(struct pdb_methods *m,
877 struct samu *oldname,
878 const char *newname)
880 return NT_STATUS_NOT_IMPLEMENTED;
883 /* This is not implemented, as this module is exptected to be used
884 * with auth_samba_dsdb, and this is responible for login counters etc
887 static NTSTATUS pdb_samba_dsdb_update_login_attempts(struct pdb_methods *m,
888 struct samu *sam_acct,
889 bool success)
891 return NT_STATUS_NOT_IMPLEMENTED;
894 static NTSTATUS pdb_samba_dsdb_getgrfilter(struct pdb_methods *m,
895 GROUP_MAP *map,
896 const char *exp_fmt, ...)
897 PRINTF_ATTRIBUTE(3,4);
899 static NTSTATUS pdb_samba_dsdb_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
900 const char *exp_fmt, ...)
902 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
903 m->private_data, struct pdb_samba_dsdb_state);
904 const char *attrs[] = { "objectClass", "objectSid", "description", "samAccountName", "groupType",
905 NULL };
906 struct ldb_message *msg;
907 va_list ap;
908 char *expression = NULL;
909 struct dom_sid *sid;
910 const char *str;
911 int rc;
912 struct id_map id_map;
913 struct id_map *id_maps[2];
914 TALLOC_CTX *tmp_ctx = talloc_stackframe();
915 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
917 va_start(ap, exp_fmt);
918 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
919 va_end(ap);
921 if (!expression) {
922 talloc_free(tmp_ctx);
923 return NT_STATUS_NO_MEMORY;
926 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
927 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
928 talloc_free(tmp_ctx);
929 return NT_STATUS_NO_SUCH_GROUP;
930 } else if (rc != LDB_SUCCESS) {
931 talloc_free(tmp_ctx);
932 DEBUG(10, ("dsdb_search_one failed %s\n",
933 ldb_errstring(state->ldb)));
934 return NT_STATUS_LDAP(rc);
937 sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
938 if (!sid) {
939 talloc_free(tmp_ctx);
940 DEBUG(10, ("Could not pull SID\n"));
941 return NT_STATUS_INTERNAL_DB_CORRUPTION;
944 map->sid = *sid;
946 if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
947 NTSTATUS status;
948 uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
949 switch (grouptype) {
950 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
951 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
952 map->sid_name_use = SID_NAME_ALIAS;
953 break;
954 case GTYPE_SECURITY_GLOBAL_GROUP:
955 map->sid_name_use = SID_NAME_DOM_GRP;
956 break;
957 default:
958 talloc_free(tmp_ctx);
959 DEBUG(10, ("Could not pull groupType\n"));
960 return NT_STATUS_INTERNAL_DB_CORRUPTION;
963 ZERO_STRUCT(id_map);
964 id_map.sid = sid;
965 id_maps[0] = &id_map;
966 id_maps[1] = NULL;
968 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
970 if (!NT_STATUS_IS_OK(status)) {
971 talloc_free(tmp_ctx);
972 return status;
974 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
975 map->gid = id_map.xid.id;
976 } else {
977 DEBUG(1, (__location__ "Did not get GUID when mapping SID for %s", expression));
978 talloc_free(tmp_ctx);
979 return NT_STATUS_INTERNAL_DB_CORRUPTION;
981 } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
982 DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
983 talloc_free(tmp_ctx);
984 return NT_STATUS_INTERNAL_DB_CORRUPTION;
987 str = ldb_msg_find_attr_as_string(msg, "samAccountName",
988 NULL);
989 if (str == NULL) {
990 talloc_free(tmp_ctx);
991 return NT_STATUS_INTERNAL_DB_CORRUPTION;
993 map->nt_name = talloc_strdup(map, str);
994 if (!map->nt_name) {
995 talloc_free(tmp_ctx);
996 return NT_STATUS_NO_MEMORY;
999 str = ldb_msg_find_attr_as_string(msg, "description",
1000 NULL);
1001 if (str != NULL) {
1002 map->comment = talloc_strdup(map, str);
1003 } else {
1004 map->comment = talloc_strdup(map, "");
1006 if (!map->comment) {
1007 talloc_free(tmp_ctx);
1008 return NT_STATUS_NO_MEMORY;
1011 talloc_free(tmp_ctx);
1012 return NT_STATUS_OK;
1015 static NTSTATUS pdb_samba_dsdb_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
1016 struct dom_sid sid)
1018 char *filter;
1019 NTSTATUS status;
1021 filter = talloc_asprintf(talloc_tos(),
1022 "(&(objectsid=%s)(objectclass=group))",
1023 sid_string_talloc(talloc_tos(), &sid));
1024 if (filter == NULL) {
1025 return NT_STATUS_NO_MEMORY;
1028 status = pdb_samba_dsdb_getgrfilter(m, map, "%s", filter);
1029 TALLOC_FREE(filter);
1030 return status;
1033 static NTSTATUS pdb_samba_dsdb_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
1034 gid_t gid)
1036 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1037 m->private_data, struct pdb_samba_dsdb_state);
1038 NTSTATUS status;
1039 struct id_map id_map;
1040 struct id_map *id_maps[2];
1041 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1042 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1044 id_map.xid.id = gid;
1045 id_map.xid.type = ID_TYPE_GID;
1046 id_maps[0] = &id_map;
1047 id_maps[1] = NULL;
1049 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1050 if (!NT_STATUS_IS_OK(status)) {
1051 talloc_free(tmp_ctx);
1052 return status;
1054 status = pdb_samba_dsdb_getgrsid(m, map, *id_map.sid);
1055 talloc_free(tmp_ctx);
1056 return status;
1059 static NTSTATUS pdb_samba_dsdb_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
1060 const char *name)
1062 char *filter;
1063 NTSTATUS status;
1065 filter = talloc_asprintf(talloc_tos(),
1066 "(&(samaccountname=%s)(objectclass=group))",
1067 name);
1068 if (filter == NULL) {
1069 return NT_STATUS_NO_MEMORY;
1072 status = pdb_samba_dsdb_getgrfilter(m, map, "%s", filter);
1073 TALLOC_FREE(filter);
1074 return status;
1077 static NTSTATUS pdb_samba_dsdb_create_dom_group(struct pdb_methods *m,
1078 TALLOC_CTX *mem_ctx, const char *name,
1079 uint32_t *rid)
1081 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1082 m->private_data, struct pdb_samba_dsdb_state);
1083 NTSTATUS status;
1084 struct dom_sid *sid;
1085 struct ldb_dn *dn;
1086 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1087 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1089 status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
1090 if (!NT_STATUS_IS_OK(status)) {
1091 talloc_free(tmp_ctx);
1092 return status;
1095 sid_peek_rid(sid, rid);
1096 talloc_free(tmp_ctx);
1097 return NT_STATUS_OK;
1100 static NTSTATUS pdb_samba_dsdb_delete_dom_group(struct pdb_methods *m,
1101 TALLOC_CTX *mem_ctx, uint32_t rid)
1103 const char *attrs[] = { NULL };
1104 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1105 m->private_data, struct pdb_samba_dsdb_state);
1106 struct dom_sid sid;
1107 struct ldb_message *msg;
1108 struct ldb_dn *dn;
1109 int rc;
1110 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1111 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1113 sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
1115 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1116 DEBUG(0, ("Unable to start transaction in pdb_samba_dsdb_delete_dom_group()\n"));
1117 return NT_STATUS_INTERNAL_ERROR;
1120 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
1121 if (!dn || !ldb_dn_validate(dn)) {
1122 talloc_free(tmp_ctx);
1123 ldb_transaction_cancel(state->ldb);
1124 return NT_STATUS_NO_MEMORY;
1126 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
1127 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1128 talloc_free(tmp_ctx);
1129 ldb_transaction_cancel(state->ldb);
1130 return NT_STATUS_NO_SUCH_GROUP;
1132 rc = ldb_delete(state->ldb, dn);
1133 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1134 talloc_free(tmp_ctx);
1135 ldb_transaction_cancel(state->ldb);
1136 return NT_STATUS_NO_SUCH_GROUP;
1137 } else if (rc != LDB_SUCCESS) {
1138 DEBUG(10, ("ldb_delete failed %s\n",
1139 ldb_errstring(state->ldb)));
1140 ldb_transaction_cancel(state->ldb);
1141 return NT_STATUS_LDAP(rc);
1144 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1145 DEBUG(0, ("Unable to commit transaction in pdb_samba_dsdb_delete_dom_group()\n"));
1146 return NT_STATUS_INTERNAL_ERROR;
1148 return NT_STATUS_OK;
1151 static NTSTATUS pdb_samba_dsdb_add_group_mapping_entry(struct pdb_methods *m,
1152 GROUP_MAP *map)
1154 return NT_STATUS_NOT_IMPLEMENTED;
1157 static NTSTATUS pdb_samba_dsdb_update_group_mapping_entry(struct pdb_methods *m,
1158 GROUP_MAP *map)
1160 return NT_STATUS_NOT_IMPLEMENTED;
1163 static NTSTATUS pdb_samba_dsdb_delete_group_mapping_entry(struct pdb_methods *m,
1164 struct dom_sid sid)
1166 return NT_STATUS_NOT_IMPLEMENTED;
1169 static NTSTATUS pdb_samba_dsdb_enum_group_mapping(struct pdb_methods *m,
1170 const struct dom_sid *sid,
1171 enum lsa_SidType sid_name_use,
1172 GROUP_MAP ***pp_rmap,
1173 size_t *p_num_entries,
1174 bool unix_only)
1176 return NT_STATUS_NOT_IMPLEMENTED;
1179 static NTSTATUS pdb_samba_dsdb_enum_group_members(struct pdb_methods *m,
1180 TALLOC_CTX *mem_ctx,
1181 const struct dom_sid *group,
1182 uint32_t **pmembers,
1183 size_t *pnum_members)
1185 unsigned int i, num_sids, num_members;
1186 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1187 m->private_data, struct pdb_samba_dsdb_state);
1188 struct dom_sid *members_as_sids;
1189 struct dom_sid *dom_sid;
1190 uint32_t *members;
1191 struct ldb_dn *dn;
1192 NTSTATUS status;
1194 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1195 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1197 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
1198 if (!dn || !ldb_dn_validate(dn)) {
1199 return NT_STATUS_NO_MEMORY;
1202 status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
1203 if (!NT_STATUS_IS_OK(status)) {
1204 talloc_free(tmp_ctx);
1205 return status;
1207 status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
1208 if (!NT_STATUS_IS_OK(status)) {
1209 talloc_free(tmp_ctx);
1210 return status;
1213 *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
1214 if (*pmembers == NULL) {
1215 TALLOC_FREE(tmp_ctx);
1216 return NT_STATUS_NO_MEMORY;
1218 num_members = 0;
1220 for (i = 0; i < num_sids; i++) {
1221 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
1222 continue;
1224 status = dom_sid_split_rid(NULL, &members_as_sids[i],
1225 NULL, &members[num_members]);
1226 if (!NT_STATUS_IS_OK(status)) {
1227 talloc_free(tmp_ctx);
1228 return status;
1230 num_members++;
1232 *pnum_members = num_members;
1233 return NT_STATUS_OK;
1236 /* Just convert the primary group SID into a group */
1237 static NTSTATUS fake_enum_group_memberships(struct pdb_samba_dsdb_state *state,
1238 TALLOC_CTX *mem_ctx,
1239 struct samu *user,
1240 struct dom_sid **pp_sids,
1241 gid_t **pp_gids,
1242 uint32_t *p_num_groups)
1244 NTSTATUS status;
1245 size_t num_groups = 0;
1246 struct dom_sid *group_sids = NULL;
1247 gid_t *gids = NULL;
1248 TALLOC_CTX *tmp_ctx;
1250 tmp_ctx = talloc_new(mem_ctx);
1251 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1253 if (user->group_sid) {
1254 struct id_map *id_maps[2];
1255 struct id_map id_map;
1257 num_groups = 1;
1259 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1260 if (group_sids == NULL) {
1261 talloc_free(tmp_ctx);
1262 return NT_STATUS_NO_MEMORY;
1264 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1265 if (gids == NULL) {
1266 talloc_free(tmp_ctx);
1267 return NT_STATUS_NO_MEMORY;
1270 group_sids[0] = *user->group_sid;
1272 ZERO_STRUCT(id_map);
1273 id_map.sid = &group_sids[0];
1274 id_maps[0] = &id_map;
1275 id_maps[1] = NULL;
1277 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1278 if (!NT_STATUS_IS_OK(status)) {
1279 talloc_free(tmp_ctx);
1280 return status;
1282 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1283 gids[0] = id_map.xid.id;
1284 } else {
1285 DEBUG(1, (__location__
1286 "Group %s, of which %s is a member, could not be converted to a GID\n",
1287 dom_sid_string(tmp_ctx, &group_sids[0]),
1288 dom_sid_string(tmp_ctx, &user->user_sid)));
1289 talloc_free(tmp_ctx);
1290 /* We must error out, otherwise a user might
1291 * avoid a DENY acl based on a group they
1292 * missed out on */
1293 return NT_STATUS_NO_SUCH_GROUP;
1297 *pp_sids = talloc_steal(mem_ctx, group_sids);
1298 *pp_gids = talloc_steal(mem_ctx, gids);
1299 *p_num_groups = num_groups;
1300 talloc_free(tmp_ctx);
1301 return NT_STATUS_OK;
1304 static NTSTATUS pdb_samba_dsdb_enum_group_memberships(struct pdb_methods *m,
1305 TALLOC_CTX *mem_ctx,
1306 struct samu *user,
1307 struct dom_sid **pp_sids,
1308 gid_t **pp_gids,
1309 uint32_t *p_num_groups)
1311 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1312 m->private_data, struct pdb_samba_dsdb_state);
1313 struct ldb_message *msg = pdb_samba_dsdb_get_samu_private(
1314 m, user);
1315 const char *attrs[] = { "tokenGroups", NULL};
1316 struct ldb_message *tokengroups_msg;
1317 struct ldb_message_element *tokengroups;
1318 int i, rc;
1319 NTSTATUS status;
1320 unsigned int count = 0;
1321 size_t num_groups;
1322 struct dom_sid *group_sids;
1323 gid_t *gids;
1324 TALLOC_CTX *tmp_ctx;
1326 if (msg == NULL) {
1327 /* Fake up some things here */
1328 return fake_enum_group_memberships(state,
1329 mem_ctx,
1330 user, pp_sids,
1331 pp_gids, p_num_groups);
1334 tmp_ctx = talloc_new(mem_ctx);
1335 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1337 rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1339 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1340 talloc_free(tmp_ctx);
1341 return NT_STATUS_NO_SUCH_USER;
1342 } else if (rc != LDB_SUCCESS) {
1343 DEBUG(10, ("dsdb_search_one failed %s\n",
1344 ldb_errstring(state->ldb)));
1345 talloc_free(tmp_ctx);
1346 return NT_STATUS_LDAP(rc);
1349 tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1351 if (tokengroups) {
1352 count = tokengroups->num_values;
1355 group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1356 if (group_sids == NULL) {
1357 talloc_free(tmp_ctx);
1358 return NT_STATUS_NO_MEMORY;
1360 gids = talloc_array(tmp_ctx, gid_t, count);
1361 if (gids == NULL) {
1362 talloc_free(tmp_ctx);
1363 return NT_STATUS_NO_MEMORY;
1365 num_groups = 0;
1367 for (i=0; i<count; i++) {
1368 struct id_map *id_maps[2];
1369 struct id_map id_map;
1370 struct ldb_val *v = &tokengroups->values[i];
1371 enum ndr_err_code ndr_err
1372 = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1373 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1374 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1375 talloc_free(tmp_ctx);
1376 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1379 ZERO_STRUCT(id_map);
1380 id_map.sid = &group_sids[num_groups];
1381 id_maps[0] = &id_map;
1382 id_maps[1] = NULL;
1384 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1385 if (!NT_STATUS_IS_OK(status)) {
1386 talloc_free(tmp_ctx);
1387 return status;
1389 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1390 gids[num_groups] = id_map.xid.id;
1391 } else {
1392 DEBUG(1, (__location__
1393 "Group %s, of which %s is a member, could not be converted to a GID\n",
1394 dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1395 ldb_dn_get_linearized(msg->dn)));
1396 talloc_free(tmp_ctx);
1397 /* We must error out, otherwise a user might
1398 * avoid a DENY acl based on a group they
1399 * missed out on */
1400 return NT_STATUS_NO_SUCH_GROUP;
1403 num_groups += 1;
1404 if (num_groups == count) {
1405 break;
1409 *pp_sids = talloc_steal(mem_ctx, group_sids);
1410 *pp_gids = talloc_steal(mem_ctx, gids);
1411 *p_num_groups = num_groups;
1412 talloc_free(tmp_ctx);
1413 return NT_STATUS_OK;
1416 static NTSTATUS pdb_samba_dsdb_set_unix_primary_group(struct pdb_methods *m,
1417 TALLOC_CTX *mem_ctx,
1418 struct samu *user)
1420 return NT_STATUS_NOT_IMPLEMENTED;
1423 static NTSTATUS pdb_samba_dsdb_mod_groupmem_by_sid(struct pdb_methods *m,
1424 TALLOC_CTX *mem_ctx,
1425 const struct dom_sid *groupsid,
1426 const struct dom_sid *membersid,
1427 int mod_op)
1429 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1430 m->private_data, struct pdb_samba_dsdb_state);
1431 struct ldb_message *msg;
1432 int ret;
1433 struct ldb_message_element *el;
1434 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1435 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1436 msg = ldb_msg_new(tmp_ctx);
1437 if (msg == NULL) {
1438 TALLOC_FREE(tmp_ctx);
1439 return NT_STATUS_NO_MEMORY;
1442 msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1443 if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1444 talloc_free(tmp_ctx);
1445 return NT_STATUS_NO_MEMORY;
1447 ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1448 if (ret != LDB_SUCCESS) {
1449 talloc_free(tmp_ctx);
1450 return NT_STATUS_NO_MEMORY;
1452 el = ldb_msg_find_element(msg, "member");
1453 el->flags = mod_op;
1455 /* No need for transactions here, the ldb auto-transaction
1456 * code will handle things for the single operation */
1457 ret = ldb_modify(state->ldb, msg);
1458 talloc_free(tmp_ctx);
1459 if (ret != LDB_SUCCESS) {
1460 DEBUG(10, ("ldb_modify failed: %s\n",
1461 ldb_errstring(state->ldb)));
1462 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1463 return NT_STATUS_MEMBER_IN_GROUP;
1465 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1466 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1468 return NT_STATUS_LDAP(ret);
1471 return NT_STATUS_OK;
1474 static NTSTATUS pdb_samba_dsdb_mod_groupmem(struct pdb_methods *m,
1475 TALLOC_CTX *mem_ctx,
1476 uint32_t grouprid, uint32_t memberrid,
1477 int mod_op)
1479 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1480 m->private_data, struct pdb_samba_dsdb_state);
1481 const struct dom_sid *dom_sid, *groupsid, *membersid;
1482 NTSTATUS status;
1483 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1484 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1486 dom_sid = samdb_domain_sid(state->ldb);
1488 groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1489 if (groupsid == NULL) {
1490 TALLOC_FREE(tmp_ctx);
1491 return NT_STATUS_NO_MEMORY;
1493 membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1494 if (membersid == NULL) {
1495 TALLOC_FREE(tmp_ctx);
1496 return NT_STATUS_NO_MEMORY;
1498 status = pdb_samba_dsdb_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1499 talloc_free(tmp_ctx);
1500 return status;
1503 static NTSTATUS pdb_samba_dsdb_add_groupmem(struct pdb_methods *m,
1504 TALLOC_CTX *mem_ctx,
1505 uint32_t group_rid, uint32_t member_rid)
1507 return pdb_samba_dsdb_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1508 LDB_FLAG_MOD_ADD);
1511 static NTSTATUS pdb_samba_dsdb_del_groupmem(struct pdb_methods *m,
1512 TALLOC_CTX *mem_ctx,
1513 uint32_t group_rid, uint32_t member_rid)
1515 return pdb_samba_dsdb_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1516 LDB_FLAG_MOD_DELETE);
1519 static NTSTATUS pdb_samba_dsdb_create_alias(struct pdb_methods *m,
1520 const char *name, uint32_t *rid)
1522 TALLOC_CTX *frame = talloc_stackframe();
1523 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1524 m->private_data, struct pdb_samba_dsdb_state);
1525 struct dom_sid *sid;
1527 struct ldb_dn *dn;
1528 NTSTATUS status;
1530 /* Internally this uses transactions to ensure all the steps
1531 * happen or fail as one */
1532 status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1533 if (!NT_STATUS_IS_OK(status)) {
1534 TALLOC_FREE(frame);
1537 sid_peek_rid(sid, rid);
1538 TALLOC_FREE(frame);
1539 return NT_STATUS_OK;
1542 static NTSTATUS pdb_samba_dsdb_delete_alias(struct pdb_methods *m,
1543 const struct dom_sid *sid)
1545 const char *attrs[] = { NULL };
1546 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1547 m->private_data, struct pdb_samba_dsdb_state);
1548 struct ldb_message *msg;
1549 struct ldb_dn *dn;
1550 int rc;
1551 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1552 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1554 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1555 if (!dn || !ldb_dn_validate(dn)) {
1556 talloc_free(tmp_ctx);
1557 return NT_STATUS_NO_MEMORY;
1560 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1561 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1562 talloc_free(tmp_ctx);
1563 return NT_STATUS_INTERNAL_ERROR;
1566 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1567 "(|(grouptype=%d)(grouptype=%d)))",
1568 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1569 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1570 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1571 talloc_free(tmp_ctx);
1572 ldb_transaction_cancel(state->ldb);
1573 return NT_STATUS_NO_SUCH_ALIAS;
1575 rc = ldb_delete(state->ldb, dn);
1576 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1577 talloc_free(tmp_ctx);
1578 ldb_transaction_cancel(state->ldb);
1579 return NT_STATUS_NO_SUCH_ALIAS;
1580 } else if (rc != LDB_SUCCESS) {
1581 DEBUG(10, ("ldb_delete failed %s\n",
1582 ldb_errstring(state->ldb)));
1583 ldb_transaction_cancel(state->ldb);
1584 talloc_free(tmp_ctx);
1585 return NT_STATUS_LDAP(rc);
1588 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1589 DEBUG(0, ("Failed to commit transaction in pdb_samba_dsdb_delete_alias(): %s\n",
1590 ldb_errstring(state->ldb)));
1591 talloc_free(tmp_ctx);
1592 return NT_STATUS_INTERNAL_ERROR;
1595 talloc_free(tmp_ctx);
1596 return NT_STATUS_OK;
1599 #if 0
1600 static NTSTATUS pdb_samba_dsdb_set_aliasinfo(struct pdb_methods *m,
1601 const struct dom_sid *sid,
1602 struct acct_info *info)
1604 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1605 m->private_data, struct pdb_samba_dsdb_state);
1606 struct tldap_context *ld;
1607 const char *attrs[3] = { "objectSid", "description",
1608 "samAccountName" };
1609 struct ldb_message **msg;
1610 char *sidstr, *dn;
1611 int rc;
1612 struct tldap_mod *mods;
1613 int num_mods;
1614 bool ok;
1616 ld = pdb_samba_dsdb_ld(state);
1617 if (ld == NULL) {
1618 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1621 sidstr = sid_binstring(talloc_tos(), sid);
1622 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1624 rc = pdb_samba_dsdb_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1625 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1626 &msg, "(&(objectSid=%s)(objectclass=group)"
1627 "(|(grouptype=%d)(grouptype=%d)))",
1628 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1629 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1630 TALLOC_FREE(sidstr)
1631 if (rc != LDB_SUCCESS) {
1632 DEBUG(10, ("ldap_search failed %s\n",
1633 ldb_errstring(state->ldb)));
1634 return NT_STATUS_LDAP(rc);
1636 switch talloc_array_length(msg) {
1637 case 0:
1638 return NT_STATUS_NO_SUCH_ALIAS;
1639 case 1:
1640 break;
1641 default:
1642 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1645 if (!tldap_entry_dn(msg[0], &dn)) {
1646 TALLOC_FREE(msg);
1647 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1650 mods = NULL;
1651 num_mods = 0;
1652 ok = true;
1654 ok &= tldap_make_mod_fmt(
1655 msg[0], msg, &num_mods, &mods, "description",
1656 "%s", info->acct_desc);
1657 ok &= tldap_make_mod_fmt(
1658 msg[0], msg, &num_mods, &mods, "samAccountName",
1659 "%s", info->acct_name);
1660 if (!ok) {
1661 TALLOC_FREE(msg);
1662 return NT_STATUS_NO_MEMORY;
1664 if (num_mods == 0) {
1665 /* no change */
1666 TALLOC_FREE(msg);
1667 return NT_STATUS_OK;
1670 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1671 TALLOC_FREE(msg);
1672 if (rc != LDB_SUCCESS) {
1673 DEBUG(10, ("ldap_modify failed: %s\n",
1674 ldb_errstring(state->ldb)));
1675 return NT_STATUS_LDAP(rc);
1677 return NT_STATUS_OK;
1679 #endif
1680 static NTSTATUS pdb_samba_dsdb_add_aliasmem(struct pdb_methods *m,
1681 const struct dom_sid *alias,
1682 const struct dom_sid *member)
1684 NTSTATUS status;
1685 TALLOC_CTX *frame = talloc_stackframe();
1686 status = pdb_samba_dsdb_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1687 talloc_free(frame);
1688 return status;
1691 static NTSTATUS pdb_samba_dsdb_del_aliasmem(struct pdb_methods *m,
1692 const struct dom_sid *alias,
1693 const struct dom_sid *member)
1695 NTSTATUS status;
1696 TALLOC_CTX *frame = talloc_stackframe();
1697 status = pdb_samba_dsdb_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1698 talloc_free(frame);
1699 return status;
1702 static NTSTATUS pdb_samba_dsdb_enum_aliasmem(struct pdb_methods *m,
1703 const struct dom_sid *alias,
1704 TALLOC_CTX *mem_ctx,
1705 struct dom_sid **pmembers,
1706 size_t *pnum_members)
1708 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1709 m->private_data, struct pdb_samba_dsdb_state);
1710 struct ldb_dn *dn;
1711 unsigned int num_members;
1712 NTSTATUS status;
1713 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1714 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1716 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1717 if (!dn || !ldb_dn_validate(dn)) {
1718 return NT_STATUS_NO_MEMORY;
1721 status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1722 *pnum_members = num_members;
1723 if (NT_STATUS_IS_OK(status)) {
1724 talloc_steal(mem_ctx, pmembers);
1726 talloc_free(tmp_ctx);
1727 return status;
1730 static NTSTATUS pdb_samba_dsdb_enum_alias_memberships(struct pdb_methods *m,
1731 TALLOC_CTX *mem_ctx,
1732 const struct dom_sid *domain_sid,
1733 const struct dom_sid *members,
1734 size_t num_members,
1735 uint32_t **palias_rids,
1736 size_t *pnum_alias_rids)
1738 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1739 m->private_data, struct pdb_samba_dsdb_state);
1740 uint32_t *alias_rids = NULL;
1741 size_t num_alias_rids = 0;
1742 int i;
1743 struct dom_sid *groupSIDs = NULL;
1744 unsigned int num_groupSIDs = 0;
1745 char *filter;
1746 NTSTATUS status;
1747 const char *sid_string;
1748 const char *sid_dn;
1749 DATA_BLOB sid_blob;
1751 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1752 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1754 * TODO: Get the filter right so that we only get the aliases from
1755 * either the SAM or BUILTIN
1758 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1759 GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1760 if (filter == NULL) {
1761 return NT_STATUS_NO_MEMORY;
1764 for (i = 0; i < num_members; i++) {
1765 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1766 if (sid_string == NULL) {
1767 TALLOC_FREE(tmp_ctx);
1768 return NT_STATUS_NO_MEMORY;
1771 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1772 if (sid_dn == NULL) {
1773 TALLOC_FREE(tmp_ctx);
1774 return NT_STATUS_NO_MEMORY;
1777 sid_blob = data_blob_string_const(sid_dn);
1779 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1780 tmp_ctx, &groupSIDs, &num_groupSIDs);
1781 if (!NT_STATUS_IS_OK(status)) {
1782 talloc_free(tmp_ctx);
1783 return status;
1787 alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1788 if (alias_rids == NULL) {
1789 talloc_free(tmp_ctx);
1790 return NT_STATUS_NO_MEMORY;
1793 for (i=0; i<num_groupSIDs; i++) {
1794 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1795 &alias_rids[num_alias_rids])) {
1796 num_alias_rids++;;
1800 *palias_rids = alias_rids;
1801 *pnum_alias_rids = num_alias_rids;
1802 return NT_STATUS_OK;
1805 static NTSTATUS pdb_samba_dsdb_lookup_rids(struct pdb_methods *m,
1806 const struct dom_sid *domain_sid,
1807 int num_rids,
1808 uint32_t *rids,
1809 const char **names,
1810 enum lsa_SidType *lsa_attrs)
1812 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1813 m->private_data, struct pdb_samba_dsdb_state);
1814 NTSTATUS status;
1816 TALLOC_CTX *tmp_ctx;
1818 if (num_rids == 0) {
1819 return NT_STATUS_NONE_MAPPED;
1822 tmp_ctx = talloc_stackframe();
1823 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1825 status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1826 talloc_free(tmp_ctx);
1827 return status;
1830 static NTSTATUS pdb_samba_dsdb_lookup_names(struct pdb_methods *m,
1831 const struct dom_sid *domain_sid,
1832 int num_names,
1833 const char **pp_names,
1834 uint32_t *rids,
1835 enum lsa_SidType *attrs)
1837 return NT_STATUS_NOT_IMPLEMENTED;
1840 static NTSTATUS pdb_samba_dsdb_get_account_policy(struct pdb_methods *m,
1841 enum pdb_policy_type type,
1842 uint32_t *value)
1844 return account_policy_get(type, value)
1845 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1848 static NTSTATUS pdb_samba_dsdb_set_account_policy(struct pdb_methods *m,
1849 enum pdb_policy_type type,
1850 uint32_t value)
1852 return account_policy_set(type, value)
1853 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1856 static NTSTATUS pdb_samba_dsdb_get_seq_num(struct pdb_methods *m,
1857 time_t *seq_num_out)
1859 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1860 m->private_data, struct pdb_samba_dsdb_state);
1861 uint64_t seq_num;
1862 int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1863 if (ret == LDB_SUCCESS) {
1864 *seq_num_out = seq_num;
1865 return NT_STATUS_OK;
1866 } else {
1867 return NT_STATUS_UNSUCCESSFUL;
1871 struct pdb_samba_dsdb_search_state {
1872 uint32_t acct_flags;
1873 struct samr_displayentry *entries;
1874 uint32_t num_entries;
1875 ssize_t array_size;
1876 uint32_t current;
1879 static bool pdb_samba_dsdb_next_entry(struct pdb_search *search,
1880 struct samr_displayentry *entry)
1882 struct pdb_samba_dsdb_search_state *state = talloc_get_type_abort(
1883 search->private_data, struct pdb_samba_dsdb_search_state);
1885 if (state->current == state->num_entries) {
1886 return false;
1889 entry->idx = state->entries[state->current].idx;
1890 entry->rid = state->entries[state->current].rid;
1891 entry->acct_flags = state->entries[state->current].acct_flags;
1893 entry->account_name = talloc_strdup(
1894 search, state->entries[state->current].account_name);
1895 entry->fullname = talloc_strdup(
1896 search, state->entries[state->current].fullname);
1897 entry->description = talloc_strdup(
1898 search, state->entries[state->current].description);
1900 state->current += 1;
1901 return true;
1904 static void pdb_samba_dsdb_search_end(struct pdb_search *search)
1906 struct pdb_samba_dsdb_search_state *state = talloc_get_type_abort(
1907 search->private_data, struct pdb_samba_dsdb_search_state);
1908 talloc_free(state);
1911 static bool pdb_samba_dsdb_search_filter(struct pdb_methods *m,
1912 struct pdb_search *search,
1913 struct pdb_samba_dsdb_search_state **pstate,
1914 const char *exp_fmt, ...)
1915 PRINTF_ATTRIBUTE(4, 5);
1917 static bool pdb_samba_dsdb_search_filter(struct pdb_methods *m,
1918 struct pdb_search *search,
1919 struct pdb_samba_dsdb_search_state **pstate,
1920 const char *exp_fmt, ...)
1922 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1923 m->private_data, struct pdb_samba_dsdb_state);
1924 struct pdb_samba_dsdb_search_state *sstate;
1925 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1926 "userAccountControl", "description", NULL };
1927 struct ldb_result *res;
1928 int i, rc, num_users;
1930 va_list ap;
1931 char *expression = NULL;
1933 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1934 if (!tmp_ctx) {
1935 return false;
1938 va_start(ap, exp_fmt);
1939 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1940 va_end(ap);
1942 if (!expression) {
1943 talloc_free(tmp_ctx);
1944 return LDB_ERR_OPERATIONS_ERROR;
1947 sstate = talloc_zero(tmp_ctx, struct pdb_samba_dsdb_search_state);
1948 if (sstate == NULL) {
1949 talloc_free(tmp_ctx);
1950 return false;
1953 rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1954 if (rc != LDB_SUCCESS) {
1955 talloc_free(tmp_ctx);
1956 DEBUG(10, ("dsdb_search failed: %s\n",
1957 ldb_errstring(state->ldb)));
1958 return false;
1961 num_users = res->count;
1963 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1964 num_users);
1965 if (sstate->entries == NULL) {
1966 talloc_free(tmp_ctx);
1967 DEBUG(10, ("talloc failed\n"));
1968 return false;
1971 sstate->num_entries = 0;
1973 for (i=0; i<num_users; i++) {
1974 struct samr_displayentry *e;
1975 struct dom_sid *sid;
1977 e = &sstate->entries[sstate->num_entries];
1979 e->idx = sstate->num_entries;
1980 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1981 if (!sid) {
1982 talloc_free(tmp_ctx);
1983 DEBUG(10, ("Could not pull SID\n"));
1984 return false;
1986 sid_peek_rid(sid, &e->rid);
1988 e->acct_flags = samdb_result_acct_flags(res->msgs[i], "userAccountControl");
1989 e->account_name = ldb_msg_find_attr_as_string(
1990 res->msgs[i], "samAccountName", NULL);
1991 if (e->account_name == NULL) {
1992 talloc_free(tmp_ctx);
1993 return false;
1995 e->fullname = ldb_msg_find_attr_as_string(
1996 res->msgs[i], "displayName", "");
1997 e->description = ldb_msg_find_attr_as_string(
1998 res->msgs[i], "description", "");
2000 sstate->num_entries += 1;
2001 if (sstate->num_entries >= num_users) {
2002 break;
2005 talloc_steal(sstate->entries, res->msgs);
2006 search->private_data = talloc_steal(search, sstate);
2007 search->next_entry = pdb_samba_dsdb_next_entry;
2008 search->search_end = pdb_samba_dsdb_search_end;
2009 *pstate = sstate;
2010 talloc_free(tmp_ctx);
2011 return true;
2014 static bool pdb_samba_dsdb_search_users(struct pdb_methods *m,
2015 struct pdb_search *search,
2016 uint32_t acct_flags)
2018 struct pdb_samba_dsdb_search_state *sstate;
2019 bool ret;
2021 ret = pdb_samba_dsdb_search_filter(m, search, &sstate, "(objectclass=user)");
2022 if (!ret) {
2023 return false;
2025 sstate->acct_flags = acct_flags;
2026 return true;
2029 static bool pdb_samba_dsdb_search_groups(struct pdb_methods *m,
2030 struct pdb_search *search)
2032 struct pdb_samba_dsdb_search_state *sstate;
2033 bool ret;
2035 ret = pdb_samba_dsdb_search_filter(m, search, &sstate,
2036 "(&(grouptype=%d)(objectclass=group))",
2037 GTYPE_SECURITY_GLOBAL_GROUP);
2038 if (!ret) {
2039 return false;
2041 sstate->acct_flags = 0;
2042 return true;
2045 static bool pdb_samba_dsdb_search_aliases(struct pdb_methods *m,
2046 struct pdb_search *search,
2047 const struct dom_sid *sid)
2049 struct pdb_samba_dsdb_search_state *sstate;
2050 bool ret;
2052 ret = pdb_samba_dsdb_search_filter(m, search, &sstate,
2053 "(&(grouptype=%d)(objectclass=group))",
2054 sid_check_is_builtin(sid)
2055 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2056 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
2057 if (!ret) {
2058 return false;
2060 sstate->acct_flags = 0;
2061 return true;
2065 * Instead of taking a gid or uid, this function takes a pointer to a
2066 * unixid.
2068 * This acts as an in-out variable so that the idmap functions can correctly
2069 * receive ID_TYPE_BOTH, and this function ensures cache details are filled
2070 * correctly rather than forcing the cache to store ID_TYPE_UID or ID_TYPE_GID.
2072 static bool pdb_samba_dsdb_id_to_sid(struct pdb_methods *m, struct unixid *id,
2073 struct dom_sid *sid)
2075 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2076 m->private_data, struct pdb_samba_dsdb_state);
2077 NTSTATUS status;
2078 struct id_map id_map;
2079 struct id_map *id_maps[2];
2080 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2081 if (!tmp_ctx) {
2082 return false;
2085 id_map.xid = *id;
2086 id_maps[0] = &id_map;
2087 id_maps[1] = NULL;
2089 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2090 if (!NT_STATUS_IS_OK(status)) {
2091 talloc_free(tmp_ctx);
2092 return false;
2095 if (id_map.xid.type != ID_TYPE_NOT_SPECIFIED) {
2096 id->type = id_map.xid.type;
2098 *sid = *id_map.sid;
2099 talloc_free(tmp_ctx);
2100 return true;
2103 static bool pdb_samba_dsdb_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2104 struct unixid *id)
2106 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2107 m->private_data, struct pdb_samba_dsdb_state);
2108 struct id_map id_map;
2109 struct id_map *id_maps[2];
2110 NTSTATUS status;
2111 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2112 if (!tmp_ctx) {
2113 return false;
2116 ZERO_STRUCT(id_map);
2117 id_map.sid = discard_const_p(struct dom_sid, sid);
2118 id_maps[0] = &id_map;
2119 id_maps[1] = NULL;
2121 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2122 talloc_free(tmp_ctx);
2123 if (!NT_STATUS_IS_OK(status)) {
2124 return false;
2126 if (id_map.xid.type != ID_TYPE_NOT_SPECIFIED) {
2127 *id = id_map.xid;
2128 return true;
2130 return false;
2133 static uint32_t pdb_samba_dsdb_capabilities(struct pdb_methods *m)
2135 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2138 static bool pdb_samba_dsdb_new_rid(struct pdb_methods *m, uint32_t *rid)
2140 return false;
2143 static bool pdb_samba_dsdb_get_trusteddom_pw(struct pdb_methods *m,
2144 const char *domain, char** pwd,
2145 struct dom_sid *sid,
2146 time_t *pass_last_set_time)
2148 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2149 m->private_data, struct pdb_samba_dsdb_state);
2150 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2151 const char * const attrs[] = {
2152 "securityIdentifier",
2153 "flatName",
2154 "trustPartner",
2155 "trustAuthOutgoing",
2156 "whenCreated",
2157 "msDS-SupportedEncryptionTypes",
2158 "trustAttributes",
2159 "trustDirection",
2160 "trustType",
2161 NULL
2163 struct ldb_message *msg;
2164 const struct ldb_val *password_val;
2165 int trust_direction_flags;
2166 int trust_type;
2167 int i;
2168 DATA_BLOB password_utf16;
2169 struct trustAuthInOutBlob password_blob;
2170 struct AuthenticationInformationArray *auth_array;
2171 char *password_talloc;
2172 size_t password_len;
2173 enum ndr_err_code ndr_err;
2174 NTSTATUS status;
2175 const char *netbios_domain = NULL;
2176 const struct dom_sid *domain_sid = NULL;
2178 status = dsdb_trust_search_tdo(state->ldb, domain, NULL,
2179 attrs, tmp_ctx, &msg);
2180 if (!NT_STATUS_IS_OK(status)) {
2182 * This can be called to work out of a domain is
2183 * trusted, rather than just to get the password
2185 DEBUG(2, ("Failed to get trusted domain password for %s - %s. "
2186 "It may not be a trusted domain.\n", domain,
2187 nt_errstr(status)));
2188 TALLOC_FREE(tmp_ctx);
2189 return false;
2192 netbios_domain = ldb_msg_find_attr_as_string(msg, "flatName", NULL);
2193 if (netbios_domain == NULL) {
2194 DEBUG(2, ("Trusted domain %s has to flatName defined.\n",
2195 domain));
2196 TALLOC_FREE(tmp_ctx);
2197 return false;
2200 domain_sid = samdb_result_dom_sid(tmp_ctx, msg, "securityIdentifier");
2201 if (domain_sid == NULL) {
2202 DEBUG(2, ("Trusted domain %s has no securityIdentifier defined.\n",
2203 domain));
2204 TALLOC_FREE(tmp_ctx);
2205 return false;
2208 trust_direction_flags = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
2209 if (!(trust_direction_flags & LSA_TRUST_DIRECTION_OUTBOUND)) {
2210 DEBUG(2, ("Trusted domain %s is is not an outbound trust.\n",
2211 domain));
2212 TALLOC_FREE(tmp_ctx);
2213 return false;
2216 trust_type = ldb_msg_find_attr_as_int(msg, "trustType", 0);
2217 if (trust_type == LSA_TRUST_TYPE_MIT) {
2218 DEBUG(1, ("Trusted domain %s is is not an AD trust "
2219 "(trustType == LSA_TRUST_TYPE_MIT).\n",
2220 domain));
2221 TALLOC_FREE(tmp_ctx);
2222 return false;
2225 password_val = ldb_msg_find_ldb_val(msg, "trustAuthOutgoing");
2226 if (password_val == NULL) {
2227 DEBUG(2, ("Failed to get trusted domain password for %s, "
2228 "attribute trustAuthOutgoing not returned.\n", domain));
2229 TALLOC_FREE(tmp_ctx);
2230 return false;
2233 ndr_err = ndr_pull_struct_blob(password_val, tmp_ctx, &password_blob,
2234 (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob);
2235 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2236 DEBUG(0, ("Failed to get trusted domain password for %s, "
2237 "attribute trustAuthOutgoing coult not be parsed %s.\n",
2238 domain,
2239 ndr_map_error2string(ndr_err)));
2240 TALLOC_FREE(tmp_ctx);
2241 return false;
2244 auth_array = &password_blob.current;
2246 for (i=0; i < auth_array->count; i++) {
2247 if (auth_array->array[i].AuthType == TRUST_AUTH_TYPE_CLEAR) {
2248 break;
2252 if (i == auth_array->count) {
2253 DEBUG(0, ("Trusted domain %s does not have a "
2254 "clear-text password stored\n",
2255 domain));
2256 TALLOC_FREE(tmp_ctx);
2257 return false;
2260 password_utf16 = data_blob_const(auth_array->array[i].AuthInfo.clear.password,
2261 auth_array->array[i].AuthInfo.clear.size);
2264 * In the future, make this function return a
2265 * cli_credentials that can store a MD4 hash with cli_credential_set_nt_hash()
2266 * but for now convert to UTF8 and fail if the string can not be converted.
2268 * We can't safely convert the random strings windows uses into
2269 * utf8.
2271 if (!convert_string_talloc(tmp_ctx,
2272 CH_UTF16MUNGED, CH_UTF8,
2273 password_utf16.data, password_utf16.length,
2274 (void *)&password_talloc,
2275 &password_len)) {
2276 DEBUG(0, ("FIXME: Could not convert password for trusted domain %s"
2277 " to UTF8. This may be a password set from Windows.\n",
2278 domain));
2279 TALLOC_FREE(tmp_ctx);
2280 return false;
2282 *pwd = SMB_STRNDUP(password_talloc, password_len);
2283 if (pass_last_set_time) {
2284 *pass_last_set_time = nt_time_to_unix(auth_array->array[i].LastUpdateTime);
2287 if (sid != NULL) {
2288 sid_copy(sid, domain_sid);
2291 TALLOC_FREE(tmp_ctx);
2292 return true;
2295 static NTSTATUS pdb_samba_dsdb_get_trusteddom_creds(struct pdb_methods *m,
2296 const char *domain,
2297 TALLOC_CTX *mem_ctx,
2298 struct cli_credentials **_creds)
2300 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2301 m->private_data, struct pdb_samba_dsdb_state);
2302 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2303 const char * const attrs[] = {
2304 "securityIdentifier",
2305 "flatName",
2306 "trustPartner",
2307 "trustAuthOutgoing",
2308 "whenCreated",
2309 "msDS-SupportedEncryptionTypes",
2310 "trustAttributes",
2311 "trustDirection",
2312 "trustType",
2313 NULL
2315 struct ldb_message *msg;
2316 const struct ldb_val *password_val;
2317 int trust_direction_flags;
2318 int trust_type;
2319 int i;
2320 DATA_BLOB password_utf16 = {};
2321 struct samr_Password *password_nt = NULL;
2322 uint32_t password_version = 0;
2323 DATA_BLOB old_password_utf16 = {};
2324 struct samr_Password *old_password_nt = NULL;
2325 struct trustAuthInOutBlob password_blob;
2326 enum ndr_err_code ndr_err;
2327 NTSTATUS status;
2328 time_t last_set_time = 0;
2329 struct cli_credentials *creds = NULL;
2330 bool ok;
2331 const char *my_netbios_name = NULL;
2332 const char *my_netbios_domain = NULL;
2333 const char *my_dns_domain = NULL;
2334 const char *netbios_domain = NULL;
2335 char *account_name = NULL;
2336 char *principal_name = NULL;
2337 const char *dns_domain = NULL;
2339 status = dsdb_trust_search_tdo(state->ldb, domain, NULL,
2340 attrs, tmp_ctx, &msg);
2341 if (!NT_STATUS_IS_OK(status)) {
2343 * This can be called to work out of a domain is
2344 * trusted, rather than just to get the password
2346 DEBUG(2, ("Failed to get trusted domain password for %s - %s "
2347 "It may not be a trusted domain.\n", domain,
2348 nt_errstr(status)));
2349 TALLOC_FREE(tmp_ctx);
2350 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2353 netbios_domain = ldb_msg_find_attr_as_string(msg, "flatName", NULL);
2354 if (netbios_domain == NULL) {
2355 DEBUG(2, ("Trusted domain %s has to flatName defined.\n",
2356 domain));
2357 TALLOC_FREE(tmp_ctx);
2358 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2361 dns_domain = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
2363 trust_direction_flags = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
2364 if (!(trust_direction_flags & LSA_TRUST_DIRECTION_OUTBOUND)) {
2365 DEBUG(2, ("Trusted domain %s is is not an outbound trust.\n",
2366 domain));
2367 TALLOC_FREE(tmp_ctx);
2368 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2371 trust_type = ldb_msg_find_attr_as_int(msg, "trustType", 0);
2372 if (trust_type == LSA_TRUST_TYPE_MIT) {
2373 DEBUG(1, ("Trusted domain %s is is not an AD trust "
2374 "(trustType == LSA_TRUST_TYPE_MIT).\n",
2375 domain));
2376 TALLOC_FREE(tmp_ctx);
2377 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2380 password_val = ldb_msg_find_ldb_val(msg, "trustAuthOutgoing");
2381 if (password_val == NULL) {
2382 DEBUG(2, ("Failed to get trusted domain password for %s, "
2383 "attribute trustAuthOutgoing not returned.\n", domain));
2384 TALLOC_FREE(tmp_ctx);
2385 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2388 ndr_err = ndr_pull_struct_blob(password_val, tmp_ctx, &password_blob,
2389 (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob);
2390 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2391 DEBUG(0, ("Failed to get trusted domain password for %s, "
2392 "attribute trustAuthOutgoing coult not be parsed %s.\n",
2393 domain,
2394 ndr_map_error2string(ndr_err)));
2395 TALLOC_FREE(tmp_ctx);
2396 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2399 for (i=0; i < password_blob.current.count; i++) {
2400 struct AuthenticationInformation *a =
2401 &password_blob.current.array[i];
2403 switch (a->AuthType) {
2404 case TRUST_AUTH_TYPE_NONE:
2405 break;
2407 case TRUST_AUTH_TYPE_VERSION:
2408 password_version = a->AuthInfo.version.version;
2409 break;
2411 case TRUST_AUTH_TYPE_CLEAR:
2412 last_set_time = nt_time_to_unix(a->LastUpdateTime);
2414 password_utf16 = data_blob_const(a->AuthInfo.clear.password,
2415 a->AuthInfo.clear.size);
2416 password_nt = NULL;
2417 break;
2419 case TRUST_AUTH_TYPE_NT4OWF:
2420 if (password_utf16.length != 0) {
2421 break;
2424 last_set_time = nt_time_to_unix(a->LastUpdateTime);
2426 password_nt = &a->AuthInfo.nt4owf.password;
2427 break;
2431 for (i=0; i < password_blob.previous.count; i++) {
2432 struct AuthenticationInformation *a = &password_blob.previous.array[i];
2434 switch (a->AuthType) {
2435 case TRUST_AUTH_TYPE_NONE:
2436 break;
2438 case TRUST_AUTH_TYPE_VERSION:
2439 break;
2441 case TRUST_AUTH_TYPE_CLEAR:
2442 old_password_utf16 = data_blob_const(a->AuthInfo.clear.password,
2443 a->AuthInfo.clear.size);
2444 old_password_nt = NULL;
2445 break;
2447 case TRUST_AUTH_TYPE_NT4OWF:
2448 if (old_password_utf16.length != 0) {
2449 break;
2452 old_password_nt = &a->AuthInfo.nt4owf.password;
2453 break;
2457 if (password_utf16.length == 0 && password_nt == NULL) {
2458 DEBUG(0, ("Trusted domain %s does not have a "
2459 "clear-text nor nt password stored\n",
2460 domain));
2461 TALLOC_FREE(tmp_ctx);
2462 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2465 my_netbios_name = lpcfg_netbios_name(state->lp_ctx);
2466 my_netbios_domain = lpcfg_workgroup(state->lp_ctx);
2467 my_dns_domain = lpcfg_dnsdomain(state->lp_ctx);
2469 creds = cli_credentials_init(tmp_ctx);
2470 if (creds == NULL) {
2471 TALLOC_FREE(tmp_ctx);
2472 return NT_STATUS_NO_MEMORY;
2475 ok = cli_credentials_set_workstation(creds, my_netbios_name, CRED_SPECIFIED);
2476 if (!ok) {
2477 TALLOC_FREE(tmp_ctx);
2478 return NT_STATUS_NO_MEMORY;
2481 ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED);
2482 if (!ok) {
2483 TALLOC_FREE(tmp_ctx);
2484 return NT_STATUS_NO_MEMORY;
2486 ok = cli_credentials_set_realm(creds, dns_domain, CRED_SPECIFIED);
2487 if (!ok) {
2488 TALLOC_FREE(tmp_ctx);
2489 return NT_STATUS_NO_MEMORY;
2492 if (my_dns_domain != NULL && dns_domain != NULL) {
2493 cli_credentials_set_secure_channel_type(creds, SEC_CHAN_DNS_DOMAIN);
2494 account_name = talloc_asprintf(tmp_ctx, "%s.", my_dns_domain);
2495 if (account_name == NULL) {
2496 TALLOC_FREE(tmp_ctx);
2497 return NT_STATUS_NO_MEMORY;
2499 principal_name = talloc_asprintf(tmp_ctx, "%s$@%s", my_netbios_domain,
2500 cli_credentials_get_realm(creds));
2501 if (principal_name == NULL) {
2502 TALLOC_FREE(tmp_ctx);
2503 return NT_STATUS_NO_MEMORY;
2505 } else {
2506 cli_credentials_set_secure_channel_type(creds, SEC_CHAN_DOMAIN);
2507 account_name = talloc_asprintf(tmp_ctx, "%s$", my_netbios_domain);
2508 if (account_name == NULL) {
2509 TALLOC_FREE(tmp_ctx);
2510 return NT_STATUS_NO_MEMORY;
2512 principal_name = NULL;
2515 ok = cli_credentials_set_username(creds, account_name, CRED_SPECIFIED);
2516 if (!ok) {
2517 TALLOC_FREE(tmp_ctx);
2518 return NT_STATUS_NO_MEMORY;
2521 if (principal_name != NULL) {
2522 ok = cli_credentials_set_principal(creds, principal_name,
2523 CRED_SPECIFIED);
2524 if (!ok) {
2525 TALLOC_FREE(tmp_ctx);
2526 return NT_STATUS_NO_MEMORY;
2530 if (old_password_nt != NULL) {
2531 ok = cli_credentials_set_old_nt_hash(creds, old_password_nt);
2532 if (!ok) {
2533 TALLOC_FREE(tmp_ctx);
2534 return NT_STATUS_NO_MEMORY;
2538 if (old_password_utf16.length > 0) {
2539 ok = cli_credentials_set_old_utf16_password(creds,
2540 &old_password_utf16);
2541 if (!ok) {
2542 TALLOC_FREE(tmp_ctx);
2543 return NT_STATUS_NO_MEMORY;
2547 if (password_nt != NULL) {
2548 ok = cli_credentials_set_nt_hash(creds, password_nt,
2549 CRED_SPECIFIED);
2550 if (!ok) {
2551 TALLOC_FREE(tmp_ctx);
2552 return NT_STATUS_NO_MEMORY;
2556 if (password_utf16.length > 0) {
2557 ok = cli_credentials_set_utf16_password(creds,
2558 &password_utf16,
2559 CRED_SPECIFIED);
2560 if (!ok) {
2561 TALLOC_FREE(tmp_ctx);
2562 return NT_STATUS_NO_MEMORY;
2566 cli_credentials_set_password_last_changed_time(creds, last_set_time);
2567 cli_credentials_set_kvno(creds, password_version);
2569 if (password_utf16.length > 0 && dns_domain != NULL) {
2571 * Force kerberos if this is an active directory domain
2573 cli_credentials_set_kerberos_state(creds,
2574 CRED_MUST_USE_KERBEROS);
2575 } else {
2577 * TODO: we should allow krb5 with the raw nt hash.
2579 cli_credentials_set_kerberos_state(creds,
2580 CRED_DONT_USE_KERBEROS);
2583 *_creds = talloc_move(mem_ctx, &creds);
2584 TALLOC_FREE(tmp_ctx);
2585 return NT_STATUS_OK;
2588 static bool pdb_samba_dsdb_set_trusteddom_pw(struct pdb_methods *m,
2589 const char* domain, const char* pwd,
2590 const struct dom_sid *sid)
2592 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2593 m->private_data, struct pdb_samba_dsdb_state);
2594 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2595 const char * const attrs[] = {
2596 "trustAuthOutgoing",
2597 "trustDirection",
2598 "trustType",
2599 NULL
2601 struct ldb_message *msg = NULL;
2602 int trust_direction_flags;
2603 int trust_type;
2604 int i;
2605 const struct ldb_val *old_val = NULL;
2606 struct trustAuthInOutBlob old_blob = {};
2607 uint32_t old_version = 0;
2608 uint32_t new_version = 0;
2609 DATA_BLOB new_utf16 = {};
2610 struct trustAuthInOutBlob new_blob = {};
2611 struct ldb_val new_val = {};
2612 struct timeval tv = timeval_current();
2613 NTTIME now = timeval_to_nttime(&tv);
2614 enum ndr_err_code ndr_err;
2615 NTSTATUS status;
2616 bool ok;
2617 int ret;
2619 ret = ldb_transaction_start(state->ldb);
2620 if (ret != LDB_SUCCESS) {
2621 DEBUG(2, ("Failed to start transaction.\n"));
2622 TALLOC_FREE(tmp_ctx);
2623 return false;
2626 ok = samdb_is_pdc(state->ldb);
2627 if (!ok) {
2628 DEBUG(2, ("Password changes for domain %s are only allowed on a PDC.\n",
2629 domain));
2630 TALLOC_FREE(tmp_ctx);
2631 ldb_transaction_cancel(state->ldb);
2632 return false;
2635 status = dsdb_trust_search_tdo(state->ldb, domain, NULL,
2636 attrs, tmp_ctx, &msg);
2637 if (!NT_STATUS_IS_OK(status)) {
2639 * This can be called to work out of a domain is
2640 * trusted, rather than just to get the password
2642 DEBUG(2, ("Failed to get trusted domain password for %s - %s. "
2643 "It may not be a trusted domain.\n", domain,
2644 nt_errstr(status)));
2645 TALLOC_FREE(tmp_ctx);
2646 ldb_transaction_cancel(state->ldb);
2647 return false;
2650 trust_direction_flags = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
2651 if (!(trust_direction_flags & LSA_TRUST_DIRECTION_OUTBOUND)) {
2652 DEBUG(2, ("Trusted domain %s is is not an outbound trust, can't set a password.\n",
2653 domain));
2654 TALLOC_FREE(tmp_ctx);
2655 ldb_transaction_cancel(state->ldb);
2656 return false;
2659 trust_type = ldb_msg_find_attr_as_int(msg, "trustType", 0);
2660 switch (trust_type) {
2661 case LSA_TRUST_TYPE_DOWNLEVEL:
2662 case LSA_TRUST_TYPE_UPLEVEL:
2663 break;
2664 default:
2665 DEBUG(0, ("Trusted domain %s is of type 0x%X - "
2666 "password changes are not supported\n",
2667 domain, (unsigned)trust_type));
2668 TALLOC_FREE(tmp_ctx);
2669 ldb_transaction_cancel(state->ldb);
2670 return false;
2673 old_val = ldb_msg_find_ldb_val(msg, "trustAuthOutgoing");
2674 if (old_val != NULL) {
2675 ndr_err = ndr_pull_struct_blob(old_val, tmp_ctx, &old_blob,
2676 (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob);
2677 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2678 DEBUG(0, ("Failed to get trusted domain password for %s, "
2679 "attribute trustAuthOutgoing coult not be parsed %s.\n",
2680 domain,
2681 ndr_map_error2string(ndr_err)));
2682 TALLOC_FREE(tmp_ctx);
2683 ldb_transaction_cancel(state->ldb);
2684 return false;
2688 for (i=0; i < old_blob.current.count; i++) {
2689 struct AuthenticationInformation *a =
2690 &old_blob.current.array[i];
2692 switch (a->AuthType) {
2693 case TRUST_AUTH_TYPE_NONE:
2694 break;
2696 case TRUST_AUTH_TYPE_VERSION:
2697 old_version = a->AuthInfo.version.version;
2698 break;
2700 case TRUST_AUTH_TYPE_CLEAR:
2701 break;
2703 case TRUST_AUTH_TYPE_NT4OWF:
2704 break;
2708 new_version = old_version + 1;
2709 ok = convert_string_talloc(tmp_ctx,
2710 CH_UNIX, CH_UTF16,
2711 pwd, strlen(pwd),
2712 (void *)&new_utf16.data,
2713 &new_utf16.length);
2714 if (!ok) {
2715 DEBUG(0, ("Failed to generate new_utf16 password for domain %s\n",
2716 domain));
2717 TALLOC_FREE(tmp_ctx);
2718 ldb_transaction_cancel(state->ldb);
2719 return false;
2722 if (new_utf16.length < 28) {
2723 DEBUG(0, ("new_utf16[%zu] version[%u] for domain %s to short.\n",
2724 new_utf16.length,
2725 (unsigned)new_version,
2726 domain));
2727 TALLOC_FREE(tmp_ctx);
2728 ldb_transaction_cancel(state->ldb);
2729 return false;
2731 if (new_utf16.length > 498) {
2732 DEBUG(0, ("new_utf16[%zu] version[%u] for domain %s to long.\n",
2733 new_utf16.length,
2734 (unsigned)new_version,
2735 domain));
2736 TALLOC_FREE(tmp_ctx);
2737 ldb_transaction_cancel(state->ldb);
2738 return false;
2741 new_blob.count = MAX(old_blob.current.count, 2);
2742 new_blob.current.array = talloc_zero_array(tmp_ctx,
2743 struct AuthenticationInformation,
2744 new_blob.count);
2745 if (new_blob.current.array == NULL) {
2746 DEBUG(0, ("talloc_zero_array(%u) failed\n",
2747 (unsigned)new_blob.count));
2748 TALLOC_FREE(tmp_ctx);
2749 ldb_transaction_cancel(state->ldb);
2750 return false;
2752 new_blob.previous.array = talloc_zero_array(tmp_ctx,
2753 struct AuthenticationInformation,
2754 new_blob.count);
2755 if (new_blob.current.array == NULL) {
2756 DEBUG(0, ("talloc_zero_array(%u) failed\n",
2757 (unsigned)new_blob.count));
2758 TALLOC_FREE(tmp_ctx);
2759 ldb_transaction_cancel(state->ldb);
2760 return false;
2763 for (i = 0; i < old_blob.current.count; i++) {
2764 struct AuthenticationInformation *o =
2765 &old_blob.current.array[i];
2766 struct AuthenticationInformation *p =
2767 &new_blob.previous.array[i];
2769 *p = *o;
2770 new_blob.previous.count++;
2772 for (; i < new_blob.count; i++) {
2773 struct AuthenticationInformation *pi =
2774 &new_blob.previous.array[i];
2776 if (i == 0) {
2778 * new_blob.previous is still empty so
2779 * we'll do new_blob.previous = new_blob.current
2780 * below.
2782 break;
2785 pi->LastUpdateTime = now;
2786 pi->AuthType = TRUST_AUTH_TYPE_NONE;
2787 new_blob.previous.count++;
2790 for (i = 0; i < new_blob.count; i++) {
2791 struct AuthenticationInformation *ci =
2792 &new_blob.current.array[i];
2794 ci->LastUpdateTime = now;
2795 switch (i) {
2796 case 0:
2797 ci->AuthType = TRUST_AUTH_TYPE_CLEAR;
2798 ci->AuthInfo.clear.size = new_utf16.length;
2799 ci->AuthInfo.clear.password = new_utf16.data;
2800 break;
2801 case 1:
2802 ci->AuthType = TRUST_AUTH_TYPE_VERSION;
2803 ci->AuthInfo.version.version = new_version;
2804 break;
2805 default:
2806 ci->AuthType = TRUST_AUTH_TYPE_NONE;
2807 break;
2810 new_blob.current.count++;
2813 if (new_blob.previous.count == 0) {
2814 TALLOC_FREE(new_blob.previous.array);
2815 new_blob.previous = new_blob.current;
2818 ndr_err = ndr_push_struct_blob(&new_val, tmp_ctx, &new_blob,
2819 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
2820 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2821 DEBUG(0, ("Failed to generate trustAuthOutgoing for "
2822 "trusted domain password for %s: %s.\n",
2823 domain, ndr_map_error2string(ndr_err)));
2824 TALLOC_FREE(tmp_ctx);
2825 ldb_transaction_cancel(state->ldb);
2826 return false;
2829 msg->num_elements = 0;
2830 ret = ldb_msg_add_empty(msg, "trustAuthOutgoing",
2831 LDB_FLAG_MOD_REPLACE, NULL);
2832 if (ret != LDB_SUCCESS) {
2833 DEBUG(0, ("ldb_msg_add_empty() failed\n"));
2834 TALLOC_FREE(tmp_ctx);
2835 ldb_transaction_cancel(state->ldb);
2836 return false;
2838 ret = ldb_msg_add_value(msg, "trustAuthOutgoing",
2839 &new_val, NULL);
2840 if (ret != LDB_SUCCESS) {
2841 DEBUG(0, ("ldb_msg_add_value() failed\n"));
2842 TALLOC_FREE(tmp_ctx);
2843 ldb_transaction_cancel(state->ldb);
2844 return false;
2847 ret = ldb_modify(state->ldb, msg);
2848 if (ret != LDB_SUCCESS) {
2849 DEBUG(0, ("Failed to replace trustAuthOutgoing for "
2850 "trusted domain password for %s: %s - %s\n",
2851 domain, ldb_strerror(ret), ldb_errstring(state->ldb)));
2852 TALLOC_FREE(tmp_ctx);
2853 ldb_transaction_cancel(state->ldb);
2854 return false;
2857 ret = ldb_transaction_commit(state->ldb);
2858 if (ret != LDB_SUCCESS) {
2859 DEBUG(0, ("Failed to commit trustAuthOutgoing for "
2860 "trusted domain password for %s: %s - %s\n",
2861 domain, ldb_strerror(ret), ldb_errstring(state->ldb)));
2862 TALLOC_FREE(tmp_ctx);
2863 return false;
2866 DEBUG(1, ("Added new_version[%u] to trustAuthOutgoing for "
2867 "trusted domain password for %s.\n",
2868 (unsigned)new_version, domain));
2869 TALLOC_FREE(tmp_ctx);
2870 return true;
2873 static bool pdb_samba_dsdb_del_trusteddom_pw(struct pdb_methods *m,
2874 const char *domain)
2876 return false;
2879 static NTSTATUS pdb_samba_dsdb_enum_trusteddoms(struct pdb_methods *m,
2880 TALLOC_CTX *mem_ctx,
2881 uint32_t *num_domains,
2882 struct trustdom_info ***domains)
2884 *num_domains = 0;
2885 *domains = NULL;
2886 return NT_STATUS_OK;
2889 static bool pdb_samba_dsdb_is_responsible_for_wellknown(struct pdb_methods *m)
2891 return true;
2894 static bool pdb_samba_dsdb_is_responsible_for_everything_else(struct pdb_methods *m)
2896 return true;
2899 static void pdb_samba_dsdb_init_methods(struct pdb_methods *m)
2901 m->name = "samba_dsdb";
2902 m->get_domain_info = pdb_samba_dsdb_get_domain_info;
2903 m->getsampwnam = pdb_samba_dsdb_getsampwnam;
2904 m->getsampwsid = pdb_samba_dsdb_getsampwsid;
2905 m->create_user = pdb_samba_dsdb_create_user;
2906 m->delete_user = pdb_samba_dsdb_delete_user;
2907 m->add_sam_account = pdb_samba_dsdb_add_sam_account;
2908 m->update_sam_account = pdb_samba_dsdb_update_sam_account;
2909 m->delete_sam_account = pdb_samba_dsdb_delete_sam_account;
2910 m->rename_sam_account = pdb_samba_dsdb_rename_sam_account;
2911 m->update_login_attempts = pdb_samba_dsdb_update_login_attempts;
2912 m->getgrsid = pdb_samba_dsdb_getgrsid;
2913 m->getgrgid = pdb_samba_dsdb_getgrgid;
2914 m->getgrnam = pdb_samba_dsdb_getgrnam;
2915 m->create_dom_group = pdb_samba_dsdb_create_dom_group;
2916 m->delete_dom_group = pdb_samba_dsdb_delete_dom_group;
2917 m->add_group_mapping_entry = pdb_samba_dsdb_add_group_mapping_entry;
2918 m->update_group_mapping_entry = pdb_samba_dsdb_update_group_mapping_entry;
2919 m->delete_group_mapping_entry = pdb_samba_dsdb_delete_group_mapping_entry;
2920 m->enum_group_mapping = pdb_samba_dsdb_enum_group_mapping;
2921 m->enum_group_members = pdb_samba_dsdb_enum_group_members;
2922 m->enum_group_memberships = pdb_samba_dsdb_enum_group_memberships;
2923 m->set_unix_primary_group = pdb_samba_dsdb_set_unix_primary_group;
2924 m->add_groupmem = pdb_samba_dsdb_add_groupmem;
2925 m->del_groupmem = pdb_samba_dsdb_del_groupmem;
2926 m->create_alias = pdb_samba_dsdb_create_alias;
2927 m->delete_alias = pdb_samba_dsdb_delete_alias;
2928 m->get_aliasinfo = pdb_default_get_aliasinfo;
2929 m->add_aliasmem = pdb_samba_dsdb_add_aliasmem;
2930 m->del_aliasmem = pdb_samba_dsdb_del_aliasmem;
2931 m->enum_aliasmem = pdb_samba_dsdb_enum_aliasmem;
2932 m->enum_alias_memberships = pdb_samba_dsdb_enum_alias_memberships;
2933 m->lookup_rids = pdb_samba_dsdb_lookup_rids;
2934 m->lookup_names = pdb_samba_dsdb_lookup_names;
2935 m->get_account_policy = pdb_samba_dsdb_get_account_policy;
2936 m->set_account_policy = pdb_samba_dsdb_set_account_policy;
2937 m->get_seq_num = pdb_samba_dsdb_get_seq_num;
2938 m->search_users = pdb_samba_dsdb_search_users;
2939 m->search_groups = pdb_samba_dsdb_search_groups;
2940 m->search_aliases = pdb_samba_dsdb_search_aliases;
2941 m->id_to_sid = pdb_samba_dsdb_id_to_sid;
2942 m->sid_to_id = pdb_samba_dsdb_sid_to_id;
2943 m->capabilities = pdb_samba_dsdb_capabilities;
2944 m->new_rid = pdb_samba_dsdb_new_rid;
2945 m->get_trusteddom_pw = pdb_samba_dsdb_get_trusteddom_pw;
2946 m->get_trusteddom_creds = pdb_samba_dsdb_get_trusteddom_creds;
2947 m->set_trusteddom_pw = pdb_samba_dsdb_set_trusteddom_pw;
2948 m->del_trusteddom_pw = pdb_samba_dsdb_del_trusteddom_pw;
2949 m->enum_trusteddoms = pdb_samba_dsdb_enum_trusteddoms;
2950 m->is_responsible_for_wellknown =
2951 pdb_samba_dsdb_is_responsible_for_wellknown;
2952 m->is_responsible_for_everything_else =
2953 pdb_samba_dsdb_is_responsible_for_everything_else;
2956 static void free_private_data(void **vp)
2958 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2959 *vp, struct pdb_samba_dsdb_state);
2960 talloc_unlink(state, state->ldb);
2961 return;
2964 static NTSTATUS pdb_samba_dsdb_init_secrets(struct pdb_methods *m)
2966 struct pdb_domain_info *dom_info;
2967 struct dom_sid stored_sid;
2968 struct GUID stored_guid;
2969 bool sid_exists_and_matches = false;
2970 bool guid_exists_and_matches = false;
2971 bool ret;
2973 dom_info = pdb_samba_dsdb_get_domain_info(m, m);
2974 if (!dom_info) {
2975 return NT_STATUS_UNSUCCESSFUL;
2978 ret = secrets_fetch_domain_sid(dom_info->name, &stored_sid);
2979 if (ret) {
2980 if (dom_sid_equal(&stored_sid, &dom_info->sid)) {
2981 sid_exists_and_matches = true;
2985 if (sid_exists_and_matches == false) {
2986 secrets_clear_domain_protection(dom_info->name);
2987 ret = secrets_store_domain_sid(dom_info->name,
2988 &dom_info->sid);
2989 ret &= secrets_mark_domain_protected(dom_info->name);
2990 if (!ret) {
2991 goto done;
2995 ret = secrets_fetch_domain_guid(dom_info->name, &stored_guid);
2996 if (ret) {
2997 if (GUID_equal(&stored_guid, &dom_info->guid)) {
2998 guid_exists_and_matches = true;
3002 if (guid_exists_and_matches == false) {
3003 secrets_clear_domain_protection(dom_info->name);
3004 ret = secrets_store_domain_guid(dom_info->name,
3005 &dom_info->guid);
3006 ret &= secrets_mark_domain_protected(dom_info->name);
3007 if (!ret) {
3008 goto done;
3012 done:
3013 TALLOC_FREE(dom_info);
3014 if (!ret) {
3015 return NT_STATUS_UNSUCCESSFUL;
3017 return NT_STATUS_OK;
3020 static NTSTATUS pdb_init_samba_dsdb(struct pdb_methods **pdb_method,
3021 const char *location)
3023 struct pdb_methods *m;
3024 struct pdb_samba_dsdb_state *state;
3025 NTSTATUS status;
3027 if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
3028 return status;
3031 state = talloc_zero(m, struct pdb_samba_dsdb_state);
3032 if (state == NULL) {
3033 goto nomem;
3035 m->private_data = state;
3036 m->free_private_data = free_private_data;
3037 pdb_samba_dsdb_init_methods(m);
3039 state->ev = s4_event_context_init(state);
3040 if (!state->ev) {
3041 DEBUG(0, ("s4_event_context_init failed\n"));
3042 goto nomem;
3045 state->lp_ctx = loadparm_init_s3(state, loadparm_s3_helpers());
3046 if (state->lp_ctx == NULL) {
3047 DEBUG(0, ("loadparm_init_s3 failed\n"));
3048 goto nomem;
3051 if (location) {
3052 state->ldb = samdb_connect_url(state,
3053 state->ev,
3054 state->lp_ctx,
3055 system_session(state->lp_ctx),
3056 0, location);
3057 } else {
3058 state->ldb = samdb_connect(state,
3059 state->ev,
3060 state->lp_ctx,
3061 system_session(state->lp_ctx), 0);
3064 if (!state->ldb) {
3065 DEBUG(0, ("samdb_connect failed\n"));
3066 status = NT_STATUS_INTERNAL_ERROR;
3067 goto fail;
3070 state->idmap_ctx = idmap_init(state, state->ev,
3071 state->lp_ctx);
3072 if (!state->idmap_ctx) {
3073 DEBUG(0, ("idmap failed\n"));
3074 status = NT_STATUS_INTERNAL_ERROR;
3075 goto fail;
3078 status = pdb_samba_dsdb_init_secrets(m);
3079 if (!NT_STATUS_IS_OK(status)) {
3080 DEBUG(10, ("pdb_samba_dsdb_init_secrets failed!\n"));
3081 goto fail;
3084 *pdb_method = m;
3085 return NT_STATUS_OK;
3086 nomem:
3087 status = NT_STATUS_NO_MEMORY;
3088 fail:
3089 TALLOC_FREE(m);
3090 return status;
3093 NTSTATUS pdb_samba_dsdb_init(void);
3094 NTSTATUS pdb_samba_dsdb_init(void)
3096 NTSTATUS status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba_dsdb",
3097 pdb_init_samba_dsdb);
3098 if (!NT_STATUS_IS_OK(status)) {
3099 return status;
3101 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
3102 pdb_init_samba_dsdb);