1 /* need access mask/acl implementation */
4 Unix SMB/CIFS implementation.
6 endpoint server for the lsarpc pipe
8 Copyright (C) Andrew Tridgell 2004
9 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "rpc_server/lsa/lsa.h"
26 #include "system/kerberos.h"
27 #include "auth/kerberos/kerberos.h"
28 #include "librpc/gen_ndr/ndr_drsblobs.h"
29 #include "librpc/gen_ndr/ndr_lsa.h"
30 #include "../lib/crypto/crypto.h"
31 #include "lib/util/tsort.h"
32 #include "dsdb/common/util.h"
33 #include "libcli/security/session.h"
34 #include "libcli/lsarpc/util_lsarpc.h"
35 #include "lib/messaging/irpc.h"
36 #include "libds/common/roles.h"
38 #define DCESRV_INTERFACE_LSARPC_BIND(context, iface) \
39 dcesrv_interface_lsarpc_bind(context, iface)
40 static NTSTATUS dcesrv_interface_lsarpc_bind(struct dcesrv_connection_context *context,
41 const struct dcesrv_interface *iface)
43 return dcesrv_interface_bind_reject_connect(context, iface);
46 static NTSTATUS lsarpc__op_init_server(struct dcesrv_context *dce_ctx,
47 const struct dcesrv_endpoint_server *ep_server);
48 static const struct dcesrv_interface dcesrv_lsarpc_interface;
50 #define NCACN_NP_PIPE_NETLOGON "ncacn_np:[\\pipe\\netlogon]"
51 #define NCACN_NP_PIPE_LSASS "ncacn_np:[\\pipe\\lsass]"
52 #define DCESRV_INTERFACE_LSARPC_NCACN_NP_SECONDARY_ENDPOINT NCACN_NP_PIPE_LSASS
54 #define DCESRV_INTERFACE_LSARPC_INIT_SERVER \
55 dcesrv_interface_lsarpc_init_server
56 static NTSTATUS dcesrv_interface_lsarpc_init_server(struct dcesrv_context *dce_ctx,
57 const struct dcesrv_endpoint_server *ep_server)
59 if (lpcfg_lsa_over_netlogon(dce_ctx->lp_ctx)) {
60 NTSTATUS ret = dcesrv_interface_register(dce_ctx,
61 NCACN_NP_PIPE_NETLOGON,
63 &dcesrv_lsarpc_interface, NULL);
64 if (!NT_STATUS_IS_OK(ret)) {
65 DEBUG(1,("lsarpc_op_init_server: failed to register endpoint '\\pipe\\netlogon'\n"));
69 return lsarpc__op_init_server(dce_ctx, ep_server);
73 this type allows us to distinguish handle types
77 state associated with a lsa_OpenAccount() operation
79 struct lsa_account_state {
80 struct lsa_policy_state *policy;
82 struct dom_sid *account_sid;
87 state associated with a lsa_OpenSecret() operation
89 struct lsa_secret_state {
90 struct lsa_policy_state *policy;
92 struct ldb_dn *secret_dn;
93 struct ldb_context *sam_ldb;
98 state associated with a lsa_OpenTrustedDomain() operation
100 struct lsa_trusted_domain_state {
101 struct lsa_policy_state *policy;
102 uint32_t access_mask;
103 struct ldb_dn *trusted_domain_dn;
104 struct ldb_dn *trusted_domain_user_dn;
107 static bool dcesrc_lsa_valid_AccountRight(const char *right)
109 enum sec_privilege priv_id;
112 priv_id = sec_privilege_id(right);
113 if (priv_id != SEC_PRIV_INVALID) {
117 right_bit = sec_right_bit(right);
118 if (right_bit != 0) {
126 this is based on the samba3 function make_lsa_object_sd()
127 It uses the same logic, but with samba4 helper functions
129 static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
130 struct security_descriptor **sd,
136 struct dom_sid *domain_sid, *domain_admins_sid;
137 const char *domain_admins_sid_str, *sidstr;
138 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
140 status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
141 if (!NT_STATUS_IS_OK(status)) {
142 TALLOC_FREE(tmp_ctx);
146 domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
147 if (domain_admins_sid == NULL) {
148 TALLOC_FREE(tmp_ctx);
149 return NT_STATUS_NO_MEMORY;
152 domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
153 if (domain_admins_sid_str == NULL) {
154 TALLOC_FREE(tmp_ctx);
155 return NT_STATUS_NO_MEMORY;
158 sidstr = dom_sid_string(tmp_ctx, sid);
159 if (sidstr == NULL) {
160 TALLOC_FREE(tmp_ctx);
161 return NT_STATUS_NO_MEMORY;
164 *sd = security_descriptor_dacl_create(mem_ctx,
168 SEC_ACE_TYPE_ACCESS_ALLOWED,
169 SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,
171 SID_BUILTIN_ADMINISTRATORS,
172 SEC_ACE_TYPE_ACCESS_ALLOWED,
175 SID_BUILTIN_ACCOUNT_OPERATORS,
176 SEC_ACE_TYPE_ACCESS_ALLOWED,
179 domain_admins_sid_str,
180 SEC_ACE_TYPE_ACCESS_ALLOWED,
184 SEC_ACE_TYPE_ACCESS_ALLOWED,
188 talloc_free(tmp_ctx);
190 NT_STATUS_HAVE_NO_MEMORY(*sd);
196 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
198 struct lsa_EnumAccountRights *r);
200 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
202 struct lsa_policy_state *state,
205 const struct lsa_RightSet *rights);
210 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
213 enum dcerpc_transport_t transport =
214 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
215 struct dcesrv_handle *h;
217 if (transport != NCACN_NP && transport != NCALRPC) {
218 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
221 *r->out.handle = *r->in.handle;
223 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
227 ZERO_STRUCTP(r->out.handle);
236 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
237 struct lsa_Delete *r)
239 return NT_STATUS_NOT_SUPPORTED;
246 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
247 struct lsa_DeleteObject *r)
249 struct auth_session_info *session_info =
250 dcesrv_call_session_info(dce_call);
251 struct dcesrv_handle *h;
254 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
256 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
257 struct lsa_secret_state *secret_state = h->data;
259 /* Ensure user is permitted to delete this... */
260 switch (security_session_user_level(session_info, NULL))
262 case SECURITY_SYSTEM:
263 case SECURITY_ADMINISTRATOR:
266 /* Users and anonymous are not allowed to delete things */
267 return NT_STATUS_ACCESS_DENIED;
270 ret = ldb_delete(secret_state->sam_ldb,
271 secret_state->secret_dn);
272 if (ret != LDB_SUCCESS) {
273 return NT_STATUS_INVALID_HANDLE;
276 ZERO_STRUCTP(r->out.handle);
280 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
281 struct lsa_trusted_domain_state *trusted_domain_state =
282 talloc_get_type(h->data, struct lsa_trusted_domain_state);
283 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
284 if (ret != LDB_SUCCESS) {
285 return NT_STATUS_INTERNAL_DB_CORRUPTION;
288 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
289 trusted_domain_state->trusted_domain_dn);
290 if (ret != LDB_SUCCESS) {
291 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
292 return NT_STATUS_INVALID_HANDLE;
295 if (trusted_domain_state->trusted_domain_user_dn) {
296 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
297 trusted_domain_state->trusted_domain_user_dn);
298 if (ret != LDB_SUCCESS) {
299 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
300 return NT_STATUS_INVALID_HANDLE;
304 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
305 if (ret != LDB_SUCCESS) {
306 return NT_STATUS_INTERNAL_DB_CORRUPTION;
309 ZERO_STRUCTP(r->out.handle);
313 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
314 struct lsa_RightSet *rights;
315 struct lsa_account_state *astate;
316 struct lsa_EnumAccountRights r2;
319 rights = talloc(mem_ctx, struct lsa_RightSet);
321 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
325 r2.in.handle = &astate->policy->handle->wire_handle;
326 r2.in.sid = astate->account_sid;
327 r2.out.rights = rights;
329 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
330 but we have a LSA_HANDLE_ACCOUNT here, so this call
332 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
333 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
337 if (!NT_STATUS_IS_OK(status)) {
341 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
342 LDB_FLAG_MOD_DELETE, astate->account_sid,
344 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
348 if (!NT_STATUS_IS_OK(status)) {
352 ZERO_STRUCTP(r->out.handle);
357 return NT_STATUS_INVALID_HANDLE;
364 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
365 struct lsa_EnumPrivs *r)
367 struct dcesrv_handle *h;
369 enum sec_privilege priv;
370 const char *privname;
372 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
374 i = *r->in.resume_handle;
376 while (((priv = sec_privilege_from_index(i)) != SEC_PRIV_INVALID) &&
377 r->out.privs->count < r->in.max_count) {
378 struct lsa_PrivEntry *e;
379 privname = sec_privilege_name(priv);
380 r->out.privs->privs = talloc_realloc(r->out.privs,
382 struct lsa_PrivEntry,
383 r->out.privs->count+1);
384 if (r->out.privs->privs == NULL) {
385 return NT_STATUS_NO_MEMORY;
387 e = &r->out.privs->privs[r->out.privs->count];
390 e->name.string = privname;
391 r->out.privs->count++;
395 *r->out.resume_handle = i;
404 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
405 struct lsa_QuerySecurity *r)
407 struct auth_session_info *session_info =
408 dcesrv_call_session_info(dce_call);
409 struct dcesrv_handle *h;
410 const struct security_descriptor *sd = NULL;
411 uint32_t access_granted = 0;
412 struct sec_desc_buf *sdbuf = NULL;
416 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
418 sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
420 if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
421 struct lsa_policy_state *pstate = h->data;
424 access_granted = pstate->access_mask;
426 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
427 struct lsa_account_state *astate = h->data;
428 struct security_descriptor *_sd = NULL;
430 status = dcesrv_build_lsa_sd(mem_ctx, &_sd, sid,
431 LSA_ACCOUNT_ALL_ACCESS);
432 if (!NT_STATUS_IS_OK(status)) {
436 access_granted = astate->access_mask;
438 return NT_STATUS_INVALID_HANDLE;
441 sdbuf = talloc_zero(mem_ctx, struct sec_desc_buf);
443 return NT_STATUS_NO_MEMORY;
446 status = security_descriptor_for_client(sdbuf, sd, r->in.sec_info,
447 access_granted, &sdbuf->sd);
448 if (!NT_STATUS_IS_OK(status)) {
452 *r->out.sdbuf = sdbuf;
461 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
462 struct lsa_SetSecObj *r)
464 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
471 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
472 struct lsa_ChangePassword *r)
474 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
478 dssetup_DsRoleGetPrimaryDomainInformation
480 This is not an LSA call, but is the only call left on the DSSETUP
481 pipe (after the pipe was truncated), and needs lsa_get_policy_state
483 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
485 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
487 union dssetup_DsRoleInfo *info;
489 info = talloc_zero(mem_ctx, union dssetup_DsRoleInfo);
490 W_ERROR_HAVE_NO_MEMORY(info);
492 switch (r->in.level) {
493 case DS_ROLE_BASIC_INFORMATION:
495 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
497 const char *domain = NULL;
498 const char *dns_domain = NULL;
499 const char *forest = NULL;
500 struct GUID domain_guid;
501 struct lsa_policy_state *state;
503 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx,
504 0, /* we skip access checks */
506 if (!NT_STATUS_IS_OK(status)) {
507 return ntstatus_to_werror(status);
510 ZERO_STRUCT(domain_guid);
512 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
513 case ROLE_STANDALONE:
514 role = DS_ROLE_STANDALONE_SERVER;
516 case ROLE_DOMAIN_MEMBER:
517 role = DS_ROLE_MEMBER_SERVER;
519 case ROLE_ACTIVE_DIRECTORY_DC:
520 if (samdb_is_pdc(state->sam_ldb)) {
521 role = DS_ROLE_PRIMARY_DC;
523 role = DS_ROLE_BACKUP_DC;
528 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
529 case ROLE_STANDALONE:
530 domain = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
531 W_ERROR_HAVE_NO_MEMORY(domain);
533 case ROLE_DOMAIN_MEMBER:
534 domain = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
535 W_ERROR_HAVE_NO_MEMORY(domain);
536 /* TODO: what is with dns_domain and forest and guid? */
538 case ROLE_ACTIVE_DIRECTORY_DC:
539 flags = DS_ROLE_PRIMARY_DS_RUNNING;
541 if (state->mixed_domain == 1) {
542 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
545 domain = state->domain_name;
546 dns_domain = state->domain_dns;
547 forest = state->forest_dns;
549 domain_guid = state->domain_guid;
550 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
554 info->basic.role = role;
555 info->basic.flags = flags;
556 info->basic.domain = domain;
557 info->basic.dns_domain = dns_domain;
558 info->basic.forest = forest;
559 info->basic.domain_guid = domain_guid;
564 case DS_ROLE_UPGRADE_STATUS:
566 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
567 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
572 case DS_ROLE_OP_STATUS:
574 info->opstatus.status = DS_ROLE_OP_IDLE;
580 return WERR_INVALID_PARAMETER;
585 fill in the AccountDomain info
587 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
588 struct lsa_DomainInfo *info)
590 info->name.string = state->domain_name;
591 info->sid = state->domain_sid;
597 fill in the DNS domain info
599 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
600 struct lsa_DnsDomainInfo *info)
602 info->name.string = state->domain_name;
603 info->sid = state->domain_sid;
604 info->dns_domain.string = state->domain_dns;
605 info->dns_forest.string = state->forest_dns;
606 info->domain_guid = state->domain_guid;
614 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
615 struct lsa_QueryInfoPolicy2 *r)
617 struct lsa_policy_state *state;
618 struct dcesrv_handle *h;
619 union lsa_PolicyInformation *info;
623 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
627 info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
629 return NT_STATUS_NO_MEMORY;
633 switch (r->in.level) {
634 case LSA_POLICY_INFO_AUDIT_LOG:
635 /* we don't need to fill in any of this */
636 ZERO_STRUCT(info->audit_log);
638 case LSA_POLICY_INFO_AUDIT_EVENTS:
639 /* we don't need to fill in any of this */
640 ZERO_STRUCT(info->audit_events);
642 case LSA_POLICY_INFO_PD:
643 /* we don't need to fill in any of this */
644 ZERO_STRUCT(info->pd);
647 case LSA_POLICY_INFO_DOMAIN:
648 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
649 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
650 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
651 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
652 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
654 case LSA_POLICY_INFO_ROLE:
655 info->role.role = LSA_ROLE_PRIMARY;
658 case LSA_POLICY_INFO_DNS:
659 case LSA_POLICY_INFO_DNS_INT:
660 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
662 case LSA_POLICY_INFO_REPLICA:
663 ZERO_STRUCT(info->replica);
666 case LSA_POLICY_INFO_QUOTA:
667 ZERO_STRUCT(info->quota);
670 case LSA_POLICY_INFO_MOD:
671 case LSA_POLICY_INFO_AUDIT_FULL_SET:
672 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
673 /* windows gives INVALID_PARAMETER */
675 return NT_STATUS_INVALID_PARAMETER;
679 return NT_STATUS_INVALID_INFO_CLASS;
685 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
686 struct lsa_QueryInfoPolicy *r)
688 struct lsa_QueryInfoPolicy2 r2;
693 r2.in.handle = r->in.handle;
694 r2.in.level = r->in.level;
695 r2.out.info = r->out.info;
697 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
705 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
706 struct lsa_SetInfoPolicy *r)
708 /* need to support this */
709 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
716 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
717 struct lsa_ClearAuditLog *r)
719 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
723 static const struct generic_mapping dcesrv_lsa_account_mapping = {
727 LSA_ACCOUNT_ALL_ACCESS
733 This call does not seem to have any long-term effects, hence no database operations
735 we need to talk to the MS product group to find out what this account database means!
737 answer is that the lsa database is totally separate from the SAM and
738 ldap databases. We are going to need a separate ldb to store these
739 accounts. The SIDs on this account bear no relation to the SIDs in
742 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
743 struct lsa_CreateAccount *r)
745 struct lsa_account_state *astate;
747 struct lsa_policy_state *state;
748 struct dcesrv_handle *h, *ah;
750 ZERO_STRUCTP(r->out.acct_handle);
752 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
756 astate = talloc(dce_call->conn, struct lsa_account_state);
757 if (astate == NULL) {
758 return NT_STATUS_NO_MEMORY;
761 astate->account_sid = dom_sid_dup(astate, r->in.sid);
762 if (astate->account_sid == NULL) {
764 return NT_STATUS_NO_MEMORY;
767 astate->policy = talloc_reference(astate, state);
768 astate->access_mask = r->in.access_mask;
771 * For now we grant all requested access.
773 * We will fail at the ldb layer later.
775 if (astate->access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
776 astate->access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
777 astate->access_mask |= LSA_ACCOUNT_ALL_ACCESS;
779 se_map_generic(&astate->access_mask, &dcesrv_lsa_account_mapping);
781 DEBUG(10,("%s: %s access desired[0x%08X] granted[0x%08X].\n",
782 __func__, dom_sid_string(mem_ctx, astate->account_sid),
783 (unsigned)r->in.access_mask,
784 (unsigned)astate->access_mask));
786 ah = dcesrv_handle_create(dce_call, LSA_HANDLE_ACCOUNT);
789 return NT_STATUS_NO_MEMORY;
792 ah->data = talloc_steal(ah, astate);
794 *r->out.acct_handle = ah->wire_handle;
803 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
804 struct lsa_EnumAccounts *r)
806 struct dcesrv_handle *h;
807 struct lsa_policy_state *state;
809 struct ldb_message **res;
810 const char * const attrs[] = { "objectSid", NULL};
813 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
817 /* NOTE: This call must only return accounts that have at least
820 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
821 "(&(objectSid=*)(privilege=*))");
823 return NT_STATUS_INTERNAL_DB_CORRUPTION;
826 if (*r->in.resume_handle >= ret) {
827 return NT_STATUS_NO_MORE_ENTRIES;
830 count = ret - *r->in.resume_handle;
831 if (count > r->in.num_entries) {
832 count = r->in.num_entries;
836 return NT_STATUS_NO_MORE_ENTRIES;
839 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
840 if (r->out.sids->sids == NULL) {
841 return NT_STATUS_NO_MEMORY;
844 for (i=0;i<count;i++) {
845 r->out.sids->sids[i].sid =
846 samdb_result_dom_sid(r->out.sids->sids,
847 res[i + *r->in.resume_handle],
849 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
852 r->out.sids->num_sids = count;
853 *r->out.resume_handle = count + *r->in.resume_handle;
858 /* This decrypts and returns Trusted Domain Auth Information Internal data */
859 static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
860 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
861 struct trustDomainPasswords *auth_struct)
863 DATA_BLOB session_key = data_blob(NULL, 0);
864 enum ndr_err_code ndr_err;
867 nt_status = dcesrv_transport_session_key(dce_call, &session_key);
868 if (!NT_STATUS_IS_OK(nt_status)) {
872 arcfour_crypt_blob(auth_blob->data, auth_blob->length, &session_key);
873 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
875 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
876 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
877 return NT_STATUS_INVALID_PARAMETER;
883 static NTSTATUS get_trustauth_inout_blob(struct dcesrv_call_state *dce_call,
885 struct trustAuthInOutBlob *iopw,
886 DATA_BLOB *trustauth_blob)
888 enum ndr_err_code ndr_err;
890 if (iopw->current.count != iopw->count) {
891 return NT_STATUS_INVALID_PARAMETER;
894 if (iopw->previous.count > iopw->current.count) {
895 return NT_STATUS_INVALID_PARAMETER;
898 if (iopw->previous.count == 0) {
900 * If the previous credentials are not present
901 * we need to make a copy.
903 iopw->previous = iopw->current;
906 if (iopw->previous.count < iopw->current.count) {
907 struct AuthenticationInformationArray *c = &iopw->current;
908 struct AuthenticationInformationArray *p = &iopw->previous;
911 * The previous array needs to have the same size
912 * as the current one.
914 * We may have to fill with TRUST_AUTH_TYPE_NONE
917 p->array = talloc_realloc(mem_ctx, p->array,
918 struct AuthenticationInformation,
920 if (p->array == NULL) {
921 return NT_STATUS_NO_MEMORY;
924 while (p->count < c->count) {
925 struct AuthenticationInformation *a =
926 &p->array[p->count++];
928 *a = (struct AuthenticationInformation) {
929 .LastUpdateTime = p->array[0].LastUpdateTime,
930 .AuthType = TRUST_AUTH_TYPE_NONE,
935 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
937 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
938 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
939 return NT_STATUS_INVALID_PARAMETER;
945 static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx,
946 struct ldb_context *sam_ldb,
947 struct ldb_dn *base_dn,
948 const char *netbios_name,
949 struct trustAuthInOutBlob *in,
950 struct ldb_dn **user_dn)
952 struct ldb_request *req;
953 struct ldb_message *msg;
958 dn = ldb_dn_copy(mem_ctx, base_dn);
960 return NT_STATUS_NO_MEMORY;
962 if (!ldb_dn_add_child_fmt(dn, "cn=%s$,cn=users", netbios_name)) {
963 return NT_STATUS_NO_MEMORY;
966 msg = ldb_msg_new(mem_ctx);
968 return NT_STATUS_NO_MEMORY;
972 ret = ldb_msg_add_string(msg, "objectClass", "user");
973 if (ret != LDB_SUCCESS) {
974 return NT_STATUS_NO_MEMORY;
977 ret = ldb_msg_add_fmt(msg, "samAccountName", "%s$", netbios_name);
978 if (ret != LDB_SUCCESS) {
979 return NT_STATUS_NO_MEMORY;
982 ret = samdb_msg_add_uint(sam_ldb, msg, msg, "userAccountControl",
983 UF_INTERDOMAIN_TRUST_ACCOUNT);
984 if (ret != LDB_SUCCESS) {
985 return NT_STATUS_NO_MEMORY;
988 for (i = 0; i < in->count; i++) {
989 const char *attribute;
991 switch (in->current.array[i].AuthType) {
992 case TRUST_AUTH_TYPE_NT4OWF:
993 attribute = "unicodePwd";
994 v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
997 case TRUST_AUTH_TYPE_CLEAR:
998 attribute = "clearTextPassword";
999 v.data = in->current.array[i].AuthInfo.clear.password;
1000 v.length = in->current.array[i].AuthInfo.clear.size;
1006 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
1007 if (ret != LDB_SUCCESS) {
1008 return NT_STATUS_NO_MEMORY;
1012 /* create the trusted_domain user account */
1013 ret = ldb_build_add_req(&req, sam_ldb, mem_ctx, msg, NULL, NULL,
1014 ldb_op_default_callback, NULL);
1015 if (ret != LDB_SUCCESS) {
1016 return NT_STATUS_NO_MEMORY;
1019 ret = ldb_request_add_control(req, DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID,
1021 if (ret != LDB_SUCCESS) {
1022 return NT_STATUS_NO_MEMORY;
1025 ret = dsdb_autotransaction_request(sam_ldb, req);
1026 if (ret != LDB_SUCCESS) {
1027 DEBUG(0,("Failed to create user record %s: %s\n",
1028 ldb_dn_get_linearized(msg->dn),
1029 ldb_errstring(sam_ldb)));
1032 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1033 return NT_STATUS_DOMAIN_EXISTS;
1034 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1035 return NT_STATUS_ACCESS_DENIED;
1037 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1044 return NT_STATUS_OK;
1048 lsa_CreateTrustedDomainEx2
1050 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
1051 TALLOC_CTX *mem_ctx,
1052 struct lsa_CreateTrustedDomainEx2 *r,
1054 struct lsa_TrustDomainInfoAuthInfo *unencrypted_auth_info)
1056 struct dcesrv_handle *policy_handle;
1057 struct lsa_policy_state *policy_state;
1058 struct lsa_trusted_domain_state *trusted_domain_state;
1059 struct dcesrv_handle *handle;
1060 struct ldb_message **msgs, *msg;
1061 const char *attrs[] = {
1064 const char *netbios_name;
1065 const char *dns_name;
1066 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
1067 struct trustDomainPasswords auth_struct;
1070 struct ldb_context *sam_ldb;
1071 struct server_id *server_ids = NULL;
1072 uint32_t num_server_ids = 0;
1075 char *dns_encoded = NULL;
1076 char *netbios_encoded = NULL;
1077 char *sid_encoded = NULL;
1079 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
1080 ZERO_STRUCTP(r->out.trustdom_handle);
1082 policy_state = policy_handle->data;
1083 sam_ldb = policy_state->sam_ldb;
1085 netbios_name = r->in.info->netbios_name.string;
1086 if (!netbios_name) {
1087 return NT_STATUS_INVALID_PARAMETER;
1090 dns_name = r->in.info->domain_name.string;
1091 if (dns_name == NULL) {
1092 return NT_STATUS_INVALID_PARAMETER;
1095 if (r->in.info->sid == NULL) {
1096 return NT_STATUS_INVALID_SID;
1100 * We expect S-1-5-21-A-B-C, but we don't
1101 * allow S-1-5-21-0-0-0 as this is used
1102 * for claims and compound identities.
1104 ok = dom_sid_is_valid_account_domain(r->in.info->sid);
1106 return NT_STATUS_INVALID_PARAMETER;
1109 dns_encoded = ldb_binary_encode_string(mem_ctx, dns_name);
1110 if (dns_encoded == NULL) {
1111 return NT_STATUS_NO_MEMORY;
1113 netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
1114 if (netbios_encoded == NULL) {
1115 return NT_STATUS_NO_MEMORY;
1117 sid_encoded = ldap_encode_ndr_dom_sid(mem_ctx, r->in.info->sid);
1118 if (sid_encoded == NULL) {
1119 return NT_STATUS_NO_MEMORY;
1122 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1123 if (!trusted_domain_state) {
1124 return NT_STATUS_NO_MEMORY;
1126 trusted_domain_state->policy = policy_state;
1128 if (strcasecmp(netbios_name, "BUILTIN") == 0
1129 || (strcasecmp(dns_name, "BUILTIN") == 0)
1130 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
1131 return NT_STATUS_INVALID_PARAMETER;
1134 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
1135 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
1136 || strcasecmp(dns_name, policy_state->domain_dns) == 0
1137 || strcasecmp(dns_name, policy_state->domain_name) == 0
1138 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
1139 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
1142 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
1143 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
1144 /* No secrets are created at this time, for this function */
1145 auth_struct.outgoing.count = 0;
1146 auth_struct.incoming.count = 0;
1147 } else if (op == NDR_LSA_CREATETRUSTEDDOMAINEX2) {
1148 auth_blob = data_blob_const(r->in.auth_info_internal->auth_blob.data,
1149 r->in.auth_info_internal->auth_blob.size);
1150 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
1151 &auth_blob, &auth_struct);
1152 if (!NT_STATUS_IS_OK(nt_status)) {
1155 } else if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
1157 if (unencrypted_auth_info->incoming_count > 1) {
1158 return NT_STATUS_INVALID_PARAMETER;
1161 /* more investigation required here, do not create secrets for
1163 auth_struct.outgoing.count = 0;
1164 auth_struct.incoming.count = 0;
1166 return NT_STATUS_INVALID_PARAMETER;
1169 if (auth_struct.incoming.count) {
1170 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1171 &auth_struct.incoming,
1172 &trustAuthIncoming);
1173 if (!NT_STATUS_IS_OK(nt_status)) {
1177 trustAuthIncoming = data_blob(NULL, 0);
1180 if (auth_struct.outgoing.count) {
1181 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1182 &auth_struct.outgoing,
1183 &trustAuthOutgoing);
1184 if (!NT_STATUS_IS_OK(nt_status)) {
1188 trustAuthOutgoing = data_blob(NULL, 0);
1191 ret = ldb_transaction_start(sam_ldb);
1192 if (ret != LDB_SUCCESS) {
1193 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1196 /* search for the trusted_domain record */
1197 ret = gendb_search(sam_ldb,
1198 mem_ctx, policy_state->system_dn, &msgs, attrs,
1199 "(&(objectClass=trustedDomain)(|"
1200 "(flatname=%s)(trustPartner=%s)"
1201 "(flatname=%s)(trustPartner=%s)"
1202 "(securityIdentifier=%s)))",
1203 dns_encoded, dns_encoded,
1204 netbios_encoded, netbios_encoded,
1207 ldb_transaction_cancel(sam_ldb);
1208 return NT_STATUS_OBJECT_NAME_COLLISION;
1211 ldb_transaction_cancel(sam_ldb);
1212 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1215 msg = ldb_msg_new(mem_ctx);
1217 return NT_STATUS_NO_MEMORY;
1220 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1221 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", dns_name)) {
1222 ldb_transaction_cancel(sam_ldb);
1223 return NT_STATUS_NO_MEMORY;
1226 ret = ldb_msg_add_string(msg, "objectClass", "trustedDomain");
1227 if (ret != LDB_SUCCESS) {
1228 ldb_transaction_cancel(sam_ldb);
1229 return NT_STATUS_NO_MEMORY;;
1232 ret = ldb_msg_add_string(msg, "flatname", netbios_name);
1233 if (ret != LDB_SUCCESS) {
1234 ldb_transaction_cancel(sam_ldb);
1235 return NT_STATUS_NO_MEMORY;
1238 ret = ldb_msg_add_string(msg, "trustPartner", dns_name);
1239 if (ret != LDB_SUCCESS) {
1240 ldb_transaction_cancel(sam_ldb);
1241 return NT_STATUS_NO_MEMORY;;
1244 ret = samdb_msg_add_dom_sid(sam_ldb, mem_ctx, msg, "securityIdentifier",
1246 if (ret != LDB_SUCCESS) {
1247 ldb_transaction_cancel(sam_ldb);
1248 return NT_STATUS_NO_MEMORY;;
1251 ret = samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
1252 if (ret != LDB_SUCCESS) {
1253 ldb_transaction_cancel(sam_ldb);
1254 return NT_STATUS_NO_MEMORY;;
1257 ret = samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
1258 if (ret != LDB_SUCCESS) {
1259 ldb_transaction_cancel(sam_ldb);
1260 return NT_STATUS_NO_MEMORY;;
1263 ret = samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
1264 if (ret != LDB_SUCCESS) {
1265 ldb_transaction_cancel(sam_ldb);
1266 return NT_STATUS_NO_MEMORY;;
1269 if (trustAuthIncoming.data) {
1270 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
1271 if (ret != LDB_SUCCESS) {
1272 ldb_transaction_cancel(sam_ldb);
1273 return NT_STATUS_NO_MEMORY;
1276 if (trustAuthOutgoing.data) {
1277 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
1278 if (ret != LDB_SUCCESS) {
1279 ldb_transaction_cancel(sam_ldb);
1280 return NT_STATUS_NO_MEMORY;
1284 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
1286 /* create the trusted_domain */
1287 ret = ldb_add(sam_ldb, msg);
1291 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1292 ldb_transaction_cancel(sam_ldb);
1293 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1294 ldb_dn_get_linearized(msg->dn),
1295 ldb_errstring(sam_ldb)));
1296 return NT_STATUS_DOMAIN_EXISTS;
1297 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1298 ldb_transaction_cancel(sam_ldb);
1299 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1300 ldb_dn_get_linearized(msg->dn),
1301 ldb_errstring(sam_ldb)));
1302 return NT_STATUS_ACCESS_DENIED;
1304 ldb_transaction_cancel(sam_ldb);
1305 DEBUG(0,("Failed to create user record %s: %s\n",
1306 ldb_dn_get_linearized(msg->dn),
1307 ldb_errstring(sam_ldb)));
1308 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1311 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1312 struct ldb_dn *user_dn;
1313 /* Inbound trusts must also create a cn=users object to match */
1314 nt_status = add_trust_user(mem_ctx, sam_ldb,
1315 policy_state->domain_dn,
1317 &auth_struct.incoming,
1319 if (!NT_STATUS_IS_OK(nt_status)) {
1320 ldb_transaction_cancel(sam_ldb);
1324 /* save the trust user dn */
1325 trusted_domain_state->trusted_domain_user_dn
1326 = talloc_steal(trusted_domain_state, user_dn);
1329 ret = ldb_transaction_commit(sam_ldb);
1330 if (ret != LDB_SUCCESS) {
1331 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1335 * Notify winbindd that we have a new trust
1337 status = irpc_servers_byname(dce_call->msg_ctx,
1340 &num_server_ids, &server_ids);
1341 if (NT_STATUS_IS_OK(status) && num_server_ids >= 1) {
1342 imessaging_send(dce_call->msg_ctx, server_ids[0],
1343 MSG_WINBIND_RELOAD_TRUSTED_DOMAINS, NULL);
1345 TALLOC_FREE(server_ids);
1347 handle = dcesrv_handle_create(dce_call, LSA_HANDLE_TRUSTED_DOMAIN);
1349 return NT_STATUS_NO_MEMORY;
1352 handle->data = talloc_steal(handle, trusted_domain_state);
1354 trusted_domain_state->access_mask = r->in.access_mask;
1355 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1357 *r->out.trustdom_handle = handle->wire_handle;
1359 return NT_STATUS_OK;
1363 lsa_CreateTrustedDomainEx2
1365 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1366 TALLOC_CTX *mem_ctx,
1367 struct lsa_CreateTrustedDomainEx2 *r)
1369 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2, NULL);
1372 lsa_CreateTrustedDomainEx
1374 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1375 TALLOC_CTX *mem_ctx,
1376 struct lsa_CreateTrustedDomainEx *r)
1378 struct lsa_CreateTrustedDomainEx2 r2;
1380 r2.in.policy_handle = r->in.policy_handle;
1381 r2.in.info = r->in.info;
1382 r2.out.trustdom_handle = r->out.trustdom_handle;
1383 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX, r->in.auth_info);
1387 lsa_CreateTrustedDomain
1389 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1390 struct lsa_CreateTrustedDomain *r)
1392 struct lsa_CreateTrustedDomainEx2 r2;
1394 r2.in.policy_handle = r->in.policy_handle;
1395 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1397 return NT_STATUS_NO_MEMORY;
1400 r2.in.info->domain_name = r->in.info->name;
1401 r2.in.info->netbios_name = r->in.info->name;
1402 r2.in.info->sid = r->in.info->sid;
1403 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1404 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1405 r2.in.info->trust_attributes = 0;
1407 r2.in.access_mask = r->in.access_mask;
1408 r2.out.trustdom_handle = r->out.trustdom_handle;
1410 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN, NULL);
1413 static NTSTATUS dcesrv_lsa_OpenTrustedDomain_common(
1414 struct dcesrv_call_state *dce_call,
1415 TALLOC_CTX *tmp_mem,
1416 struct lsa_policy_state *policy_state,
1418 uint32_t access_mask,
1419 struct dcesrv_handle **_handle)
1421 struct lsa_trusted_domain_state *trusted_domain_state;
1422 struct dcesrv_handle *handle;
1423 struct ldb_message **msgs;
1424 const char *attrs[] = {
1432 /* TODO: perform access checks */
1434 /* search for the trusted_domain record */
1435 ret = gendb_search(policy_state->sam_ldb, tmp_mem,
1436 policy_state->system_dn,
1437 &msgs, attrs, "%s", filter);
1439 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1443 DEBUG(0,("Found %d records matching %s under %s\n", ret,
1445 ldb_dn_get_linearized(policy_state->system_dn)));
1446 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1449 trusted_domain_state = talloc_zero(tmp_mem,
1450 struct lsa_trusted_domain_state);
1451 if (!trusted_domain_state) {
1452 return NT_STATUS_NO_MEMORY;
1454 trusted_domain_state->policy = policy_state;
1456 trusted_domain_state->trusted_domain_dn =
1457 talloc_steal(trusted_domain_state, msgs[0]->dn);
1459 direction = ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0);
1460 if (direction & LSA_TRUST_DIRECTION_INBOUND) {
1461 const char *flatname = ldb_msg_find_attr_as_string(msgs[0],
1464 /* search for the trusted_domain account */
1465 ret = gendb_search(policy_state->sam_ldb, tmp_mem,
1466 policy_state->domain_dn,
1468 "(&(samaccountname=%s$)(objectclass=user)"
1469 "(userAccountControl:%s:=%u))",
1471 LDB_OID_COMPARATOR_AND,
1472 UF_INTERDOMAIN_TRUST_ACCOUNT);
1474 trusted_domain_state->trusted_domain_user_dn =
1475 talloc_steal(trusted_domain_state, msgs[0]->dn);
1479 handle = dcesrv_handle_create(dce_call, LSA_HANDLE_TRUSTED_DOMAIN);
1481 return NT_STATUS_NO_MEMORY;
1484 handle->data = talloc_steal(handle, trusted_domain_state);
1486 trusted_domain_state->access_mask = access_mask;
1487 trusted_domain_state->policy = talloc_reference(trusted_domain_state,
1492 return NT_STATUS_OK;
1496 lsa_OpenTrustedDomain
1498 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1499 struct lsa_OpenTrustedDomain *r)
1501 struct dcesrv_handle *policy_handle;
1502 struct lsa_policy_state *policy_state;
1503 struct dcesrv_handle *handle;
1504 const char *sid_string;
1508 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1509 ZERO_STRUCTP(r->out.trustdom_handle);
1510 policy_state = policy_handle->data;
1512 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1514 return NT_STATUS_NO_MEMORY;
1517 filter = talloc_asprintf(mem_ctx,
1518 "(&(securityIdentifier=%s)"
1519 "(objectclass=trustedDomain))",
1521 if (filter == NULL) {
1522 return NT_STATUS_NO_MEMORY;
1525 status = dcesrv_lsa_OpenTrustedDomain_common(dce_call, mem_ctx,
1530 if (!NT_STATUS_IS_OK(status)) {
1534 *r->out.trustdom_handle = handle->wire_handle;
1536 return NT_STATUS_OK;
1541 lsa_OpenTrustedDomainByName
1543 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1544 TALLOC_CTX *mem_ctx,
1545 struct lsa_OpenTrustedDomainByName *r)
1547 struct dcesrv_handle *policy_handle;
1548 struct lsa_policy_state *policy_state;
1549 struct dcesrv_handle *handle;
1554 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1555 ZERO_STRUCTP(r->out.trustdom_handle);
1556 policy_state = policy_handle->data;
1558 if (!r->in.name.string) {
1559 return NT_STATUS_INVALID_PARAMETER;
1562 /* search for the trusted_domain record */
1563 td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string);
1564 if (td_name == NULL) {
1565 return NT_STATUS_NO_MEMORY;
1568 filter = talloc_asprintf(mem_ctx,
1569 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))"
1570 "(objectclass=trustedDomain))",
1571 td_name, td_name, td_name);
1572 if (filter == NULL) {
1573 return NT_STATUS_NO_MEMORY;
1576 status = dcesrv_lsa_OpenTrustedDomain_common(dce_call, mem_ctx,
1581 if (!NT_STATUS_IS_OK(status)) {
1585 *r->out.trustdom_handle = handle->wire_handle;
1587 return NT_STATUS_OK;
1593 lsa_SetTrustedDomainInfo
1595 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1596 struct lsa_SetTrustedDomainInfo *r)
1598 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1603 /* parameters 4 to 6 are optional if the dn is a dn of a TDO object,
1604 * otherwise at least one must be provided */
1605 static NTSTATUS get_tdo(struct ldb_context *sam, TALLOC_CTX *mem_ctx,
1606 struct ldb_dn *basedn, const char *dns_domain,
1607 const char *netbios, struct dom_sid2 *sid,
1608 struct ldb_message ***msgs)
1610 const char *attrs[] = { "flatname", "trustPartner",
1611 "securityIdentifier", "trustDirection",
1612 "trustType", "trustAttributes",
1614 "msDs-supportedEncryptionTypes",
1615 "msDS-TrustForestTrustInfo",
1620 char *sidstr = NULL;
1625 if (dns_domain || netbios || sid) {
1626 filter = talloc_strdup(mem_ctx,
1627 "(&(objectclass=trustedDomain)(|");
1629 filter = talloc_strdup(mem_ctx,
1630 "(objectclass=trustedDomain)");
1633 return NT_STATUS_NO_MEMORY;
1637 dns = ldb_binary_encode_string(mem_ctx, dns_domain);
1639 return NT_STATUS_NO_MEMORY;
1641 filter = talloc_asprintf_append(filter,
1642 "(trustPartner=%s)", dns);
1644 return NT_STATUS_NO_MEMORY;
1648 nbn = ldb_binary_encode_string(mem_ctx, netbios);
1650 return NT_STATUS_NO_MEMORY;
1652 filter = talloc_asprintf_append(filter,
1653 "(flatname=%s)", nbn);
1655 return NT_STATUS_NO_MEMORY;
1659 sidstr = dom_sid_string(mem_ctx, sid);
1661 return NT_STATUS_INVALID_PARAMETER;
1663 filter = talloc_asprintf_append(filter,
1664 "(securityIdentifier=%s)",
1667 return NT_STATUS_NO_MEMORY;
1670 if (dns_domain || netbios || sid) {
1671 filter = talloc_asprintf_append(filter, "))");
1673 return NT_STATUS_NO_MEMORY;
1677 ret = gendb_search(sam, mem_ctx, basedn, msgs, attrs, "%s", filter);
1679 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1683 return NT_STATUS_OBJECT_NAME_COLLISION;
1686 return NT_STATUS_OK;
1689 static NTSTATUS update_uint32_t_value(TALLOC_CTX *mem_ctx,
1690 struct ldb_context *sam_ldb,
1691 struct ldb_message *orig,
1692 struct ldb_message *dest,
1693 const char *attribute,
1695 uint32_t *orig_value)
1697 const struct ldb_val *orig_val;
1698 uint32_t orig_uint = 0;
1699 unsigned int flags = 0;
1703 orig_val = ldb_msg_find_ldb_val(orig, attribute);
1704 if (!orig_val || !orig_val->data) {
1705 /* add new attribute */
1706 flags = LDB_FLAG_MOD_ADD;
1709 orig_uint = strtoul_err((const char *)orig_val->data,
1713 if (error != 0 || orig_uint != value) {
1714 /* replace also if can't get value */
1715 flags = LDB_FLAG_MOD_REPLACE;
1720 /* stored value is identical, nothing to change */
1724 ret = ldb_msg_add_empty(dest, attribute, flags, NULL);
1725 if (ret != LDB_SUCCESS) {
1726 return NT_STATUS_NO_MEMORY;
1729 ret = samdb_msg_add_uint(sam_ldb, dest, dest, attribute, value);
1730 if (ret != LDB_SUCCESS) {
1731 return NT_STATUS_NO_MEMORY;
1736 *orig_value = orig_uint;
1738 return NT_STATUS_OK;
1741 static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx,
1742 struct ldb_context *sam_ldb,
1743 struct ldb_dn *base_dn,
1745 const char *netbios_name,
1746 struct trustAuthInOutBlob *in)
1748 const char *attrs[] = { "userAccountControl", NULL };
1749 struct ldb_message **msgs;
1750 struct ldb_message *msg;
1755 ret = gendb_search(sam_ldb, mem_ctx,
1756 base_dn, &msgs, attrs,
1757 "samAccountName=%s$", netbios_name);
1759 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1764 return NT_STATUS_OK;
1767 /* ok no existing user, add it from scratch */
1768 return add_trust_user(mem_ctx, sam_ldb, base_dn,
1769 netbios_name, in, NULL);
1772 /* check user is what we are looking for */
1773 uac = ldb_msg_find_attr_as_uint(msgs[0],
1774 "userAccountControl", 0);
1775 if (!(uac & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
1776 return NT_STATUS_OBJECT_NAME_COLLISION;
1780 ret = ldb_delete(sam_ldb, msgs[0]->dn);
1783 return NT_STATUS_OK;
1784 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1785 return NT_STATUS_ACCESS_DENIED;
1787 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1791 /* entry exists, just modify secret if any */
1792 if (in == NULL || in->count == 0) {
1793 return NT_STATUS_OK;
1796 msg = ldb_msg_new(mem_ctx);
1798 return NT_STATUS_NO_MEMORY;
1800 msg->dn = msgs[0]->dn;
1802 for (i = 0; i < in->count; i++) {
1803 const char *attribute;
1805 switch (in->current.array[i].AuthType) {
1806 case TRUST_AUTH_TYPE_NT4OWF:
1807 attribute = "unicodePwd";
1808 v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
1811 case TRUST_AUTH_TYPE_CLEAR:
1812 attribute = "clearTextPassword";
1813 v.data = in->current.array[i].AuthInfo.clear.password;
1814 v.length = in->current.array[i].AuthInfo.clear.size;
1820 ret = ldb_msg_add_empty(msg, attribute,
1821 LDB_FLAG_MOD_REPLACE, NULL);
1822 if (ret != LDB_SUCCESS) {
1823 return NT_STATUS_NO_MEMORY;
1826 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
1827 if (ret != LDB_SUCCESS) {
1828 return NT_STATUS_NO_MEMORY;
1832 /* create the trusted_domain user account */
1833 ret = ldb_modify(sam_ldb, msg);
1834 if (ret != LDB_SUCCESS) {
1835 DEBUG(0,("Failed to create user record %s: %s\n",
1836 ldb_dn_get_linearized(msg->dn),
1837 ldb_errstring(sam_ldb)));
1840 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1841 return NT_STATUS_DOMAIN_EXISTS;
1842 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1843 return NT_STATUS_ACCESS_DENIED;
1845 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1849 return NT_STATUS_OK;
1853 static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call,
1854 struct lsa_policy_state *p_state,
1855 TALLOC_CTX *mem_ctx,
1856 struct ldb_message *dom_msg,
1857 enum lsa_TrustDomInfoEnum level,
1858 union lsa_TrustedDomainInfo *info)
1860 uint32_t *posix_offset = NULL;
1861 struct lsa_TrustDomainInfoInfoEx *info_ex = NULL;
1862 struct lsa_TrustDomainInfoAuthInfo *auth_info = NULL;
1863 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
1864 uint32_t *enc_types = NULL;
1865 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
1866 struct trustDomainPasswords auth_struct;
1867 struct trustAuthInOutBlob *current_passwords = NULL;
1869 struct ldb_message **msgs;
1870 struct ldb_message *msg;
1871 bool add_outgoing = false;
1872 bool add_incoming = false;
1873 bool del_outgoing = false;
1874 bool del_incoming = false;
1875 bool del_forest_info = false;
1876 bool in_transaction = false;
1881 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1882 posix_offset = &info->posix_offset.posix_offset;
1884 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1885 info_ex = &info->info_ex;
1887 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1888 auth_info = &info->auth_info;
1890 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1891 posix_offset = &info->full_info.posix_offset.posix_offset;
1892 info_ex = &info->full_info.info_ex;
1893 auth_info = &info->full_info.auth_info;
1895 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1896 auth_info_int = &info->auth_info_internal;
1898 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1899 posix_offset = &info->full_info_internal.posix_offset.posix_offset;
1900 info_ex = &info->full_info_internal.info_ex;
1901 auth_info_int = &info->full_info_internal.auth_info;
1903 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1904 enc_types = &info->enc_types.enc_types;
1907 return NT_STATUS_INVALID_PARAMETER;
1911 nt_status = auth_info_2_auth_blob(mem_ctx, auth_info,
1913 &trustAuthOutgoing);
1914 if (!NT_STATUS_IS_OK(nt_status)) {
1917 if (trustAuthIncoming.data) {
1918 /* This does the decode of some of this twice, but it is easier that way */
1919 nt_status = auth_info_2_trustauth_inout(mem_ctx,
1920 auth_info->incoming_count,
1921 auth_info->incoming_current_auth_info,
1923 ¤t_passwords);
1924 if (!NT_STATUS_IS_OK(nt_status)) {
1930 /* decode auth_info_int if set */
1931 if (auth_info_int) {
1933 /* now decrypt blob */
1934 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
1935 auth_info_int->auth_blob.size);
1937 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
1938 &auth_blob, &auth_struct);
1939 if (!NT_STATUS_IS_OK(nt_status)) {
1945 /* verify data matches */
1946 if (info_ex->trust_attributes &
1947 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1948 /* TODO: check what behavior level we have */
1949 if (strcasecmp_m(p_state->domain_dns,
1950 p_state->forest_dns) != 0) {
1951 return NT_STATUS_INVALID_DOMAIN_STATE;
1955 ret = samdb_rodc(p_state->sam_ldb, &am_rodc);
1956 if (ret == LDB_SUCCESS && am_rodc) {
1957 return NT_STATUS_NO_SUCH_DOMAIN;
1960 /* verify only one object matches the dns/netbios/sid
1961 * triplet and that this is the one we already have */
1962 nt_status = get_tdo(p_state->sam_ldb, mem_ctx,
1964 info_ex->domain_name.string,
1965 info_ex->netbios_name.string,
1966 info_ex->sid, &msgs);
1967 if (!NT_STATUS_IS_OK(nt_status)) {
1970 if (ldb_dn_compare(dom_msg->dn, msgs[0]->dn) != 0) {
1971 return NT_STATUS_OBJECT_NAME_COLLISION;
1976 /* TODO: should we fetch previous values from the existing entry
1977 * and append them ? */
1978 if (auth_info_int && auth_struct.incoming.count) {
1979 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1980 &auth_struct.incoming,
1981 &trustAuthIncoming);
1982 if (!NT_STATUS_IS_OK(nt_status)) {
1986 current_passwords = &auth_struct.incoming;
1989 trustAuthIncoming = data_blob(NULL, 0);
1992 if (auth_info_int && auth_struct.outgoing.count) {
1993 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1994 &auth_struct.outgoing,
1995 &trustAuthOutgoing);
1996 if (!NT_STATUS_IS_OK(nt_status)) {
2000 trustAuthOutgoing = data_blob(NULL, 0);
2003 msg = ldb_msg_new(mem_ctx);
2005 return NT_STATUS_NO_MEMORY;
2007 msg->dn = dom_msg->dn;
2010 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2013 *posix_offset, NULL);
2014 if (!NT_STATUS_IS_OK(nt_status)) {
2021 uint32_t changed_attrs;
2025 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2028 info_ex->trust_direction,
2030 if (!NT_STATUS_IS_OK(nt_status)) {
2034 if (info_ex->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
2035 if (auth_info != NULL && trustAuthIncoming.length > 0) {
2036 add_incoming = true;
2039 if (info_ex->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) {
2040 if (auth_info != NULL && trustAuthOutgoing.length > 0) {
2041 add_outgoing = true;
2045 if ((origdir & LSA_TRUST_DIRECTION_INBOUND) &&
2046 !(info_ex->trust_direction & LSA_TRUST_DIRECTION_INBOUND)) {
2047 del_incoming = true;
2049 if ((origdir & LSA_TRUST_DIRECTION_OUTBOUND) &&
2050 !(info_ex->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND)) {
2051 del_outgoing = true;
2054 origtype = ldb_msg_find_attr_as_int(dom_msg, "trustType", -1);
2055 if (origtype == -1 || origtype != info_ex->trust_type) {
2056 DEBUG(1, ("Attempted to change trust type! "
2057 "Operation not handled\n"));
2058 return NT_STATUS_INVALID_PARAMETER;
2061 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2064 info_ex->trust_attributes,
2066 if (!NT_STATUS_IS_OK(nt_status)) {
2069 /* TODO: check forestFunctionality from ldb opaque */
2070 /* TODO: check what is set makes sense */
2072 changed_attrs = origattrs ^ info_ex->trust_attributes;
2073 if (changed_attrs & ~LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2075 * For now we only allow
2076 * LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE to be changed.
2078 * TODO: we may need to support more attribute changes
2080 DEBUG(1, ("Attempted to change trust attributes "
2081 "(0x%08x != 0x%08x)! "
2082 "Operation not handled yet...\n",
2083 (unsigned)origattrs,
2084 (unsigned)info_ex->trust_attributes));
2085 return NT_STATUS_INVALID_PARAMETER;
2088 if (!(info_ex->trust_attributes &
2089 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE))
2091 struct ldb_message_element *orig_forest_el = NULL;
2093 orig_forest_el = ldb_msg_find_element(dom_msg,
2094 "msDS-TrustForestTrustInfo");
2095 if (orig_forest_el != NULL) {
2096 del_forest_info = true;
2102 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2104 "msDS-SupportedEncryptionTypes",
2106 if (!NT_STATUS_IS_OK(nt_status)) {
2111 if (add_incoming || del_incoming) {
2112 ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
2113 LDB_FLAG_MOD_REPLACE, NULL);
2114 if (ret != LDB_SUCCESS) {
2115 return NT_STATUS_NO_MEMORY;
2118 ret = ldb_msg_add_value(msg, "trustAuthIncoming",
2119 &trustAuthIncoming, NULL);
2120 if (ret != LDB_SUCCESS) {
2121 return NT_STATUS_NO_MEMORY;
2125 if (add_outgoing || del_outgoing) {
2126 ret = ldb_msg_add_empty(msg, "trustAuthOutgoing",
2127 LDB_FLAG_MOD_REPLACE, NULL);
2128 if (ret != LDB_SUCCESS) {
2129 return NT_STATUS_NO_MEMORY;
2132 ret = ldb_msg_add_value(msg, "trustAuthOutgoing",
2133 &trustAuthOutgoing, NULL);
2134 if (ret != LDB_SUCCESS) {
2135 return NT_STATUS_NO_MEMORY;
2139 if (del_forest_info) {
2140 ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo",
2141 LDB_FLAG_MOD_REPLACE, NULL);
2142 if (ret != LDB_SUCCESS) {
2143 return NT_STATUS_NO_MEMORY;
2147 /* start transaction */
2148 ret = ldb_transaction_start(p_state->sam_ldb);
2149 if (ret != LDB_SUCCESS) {
2150 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2152 in_transaction = true;
2154 if (msg->num_elements) {
2155 ret = ldb_modify(p_state->sam_ldb, msg);
2156 if (ret != LDB_SUCCESS) {
2157 DEBUG(1,("Failed to modify trusted domain record %s: %s\n",
2158 ldb_dn_get_linearized(msg->dn),
2159 ldb_errstring(p_state->sam_ldb)));
2160 nt_status = dsdb_ldb_err_to_ntstatus(ret);
2165 if (add_incoming || del_incoming) {
2166 const char *netbios_name;
2168 netbios_name = ldb_msg_find_attr_as_string(dom_msg,
2170 if (!netbios_name) {
2171 nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
2175 /* We use trustAuthIncoming.data to incidate that auth_struct.incoming is valid */
2176 nt_status = update_trust_user(mem_ctx,
2182 if (!NT_STATUS_IS_OK(nt_status)) {
2187 /* ok, all fine, commit transaction and return */
2188 ret = ldb_transaction_commit(p_state->sam_ldb);
2189 if (ret != LDB_SUCCESS) {
2190 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2192 in_transaction = false;
2194 nt_status = NT_STATUS_OK;
2197 if (in_transaction) {
2198 ldb_transaction_cancel(p_state->sam_ldb);
2204 lsa_SetInfomrationTrustedDomain
2206 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(
2207 struct dcesrv_call_state *dce_call,
2208 TALLOC_CTX *mem_ctx,
2209 struct lsa_SetInformationTrustedDomain *r)
2211 struct dcesrv_handle *h;
2212 struct lsa_trusted_domain_state *td_state;
2213 struct ldb_message **msgs;
2216 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle,
2217 LSA_HANDLE_TRUSTED_DOMAIN);
2219 td_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
2221 /* get the trusted domain object */
2222 nt_status = get_tdo(td_state->policy->sam_ldb, mem_ctx,
2223 td_state->trusted_domain_dn,
2224 NULL, NULL, NULL, &msgs);
2225 if (!NT_STATUS_IS_OK(nt_status)) {
2226 if (NT_STATUS_EQUAL(nt_status,
2227 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2230 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2233 return setInfoTrustedDomain_base(dce_call, td_state->policy, mem_ctx,
2234 msgs[0], r->in.level, r->in.info);
2239 lsa_DeleteTrustedDomain
2241 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2242 struct lsa_DeleteTrustedDomain *r)
2245 struct lsa_OpenTrustedDomain opn = {{0},{0}};
2246 struct lsa_DeleteObject del;
2247 struct dcesrv_handle *h;
2249 opn.in.handle = r->in.handle;
2250 opn.in.sid = r->in.dom_sid;
2251 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2252 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2253 if (!opn.out.trustdom_handle) {
2254 return NT_STATUS_NO_MEMORY;
2256 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
2257 if (!NT_STATUS_IS_OK(status)) {
2261 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2262 talloc_steal(mem_ctx, h);
2264 del.in.handle = opn.out.trustdom_handle;
2265 del.out.handle = opn.out.trustdom_handle;
2266 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
2267 if (!NT_STATUS_IS_OK(status)) {
2270 return NT_STATUS_OK;
2273 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
2274 struct ldb_message *msg,
2275 struct lsa_TrustDomainInfoInfoEx *info_ex)
2277 info_ex->domain_name.string
2278 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
2279 info_ex->netbios_name.string
2280 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2282 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
2283 info_ex->trust_direction
2284 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
2286 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
2287 info_ex->trust_attributes
2288 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
2289 return NT_STATUS_OK;
2293 lsa_QueryTrustedDomainInfo
2295 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2296 struct lsa_QueryTrustedDomainInfo *r)
2298 union lsa_TrustedDomainInfo *info = NULL;
2299 struct dcesrv_handle *h;
2300 struct lsa_trusted_domain_state *trusted_domain_state;
2301 struct ldb_message *msg;
2303 struct ldb_message **res;
2304 const char *attrs[] = {
2307 "securityIdentifier",
2311 "msDs-supportedEncryptionTypes",
2315 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
2317 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
2319 /* pull all the user attributes */
2320 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
2321 trusted_domain_state->trusted_domain_dn, &res, attrs);
2323 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2327 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
2329 return NT_STATUS_NO_MEMORY;
2331 *r->out.info = info;
2333 switch (r->in.level) {
2334 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2335 info->name.netbios_name.string
2336 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2338 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2339 info->posix_offset.posix_offset
2340 = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
2342 #if 0 /* Win2k3 doesn't implement this */
2343 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2344 r->out.info->info_basic.netbios_name.string
2345 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2346 r->out.info->info_basic.sid
2347 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
2350 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2351 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
2353 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2354 ZERO_STRUCT(info->full_info);
2355 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
2356 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2357 ZERO_STRUCT(info->full_info2_internal);
2358 info->full_info2_internal.posix_offset.posix_offset
2359 = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
2360 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
2362 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2363 info->enc_types.enc_types
2364 = ldb_msg_find_attr_as_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
2367 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2368 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2369 /* oops, we don't want to return the info after all */
2371 *r->out.info = NULL;
2372 return NT_STATUS_INVALID_PARAMETER;
2374 /* oops, we don't want to return the info after all */
2376 *r->out.info = NULL;
2377 return NT_STATUS_INVALID_INFO_CLASS;
2380 return NT_STATUS_OK;
2385 lsa_QueryTrustedDomainInfoBySid
2387 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2388 struct lsa_QueryTrustedDomainInfoBySid *r)
2391 struct lsa_OpenTrustedDomain opn = {{0},{0}};
2392 struct lsa_QueryTrustedDomainInfo query;
2393 struct dcesrv_handle *h;
2395 opn.in.handle = r->in.handle;
2396 opn.in.sid = r->in.dom_sid;
2397 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2398 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2399 if (!opn.out.trustdom_handle) {
2400 return NT_STATUS_NO_MEMORY;
2402 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
2403 if (!NT_STATUS_IS_OK(status)) {
2407 /* Ensure this handle goes away at the end of this call */
2408 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2409 talloc_steal(mem_ctx, h);
2411 query.in.trustdom_handle = opn.out.trustdom_handle;
2412 query.in.level = r->in.level;
2413 query.out.info = r->out.info;
2414 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2415 if (!NT_STATUS_IS_OK(status)) {
2419 return NT_STATUS_OK;
2423 lsa_SetTrustedDomainInfoByName
2425 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2426 TALLOC_CTX *mem_ctx,
2427 struct lsa_SetTrustedDomainInfoByName *r)
2429 struct dcesrv_handle *policy_handle;
2430 struct lsa_policy_state *policy_state;
2431 struct ldb_message **msgs;
2434 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2435 policy_state = policy_handle->data;
2437 /* get the trusted domain object */
2438 nt_status = get_tdo(policy_state->sam_ldb, mem_ctx,
2439 policy_state->domain_dn,
2440 r->in.trusted_domain->string,
2441 r->in.trusted_domain->string,
2443 if (!NT_STATUS_IS_OK(nt_status)) {
2444 if (NT_STATUS_EQUAL(nt_status,
2445 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2448 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2451 return setInfoTrustedDomain_base(dce_call, policy_state, mem_ctx,
2452 msgs[0], r->in.level, r->in.info);
2456 lsa_QueryTrustedDomainInfoByName
2458 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2459 TALLOC_CTX *mem_ctx,
2460 struct lsa_QueryTrustedDomainInfoByName *r)
2463 struct lsa_OpenTrustedDomainByName opn = {{0},{0}};
2464 struct lsa_QueryTrustedDomainInfo query;
2465 struct dcesrv_handle *h;
2467 opn.in.handle = r->in.handle;
2468 opn.in.name = *r->in.trusted_domain;
2469 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2470 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2471 if (!opn.out.trustdom_handle) {
2472 return NT_STATUS_NO_MEMORY;
2474 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
2475 if (!NT_STATUS_IS_OK(status)) {
2479 /* Ensure this handle goes away at the end of this call */
2480 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2481 talloc_steal(mem_ctx, h);
2483 query.in.trustdom_handle = opn.out.trustdom_handle;
2484 query.in.level = r->in.level;
2485 query.out.info = r->out.info;
2486 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2487 if (!NT_STATUS_IS_OK(status)) {
2491 return NT_STATUS_OK;
2495 lsa_CloseTrustedDomainEx
2497 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
2498 TALLOC_CTX *mem_ctx,
2499 struct lsa_CloseTrustedDomainEx *r)
2501 /* The result of a bad hair day from an IDL programmer? Not
2502 * implmented in Win2k3. You should always just lsa_Close
2504 return NT_STATUS_NOT_IMPLEMENTED;
2509 comparison function for sorting lsa_DomainInformation array
2511 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
2513 return strcasecmp_m(e1->name.string, e2->name.string);
2519 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2520 struct lsa_EnumTrustDom *r)
2522 struct dcesrv_handle *policy_handle;
2523 struct lsa_DomainInfo *entries;
2524 struct lsa_policy_state *policy_state;
2525 struct ldb_message **domains;
2526 const char *attrs[] = {
2528 "securityIdentifier",
2535 *r->out.resume_handle = 0;
2537 r->out.domains->domains = NULL;
2538 r->out.domains->count = 0;
2540 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2542 policy_state = policy_handle->data;
2544 /* search for all users in this domain. This could possibly be cached and
2545 resumed based on resume_key */
2546 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2547 "objectclass=trustedDomain");
2549 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2552 /* convert to lsa_TrustInformation format */
2553 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
2555 return NT_STATUS_NO_MEMORY;
2557 for (i=0;i<count;i++) {
2558 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
2559 entries[i].name.string = ldb_msg_find_attr_as_string(domains[i], "flatname", NULL);
2562 /* sort the results by name */
2563 TYPESAFE_QSORT(entries, count, compare_DomainInfo);
2565 if (*r->in.resume_handle >= count) {
2566 *r->out.resume_handle = -1;
2568 return NT_STATUS_NO_MORE_ENTRIES;
2571 /* return the rest, limit by max_size. Note that we
2572 use the w2k3 element size value of 60 */
2573 r->out.domains->count = count - *r->in.resume_handle;
2574 r->out.domains->count = MIN(r->out.domains->count,
2575 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
2577 r->out.domains->domains = entries + *r->in.resume_handle;
2579 if (r->out.domains->count < count - *r->in.resume_handle) {
2580 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2581 return STATUS_MORE_ENTRIES;
2584 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2585 * always be larger than the previous input resume handle, in
2586 * particular when hitting the last query it is vital to set the
2587 * resume handle correctly to avoid infinite client loops, as
2588 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2589 * status is NT_STATUS_OK - gd */
2591 *r->out.resume_handle = (uint32_t)-1;
2593 return NT_STATUS_OK;
2597 comparison function for sorting lsa_DomainInformation array
2599 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
2601 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
2605 lsa_EnumTrustedDomainsEx
2607 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2608 struct lsa_EnumTrustedDomainsEx *r)
2610 struct dcesrv_handle *policy_handle;
2611 struct lsa_TrustDomainInfoInfoEx *entries;
2612 struct lsa_policy_state *policy_state;
2613 struct ldb_message **domains;
2614 const char *attrs[] = {
2617 "securityIdentifier",
2627 *r->out.resume_handle = 0;
2629 r->out.domains->domains = NULL;
2630 r->out.domains->count = 0;
2632 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2634 policy_state = policy_handle->data;
2636 /* search for all users in this domain. This could possibly be cached and
2637 resumed based on resume_key */
2638 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2639 "objectclass=trustedDomain");
2641 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2644 /* convert to lsa_DomainInformation format */
2645 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
2647 return NT_STATUS_NO_MEMORY;
2649 for (i=0;i<count;i++) {
2650 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
2651 if (!NT_STATUS_IS_OK(nt_status)) {
2656 /* sort the results by name */
2657 TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
2659 if (*r->in.resume_handle >= count) {
2660 *r->out.resume_handle = -1;
2662 return NT_STATUS_NO_MORE_ENTRIES;
2665 /* return the rest, limit by max_size. Note that we
2666 use the w2k3 element size value of 60 */
2667 r->out.domains->count = count - *r->in.resume_handle;
2668 r->out.domains->count = MIN(r->out.domains->count,
2669 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
2671 r->out.domains->domains = entries + *r->in.resume_handle;
2673 if (r->out.domains->count < count - *r->in.resume_handle) {
2674 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2675 return STATUS_MORE_ENTRIES;
2678 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2680 return NT_STATUS_OK;
2687 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2688 struct lsa_OpenAccount *r)
2690 struct dcesrv_handle *h, *ah;
2691 struct lsa_policy_state *state;
2692 struct lsa_account_state *astate;
2694 ZERO_STRUCTP(r->out.acct_handle);
2696 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2700 astate = talloc(dce_call->conn, struct lsa_account_state);
2701 if (astate == NULL) {
2702 return NT_STATUS_NO_MEMORY;
2705 astate->account_sid = dom_sid_dup(astate, r->in.sid);
2706 if (astate->account_sid == NULL) {
2707 talloc_free(astate);
2708 return NT_STATUS_NO_MEMORY;
2711 astate->policy = talloc_reference(astate, state);
2712 astate->access_mask = r->in.access_mask;
2715 * For now we grant all requested access.
2717 * We will fail at the ldb layer later.
2719 if (astate->access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
2720 astate->access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
2721 astate->access_mask |= LSA_ACCOUNT_ALL_ACCESS;
2723 se_map_generic(&astate->access_mask, &dcesrv_lsa_account_mapping);
2725 DEBUG(10,("%s: %s access desired[0x%08X] granted[0x%08X] - success.\n",
2726 __func__, dom_sid_string(mem_ctx, astate->account_sid),
2727 (unsigned)r->in.access_mask,
2728 (unsigned)astate->access_mask));
2730 ah = dcesrv_handle_create(dce_call, LSA_HANDLE_ACCOUNT);
2732 talloc_free(astate);
2733 return NT_STATUS_NO_MEMORY;
2736 ah->data = talloc_steal(ah, astate);
2738 *r->out.acct_handle = ah->wire_handle;
2740 return NT_STATUS_OK;
2745 lsa_EnumPrivsAccount
2747 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
2748 TALLOC_CTX *mem_ctx,
2749 struct lsa_EnumPrivsAccount *r)
2751 struct dcesrv_handle *h;
2752 struct lsa_account_state *astate;
2755 struct ldb_message **res;
2756 const char * const attrs[] = { "privilege", NULL};
2757 struct ldb_message_element *el;
2759 struct lsa_PrivilegeSet *privs;
2761 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2765 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2766 if (privs == NULL) {
2767 return NT_STATUS_NO_MEMORY;
2773 *r->out.privs = privs;
2775 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
2776 if (sidstr == NULL) {
2777 return NT_STATUS_NO_MEMORY;
2780 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
2781 "objectSid=%s", sidstr);
2783 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2786 return NT_STATUS_OK;
2789 el = ldb_msg_find_element(res[0], "privilege");
2790 if (el == NULL || el->num_values == 0) {
2791 return NT_STATUS_OK;
2794 privs->set = talloc_array(privs,
2795 struct lsa_LUIDAttribute, el->num_values);
2796 if (privs->set == NULL) {
2797 return NT_STATUS_NO_MEMORY;
2801 for (i=0;i<el->num_values;i++) {
2802 int id = sec_privilege_id((const char *)el->values[i].data);
2803 if (id == SEC_PRIV_INVALID) {
2804 /* Perhaps an account right, not a privilege */
2807 privs->set[j].attribute = 0;
2808 privs->set[j].luid.low = id;
2809 privs->set[j].luid.high = 0;
2815 return NT_STATUS_OK;
2819 lsa_EnumAccountRights
2821 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
2822 TALLOC_CTX *mem_ctx,
2823 struct lsa_EnumAccountRights *r)
2825 struct dcesrv_handle *h;
2826 struct lsa_policy_state *state;
2829 struct ldb_message **res;
2830 const char * const attrs[] = { "privilege", NULL};
2832 struct ldb_message_element *el;
2834 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2838 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
2839 if (sidstr == NULL) {
2840 return NT_STATUS_NO_MEMORY;
2843 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2844 "(&(objectSid=%s)(privilege=*))", sidstr);
2846 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2849 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
2850 dom_sid_string(mem_ctx, r->in.sid),
2851 ldb_errstring(state->pdb)));
2852 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2855 el = ldb_msg_find_element(res[0], "privilege");
2856 if (el == NULL || el->num_values == 0) {
2857 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2860 r->out.rights->count = el->num_values;
2861 r->out.rights->names = talloc_array(r->out.rights,
2862 struct lsa_StringLarge, r->out.rights->count);
2863 if (r->out.rights->names == NULL) {
2864 return NT_STATUS_NO_MEMORY;
2867 for (i=0;i<el->num_values;i++) {
2868 r->out.rights->names[i].string = (const char *)el->values[i].data;
2871 return NT_STATUS_OK;
2877 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
2879 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
2880 TALLOC_CTX *mem_ctx,
2881 struct lsa_policy_state *state,
2883 struct dom_sid *sid,
2884 const struct lsa_RightSet *rights)
2886 struct auth_session_info *session_info =
2887 dcesrv_call_session_info(dce_call);
2888 const char *sidstr, *sidndrstr;
2889 struct ldb_message *msg;
2890 struct ldb_message_element *el;
2893 struct lsa_EnumAccountRights r2;
2896 if (security_session_user_level(session_info, NULL) <
2897 SECURITY_ADMINISTRATOR) {
2898 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
2899 return NT_STATUS_ACCESS_DENIED;
2902 msg = ldb_msg_new(mem_ctx);
2904 return NT_STATUS_NO_MEMORY;
2907 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
2908 if (sidndrstr == NULL) {
2910 return NT_STATUS_NO_MEMORY;
2913 sidstr = dom_sid_string(msg, sid);
2914 if (sidstr == NULL) {
2916 return NT_STATUS_NO_MEMORY;
2919 dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
2920 if (dnstr == NULL) {
2922 return NT_STATUS_NO_MEMORY;
2925 msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
2926 if (msg->dn == NULL) {
2928 return NT_STATUS_NO_MEMORY;
2931 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
2934 r2.in.handle = &state->handle->wire_handle;
2936 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
2938 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2939 if (!NT_STATUS_IS_OK(status)) {
2940 ZERO_STRUCTP(r2.out.rights);
2944 for (i=0;i<rights->count;i++) {
2947 ok = dcesrc_lsa_valid_AccountRight(rights->names[i].string);
2950 return NT_STATUS_NO_SUCH_PRIVILEGE;
2953 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
2955 for (j=0;j<r2.out.rights->count;j++) {
2956 if (strcasecmp_m(r2.out.rights->names[j].string,
2957 rights->names[i].string) == 0) {
2961 if (j != r2.out.rights->count) continue;
2964 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2965 if (ret != LDB_SUCCESS) {
2967 return NT_STATUS_NO_MEMORY;
2971 el = ldb_msg_find_element(msg, "privilege");
2974 return NT_STATUS_OK;
2977 el->flags = ldb_flag;
2979 ret = ldb_modify(state->pdb, msg);
2980 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
2981 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
2983 return NT_STATUS_NO_MEMORY;
2985 ldb_msg_add_string(msg, "comment", "added via LSA");
2986 ret = ldb_add(state->pdb, msg);
2988 if (ret != LDB_SUCCESS) {
2989 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2991 return NT_STATUS_OK;
2993 DEBUG(3, ("Could not %s attributes from %s: %s",
2994 LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2995 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
2997 return NT_STATUS_UNEXPECTED_IO_ERROR;
3001 return NT_STATUS_OK;
3005 lsa_AddPrivilegesToAccount
3007 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3008 struct lsa_AddPrivilegesToAccount *r)
3010 struct lsa_RightSet rights;
3011 struct dcesrv_handle *h;
3012 struct lsa_account_state *astate;
3015 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
3019 rights.count = r->in.privs->count;
3020 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
3021 if (rights.names == NULL) {
3022 return NT_STATUS_NO_MEMORY;
3024 for (i=0;i<rights.count;i++) {
3025 int id = r->in.privs->set[i].luid.low;
3026 if (r->in.privs->set[i].luid.high) {
3027 return NT_STATUS_NO_SUCH_PRIVILEGE;
3029 rights.names[i].string = sec_privilege_name(id);
3030 if (rights.names[i].string == NULL) {
3031 return NT_STATUS_NO_SUCH_PRIVILEGE;
3035 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
3036 LDB_FLAG_MOD_ADD, astate->account_sid,
3042 lsa_RemovePrivilegesFromAccount
3044 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3045 struct lsa_RemovePrivilegesFromAccount *r)
3047 struct lsa_RightSet *rights;
3048 struct dcesrv_handle *h;
3049 struct lsa_account_state *astate;
3052 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
3056 rights = talloc(mem_ctx, struct lsa_RightSet);
3058 if (r->in.remove_all == 1 &&
3059 r->in.privs == NULL) {
3060 struct lsa_EnumAccountRights r2;
3063 r2.in.handle = &astate->policy->handle->wire_handle;
3064 r2.in.sid = astate->account_sid;
3065 r2.out.rights = rights;
3067 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
3068 if (!NT_STATUS_IS_OK(status)) {
3072 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
3073 LDB_FLAG_MOD_DELETE, astate->account_sid,
3077 if (r->in.remove_all != 0) {
3078 return NT_STATUS_INVALID_PARAMETER;
3081 rights->count = r->in.privs->count;
3082 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
3083 if (rights->names == NULL) {
3084 return NT_STATUS_NO_MEMORY;
3086 for (i=0;i<rights->count;i++) {
3087 int id = r->in.privs->set[i].luid.low;
3088 if (r->in.privs->set[i].luid.high) {
3089 return NT_STATUS_NO_SUCH_PRIVILEGE;
3091 rights->names[i].string = sec_privilege_name(id);
3092 if (rights->names[i].string == NULL) {
3093 return NT_STATUS_NO_SUCH_PRIVILEGE;
3097 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
3098 LDB_FLAG_MOD_DELETE, astate->account_sid,
3104 lsa_GetQuotasForAccount
3106 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3107 struct lsa_GetQuotasForAccount *r)
3109 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3114 lsa_SetQuotasForAccount
3116 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3117 struct lsa_SetQuotasForAccount *r)
3119 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3124 lsa_GetSystemAccessAccount
3126 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3127 struct lsa_GetSystemAccessAccount *r)
3129 struct dcesrv_handle *h;
3130 struct lsa_account_state *astate;
3133 struct ldb_message **res;
3134 const char * const attrs[] = { "privilege", NULL};
3135 struct ldb_message_element *el;
3138 *(r->out.access_mask) = 0x00000000;
3140 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
3144 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
3145 if (sidstr == NULL) {
3146 return NT_STATUS_NO_MEMORY;
3149 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
3150 "objectSid=%s", sidstr);
3152 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3155 return NT_STATUS_OK;
3158 el = ldb_msg_find_element(res[0], "privilege");
3159 if (el == NULL || el->num_values == 0) {
3160 return NT_STATUS_OK;
3163 for (i=0;i<el->num_values;i++) {
3164 uint32_t right_bit = sec_right_bit((const char *)el->values[i].data);
3165 if (right_bit == 0) {
3166 /* Perhaps an privilege, not a right */
3169 *(r->out.access_mask) |= right_bit;
3172 return NT_STATUS_OK;
3177 lsa_SetSystemAccessAccount
3179 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3180 struct lsa_SetSystemAccessAccount *r)
3182 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3187 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3188 struct lsa_CreateSecret *r)
3190 struct auth_session_info *session_info =
3191 dcesrv_call_session_info(dce_call);
3192 struct dcesrv_handle *policy_handle;
3193 struct lsa_policy_state *policy_state;
3194 struct lsa_secret_state *secret_state;
3195 struct dcesrv_handle *handle;
3196 struct ldb_message **msgs, *msg;
3197 struct ldb_context *samdb = NULL;
3198 const char *attrs[] = {
3206 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3207 ZERO_STRUCTP(r->out.sec_handle);
3209 switch (security_session_user_level(session_info, NULL))
3211 case SECURITY_SYSTEM:
3212 case SECURITY_ADMINISTRATOR:
3215 /* Users and annonymous are not allowed create secrets */
3216 return NT_STATUS_ACCESS_DENIED;
3219 policy_state = policy_handle->data;
3221 if (!r->in.name.string) {
3222 return NT_STATUS_INVALID_PARAMETER;
3225 secret_state = talloc(mem_ctx, struct lsa_secret_state);
3226 NT_STATUS_HAVE_NO_MEMORY(secret_state);
3227 secret_state->policy = policy_state;
3229 msg = ldb_msg_new(mem_ctx);
3231 return NT_STATUS_NO_MEMORY;
3234 if (strncmp("G$", r->in.name.string, 2) == 0) {
3237 secret_state->global = true;
3239 name = &r->in.name.string[2];
3240 if (strlen(name) == 0) {
3241 return NT_STATUS_INVALID_PARAMETER;
3244 name2 = talloc_asprintf(mem_ctx, "%s Secret",
3245 ldb_binary_encode_string(mem_ctx, name));
3246 NT_STATUS_HAVE_NO_MEMORY(name2);
3249 * We need to connect to the database as system, as this is
3250 * one of the rare RPC calls that must read the secrets
3251 * (and this is denied otherwise)
3253 * We also save the current remote session details so they can
3254 * used by the audit logging module. This allows the audit
3255 * logging to report the remote users details, rather than the
3256 * system users details.
3258 samdb = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
3259 secret_state->sam_ldb = talloc_reference(secret_state, samdb);
3260 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
3262 /* search for the secret record */
3263 ret = gendb_search(secret_state->sam_ldb,
3264 mem_ctx, policy_state->system_dn, &msgs, attrs,
3265 "(&(cn=%s)(objectclass=secret))",
3268 return NT_STATUS_OBJECT_NAME_COLLISION;
3272 DEBUG(0,("Failure searching for CN=%s: %s\n",
3273 name2, ldb_errstring(secret_state->sam_ldb)));
3274 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3277 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
3278 NT_STATUS_HAVE_NO_MEMORY(msg->dn);
3279 if (!ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
3280 return NT_STATUS_NO_MEMORY;
3283 ret = ldb_msg_add_string(msg, "cn", name2);
3284 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
3286 secret_state->global = false;
3288 name = r->in.name.string;
3289 if (strlen(name) == 0) {
3290 return NT_STATUS_INVALID_PARAMETER;
3293 secret_state->sam_ldb = talloc_reference(secret_state,
3294 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
3295 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
3297 /* search for the secret record */
3298 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
3299 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
3301 "(&(cn=%s)(objectclass=secret))",
3302 ldb_binary_encode_string(mem_ctx, name));
3304 return NT_STATUS_OBJECT_NAME_COLLISION;
3308 DEBUG(0,("Failure searching for CN=%s: %s\n",
3309 name, ldb_errstring(secret_state->sam_ldb)));
3310 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3313 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb,
3314 "cn=%s,cn=LSA Secrets", name);
3315 NT_STATUS_HAVE_NO_MEMORY(msg->dn);
3316 ret = ldb_msg_add_string(msg, "cn", name);
3317 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
3320 ret = ldb_msg_add_string(msg, "objectClass", "secret");
3321 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
3323 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
3324 NT_STATUS_HAVE_NO_MEMORY(secret_state->secret_dn);
3326 /* create the secret */
3327 ret = ldb_add(secret_state->sam_ldb, msg);
3328 if (ret != LDB_SUCCESS) {
3329 DEBUG(0,("Failed to create secret record %s: %s\n",
3330 ldb_dn_get_linearized(msg->dn),
3331 ldb_errstring(secret_state->sam_ldb)));
3332 return NT_STATUS_ACCESS_DENIED;
3335 handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET);
3336 NT_STATUS_HAVE_NO_MEMORY(handle);
3338 handle->data = talloc_steal(handle, secret_state);
3340 secret_state->access_mask = r->in.access_mask;
3341 secret_state->policy = talloc_reference(secret_state, policy_state);
3342 NT_STATUS_HAVE_NO_MEMORY(secret_state->policy);
3344 *r->out.sec_handle = handle->wire_handle;
3346 return NT_STATUS_OK;
3353 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3354 struct lsa_OpenSecret *r)
3356 struct auth_session_info *session_info =
3357 dcesrv_call_session_info(dce_call);
3358 struct dcesrv_handle *policy_handle;
3359 struct lsa_policy_state *policy_state;
3360 struct lsa_secret_state *secret_state;
3361 struct dcesrv_handle *handle;
3362 struct ldb_message **msgs;
3363 struct ldb_context *samdb = NULL;
3364 const char *attrs[] = {
3370 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3371 ZERO_STRUCTP(r->out.sec_handle);
3372 policy_state = policy_handle->data;
3374 if (!r->in.name.string) {
3375 return NT_STATUS_INVALID_PARAMETER;
3378 switch (security_session_user_level(session_info, NULL))
3380 case SECURITY_SYSTEM:
3381 case SECURITY_ADMINISTRATOR:
3384 /* Users and annonymous are not allowed to access secrets */
3385 return NT_STATUS_ACCESS_DENIED;
3388 secret_state = talloc(mem_ctx, struct lsa_secret_state);
3389 if (!secret_state) {
3390 return NT_STATUS_NO_MEMORY;
3392 secret_state->policy = policy_state;
3394 if (strncmp("G$", r->in.name.string, 2) == 0) {
3395 name = &r->in.name.string[2];
3397 * We need to connect to the database as system, as this is
3398 * one of the rare RPC calls that must read the secrets
3399 * (and this is denied otherwise)
3401 * We also save the current remote session details so they can
3402 * used by the audit logging module. This allows the audit
3403 * logging to report the remote users details, rather than the
3404 * system users details.
3406 samdb = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
3407 secret_state->sam_ldb = talloc_reference(secret_state, samdb);
3408 secret_state->global = true;
3410 if (strlen(name) < 1) {
3411 return NT_STATUS_INVALID_PARAMETER;
3414 /* search for the secret record */
3415 ret = gendb_search(secret_state->sam_ldb,
3416 mem_ctx, policy_state->system_dn, &msgs, attrs,
3417 "(&(cn=%s Secret)(objectclass=secret))",
3418 ldb_binary_encode_string(mem_ctx, name));
3420 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3424 DEBUG(0,("Found %d records matching DN %s\n", ret,
3425 ldb_dn_get_linearized(policy_state->system_dn)));
3426 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3429 secret_state->global = false;
3430 secret_state->sam_ldb = talloc_reference(secret_state,
3431 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
3433 name = r->in.name.string;
3434 if (strlen(name) < 1) {
3435 return NT_STATUS_INVALID_PARAMETER;
3438 /* search for the secret record */
3439 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
3440 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
3442 "(&(cn=%s)(objectclass=secret))",
3443 ldb_binary_encode_string(mem_ctx, name));
3445 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3449 DEBUG(0,("Found %d records matching CN=%s\n",
3450 ret, ldb_binary_encode_string(mem_ctx, name)));
3451 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3455 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
3457 handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET);
3459 return NT_STATUS_NO_MEMORY;
3462 handle->data = talloc_steal(handle, secret_state);
3464 secret_state->access_mask = r->in.access_mask;
3465 secret_state->policy = talloc_reference(secret_state, policy_state);
3467 *r->out.sec_handle = handle->wire_handle;
3469 return NT_STATUS_OK;
3476 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3477 struct lsa_SetSecret *r)
3480 struct dcesrv_handle *h;
3481 struct lsa_secret_state *secret_state;
3482 struct ldb_message *msg;
3483 DATA_BLOB session_key;
3484 DATA_BLOB crypt_secret, secret;
3487 NTSTATUS status = NT_STATUS_OK;
3489 struct timeval now = timeval_current();
3490 NTTIME nt_now = timeval_to_nttime(&now);
3492 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3494 secret_state = h->data;
3496 msg = ldb_msg_new(mem_ctx);
3498 return NT_STATUS_NO_MEMORY;
3501 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
3503 return NT_STATUS_NO_MEMORY;
3505 status = dcesrv_transport_session_key(dce_call, &session_key);
3506 if (!NT_STATUS_IS_OK(status)) {
3510 if (r->in.old_val) {
3512 crypt_secret.data = r->in.old_val->data;
3513 crypt_secret.length = r->in.old_val->size;
3515 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3516 if (!NT_STATUS_IS_OK(status)) {
3520 val.data = secret.data;
3521 val.length = secret.length;
3524 if (ldb_msg_add_value(msg, "priorValue", &val, NULL) != LDB_SUCCESS) {
3525 return NT_STATUS_NO_MEMORY;
3528 /* set old value mtime */
3529 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3530 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3531 return NT_STATUS_NO_MEMORY;
3535 /* If the old value is not set, then migrate the
3536 * current value to the old value */
3537 const struct ldb_val *old_val;
3538 NTTIME last_set_time;
3539 struct ldb_message **res;
3540 const char *attrs[] = {
3546 /* search for the secret record */
3547 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
3548 secret_state->secret_dn, &res, attrs);
3550 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3554 DEBUG(0,("Found %d records matching dn=%s\n", ret,
3555 ldb_dn_get_linearized(secret_state->secret_dn)));
3556 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3559 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3560 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3564 if (ldb_msg_add_value(msg, "priorValue",
3565 old_val, NULL) != LDB_SUCCESS) {
3566 return NT_STATUS_NO_MEMORY;
3569 if (samdb_msg_add_delete(secret_state->sam_ldb,
3570 mem_ctx, msg, "priorValue") != LDB_SUCCESS) {
3571 return NT_STATUS_NO_MEMORY;
3575 /* set old value mtime */
3576 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
3577 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3578 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
3579 return NT_STATUS_NO_MEMORY;
3582 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3583 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3584 return NT_STATUS_NO_MEMORY;
3589 if (r->in.new_val) {
3591 crypt_secret.data = r->in.new_val->data;
3592 crypt_secret.length = r->in.new_val->size;
3594 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3595 if (!NT_STATUS_IS_OK(status)) {
3599 val.data = secret.data;
3600 val.length = secret.length;
3603 if (ldb_msg_add_value(msg, "currentValue", &val, NULL) != LDB_SUCCESS) {
3604 return NT_STATUS_NO_MEMORY;
3607 /* set new value mtime */
3608 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3609 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3610 return NT_STATUS_NO_MEMORY;
3613 /* NULL out the NEW value */
3614 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3615 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3616 return NT_STATUS_NO_MEMORY;
3618 if (samdb_msg_add_delete(secret_state->sam_ldb,
3619 mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
3620 return NT_STATUS_NO_MEMORY;
3624 /* modify the samdb record */
3625 ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
3626 if (ret != LDB_SUCCESS) {
3627 return dsdb_ldb_err_to_ntstatus(ret);
3630 return NT_STATUS_OK;
3637 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3638 struct lsa_QuerySecret *r)
3640 struct auth_session_info *session_info =
3641 dcesrv_call_session_info(dce_call);
3642 struct dcesrv_handle *h;
3643 struct lsa_secret_state *secret_state;
3644 struct ldb_message *msg;
3645 DATA_BLOB session_key;
3646 DATA_BLOB crypt_secret, secret;
3648 struct ldb_message **res;
3649 const char *attrs[] = {
3659 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3661 /* Ensure user is permitted to read this... */
3662 switch (security_session_user_level(session_info, NULL))
3664 case SECURITY_SYSTEM:
3665 case SECURITY_ADMINISTRATOR:
3668 /* Users and annonymous are not allowed to read secrets */
3669 return NT_STATUS_ACCESS_DENIED;
3672 secret_state = h->data;
3674 /* pull all the user attributes */
3675 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
3676 secret_state->secret_dn, &res, attrs);
3678 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3682 nt_status = dcesrv_transport_session_key(dce_call, &session_key);
3683 if (!NT_STATUS_IS_OK(nt_status)) {
3687 if (r->in.old_val) {
3688 const struct ldb_val *prior_val;
3689 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3690 if (!r->out.old_val) {
3691 return NT_STATUS_NO_MEMORY;
3693 prior_val = ldb_msg_find_ldb_val(msg, "priorValue");
3695 if (prior_val && prior_val->length) {
3696 secret.data = prior_val->data;
3697 secret.length = prior_val->length;
3700 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3701 if (!crypt_secret.length) {
3702 return NT_STATUS_NO_MEMORY;
3704 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3705 if (!r->out.old_val->buf) {
3706 return NT_STATUS_NO_MEMORY;
3708 r->out.old_val->buf->size = crypt_secret.length;
3709 r->out.old_val->buf->length = crypt_secret.length;
3710 r->out.old_val->buf->data = crypt_secret.data;
3714 if (r->in.old_mtime) {
3715 r->out.old_mtime = talloc(mem_ctx, NTTIME);
3716 if (!r->out.old_mtime) {
3717 return NT_STATUS_NO_MEMORY;
3719 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(msg, "priorSetTime", 0);
3722 if (r->in.new_val) {
3723 const struct ldb_val *new_val;
3724 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3725 if (!r->out.new_val) {
3726 return NT_STATUS_NO_MEMORY;
3729 new_val = ldb_msg_find_ldb_val(msg, "currentValue");
3731 if (new_val && new_val->length) {
3732 secret.data = new_val->data;
3733 secret.length = new_val->length;
3736 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3737 if (!crypt_secret.length) {
3738 return NT_STATUS_NO_MEMORY;
3740 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3741 if (!r->out.new_val->buf) {
3742 return NT_STATUS_NO_MEMORY;
3744 r->out.new_val->buf->length = crypt_secret.length;
3745 r->out.new_val->buf->size = crypt_secret.length;
3746 r->out.new_val->buf->data = crypt_secret.data;
3750 if (r->in.new_mtime) {
3751 r->out.new_mtime = talloc(mem_ctx, NTTIME);
3752 if (!r->out.new_mtime) {
3753 return NT_STATUS_NO_MEMORY;
3755 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(msg, "lastSetTime", 0);
3758 return NT_STATUS_OK;
3765 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
3766 TALLOC_CTX *mem_ctx,
3767 struct lsa_LookupPrivValue *r)
3769 struct dcesrv_handle *h;
3772 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3774 id = sec_privilege_id(r->in.name->string);
3775 if (id == SEC_PRIV_INVALID) {
3776 return NT_STATUS_NO_SUCH_PRIVILEGE;
3779 r->out.luid->low = id;
3780 r->out.luid->high = 0;
3782 return NT_STATUS_OK;
3789 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
3790 TALLOC_CTX *mem_ctx,
3791 struct lsa_LookupPrivName *r)
3793 struct dcesrv_handle *h;
3794 struct lsa_StringLarge *name;
3795 const char *privname;
3797 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3799 if (r->in.luid->high != 0) {
3800 return NT_STATUS_NO_SUCH_PRIVILEGE;
3803 privname = sec_privilege_name(r->in.luid->low);
3804 if (privname == NULL) {
3805 return NT_STATUS_NO_SUCH_PRIVILEGE;
3808 name = talloc(mem_ctx, struct lsa_StringLarge);
3810 return NT_STATUS_NO_MEMORY;
3813 name->string = privname;
3815 *r->out.name = name;
3817 return NT_STATUS_OK;
3822 lsa_LookupPrivDisplayName
3824 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
3825 TALLOC_CTX *mem_ctx,
3826 struct lsa_LookupPrivDisplayName *r)
3828 struct dcesrv_handle *h;
3829 struct lsa_StringLarge *disp_name = NULL;
3830 enum sec_privilege id;
3832 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3834 id = sec_privilege_id(r->in.name->string);
3835 if (id == SEC_PRIV_INVALID) {
3836 return NT_STATUS_NO_SUCH_PRIVILEGE;
3839 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
3840 if (disp_name == NULL) {
3841 return NT_STATUS_NO_MEMORY;
3844 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
3845 if (disp_name->string == NULL) {
3846 return NT_STATUS_INTERNAL_ERROR;
3849 *r->out.disp_name = disp_name;
3850 *r->out.returned_language_id = 0;
3852 return NT_STATUS_OK;
3857 lsa_EnumAccountsWithUserRight
3859 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
3860 TALLOC_CTX *mem_ctx,
3861 struct lsa_EnumAccountsWithUserRight *r)
3863 struct dcesrv_handle *h;
3864 struct lsa_policy_state *state;
3866 struct ldb_message **res;
3867 const char * const attrs[] = { "objectSid", NULL};
3868 const char *privname;
3871 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3875 if (r->in.name == NULL) {
3876 return NT_STATUS_NO_SUCH_PRIVILEGE;
3879 privname = r->in.name->string;
3881 ok = dcesrc_lsa_valid_AccountRight(privname);
3883 return NT_STATUS_NO_SUCH_PRIVILEGE;
3886 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
3887 "privilege=%s", privname);
3889 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3892 return NT_STATUS_NO_MORE_ENTRIES;
3895 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
3896 if (r->out.sids->sids == NULL) {
3897 return NT_STATUS_NO_MEMORY;
3899 for (i=0;i<ret;i++) {
3900 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
3901 res[i], "objectSid");
3902 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
3904 r->out.sids->num_sids = ret;
3906 return NT_STATUS_OK;
3911 lsa_AddAccountRights
3913 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
3914 TALLOC_CTX *mem_ctx,
3915 struct lsa_AddAccountRights *r)
3917 struct dcesrv_handle *h;
3918 struct lsa_policy_state *state;
3920 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3924 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3926 r->in.sid, r->in.rights);
3931 lsa_RemoveAccountRights
3933 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
3934 TALLOC_CTX *mem_ctx,
3935 struct lsa_RemoveAccountRights *r)
3937 struct dcesrv_handle *h;
3938 struct lsa_policy_state *state;
3940 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3944 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3945 LDB_FLAG_MOD_DELETE,
3946 r->in.sid, r->in.rights);
3951 lsa_StorePrivateData
3953 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3954 struct lsa_StorePrivateData *r)
3956 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3961 lsa_RetrievePrivateData
3963 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3964 struct lsa_RetrievePrivateData *r)
3966 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3973 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3974 struct lsa_GetUserName *r)
3976 enum dcerpc_transport_t transport =
3977 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
3978 struct auth_session_info *session_info =
3979 dcesrv_call_session_info(dce_call);
3980 NTSTATUS status = NT_STATUS_OK;
3981 const char *account_name;
3982 const char *authority_name;
3983 struct lsa_String *_account_name;
3984 struct lsa_String *_authority_name = NULL;
3986 if (transport != NCACN_NP && transport != NCALRPC) {
3987 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
3990 /* this is what w2k3 does */
3991 r->out.account_name = r->in.account_name;
3992 r->out.authority_name = r->in.authority_name;
3994 if (r->in.account_name
3995 && *r->in.account_name
3996 /* && *(*r->in.account_name)->string */
3998 return NT_STATUS_INVALID_PARAMETER;
4001 if (r->in.authority_name
4002 && *r->in.authority_name
4003 /* && *(*r->in.authority_name)->string */
4005 return NT_STATUS_INVALID_PARAMETER;
4008 account_name = talloc_reference(mem_ctx, session_info->info->account_name);
4009 authority_name = talloc_reference(mem_ctx, session_info->info->domain_name);
4011 _account_name = talloc(mem_ctx, struct lsa_String);
4012 NT_STATUS_HAVE_NO_MEMORY(_account_name);
4013 _account_name->string = account_name;
4015 if (r->in.authority_name) {
4016 _authority_name = talloc(mem_ctx, struct lsa_String);
4017 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
4018 _authority_name->string = authority_name;
4021 *r->out.account_name = _account_name;
4022 if (r->out.authority_name) {
4023 *r->out.authority_name = _authority_name;
4032 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
4033 TALLOC_CTX *mem_ctx,
4034 struct lsa_SetInfoPolicy2 *r)
4036 /* need to support these */
4037 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4040 static void kdc_get_policy(TALLOC_CTX *mem_ctx,
4041 struct loadparm_context *lp_ctx,
4042 struct smb_krb5_context *smb_krb5_context,
4043 struct lsa_DomainInfoKerberos *k)
4045 time_t svc_tkt_lifetime;
4046 time_t usr_tkt_lifetime;
4047 time_t renewal_lifetime;
4049 /* Our KDC always re-validates the client */
4050 k->authentication_options = LSA_POLICY_KERBEROS_VALIDATE_CLIENT;
4052 lpcfg_default_kdc_policy(mem_ctx, lp_ctx, &svc_tkt_lifetime,
4053 &usr_tkt_lifetime, &renewal_lifetime);
4055 unix_to_nt_time(&k->service_tkt_lifetime, svc_tkt_lifetime);
4056 unix_to_nt_time(&k->user_tkt_lifetime, usr_tkt_lifetime);
4057 unix_to_nt_time(&k->user_tkt_renewaltime, renewal_lifetime);
4058 #ifdef SAMBA4_USES_HEIMDAL /* MIT lacks krb5_get_max_time_skew.
4059 However in the parent function we basically just did a full
4060 krb5_context init with the only purpose of getting a global
4061 config option (the max skew), it would probably make more sense
4062 to have a lp_ or ldb global option as the samba default */
4063 if (smb_krb5_context) {
4064 unix_to_nt_time(&k->clock_skew,
4065 krb5_get_max_time_skew(smb_krb5_context->krb5_context));
4071 lsa_QueryDomainInformationPolicy
4073 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
4074 TALLOC_CTX *mem_ctx,
4075 struct lsa_QueryDomainInformationPolicy *r)
4077 union lsa_DomainInformationPolicy *info;
4079 info = talloc_zero(r->out.info, union lsa_DomainInformationPolicy);
4081 return NT_STATUS_NO_MEMORY;
4084 switch (r->in.level) {
4085 case LSA_DOMAIN_INFO_POLICY_EFS:
4087 *r->out.info = NULL;
4088 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4089 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
4091 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
4092 struct smb_krb5_context *smb_krb5_context;
4093 int ret = smb_krb5_init_context(mem_ctx,
4094 dce_call->conn->dce_ctx->lp_ctx,
4098 *r->out.info = NULL;
4099 return NT_STATUS_INTERNAL_ERROR;
4101 kdc_get_policy(mem_ctx, dce_call->conn->dce_ctx->lp_ctx,
4104 talloc_free(smb_krb5_context);
4105 *r->out.info = info;
4106 return NT_STATUS_OK;
4110 *r->out.info = NULL;
4111 return NT_STATUS_INVALID_INFO_CLASS;
4116 lsa_SetDomInfoPolicy
4118 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
4119 TALLOC_CTX *mem_ctx,
4120 struct lsa_SetDomainInformationPolicy *r)
4122 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4128 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
4129 TALLOC_CTX *mem_ctx,
4130 struct lsa_TestCall *r)
4132 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4138 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4139 struct lsa_CREDRWRITE *r)
4141 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4148 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4149 struct lsa_CREDRREAD *r)
4151 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4158 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4159 struct lsa_CREDRENUMERATE *r)
4161 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4166 lsa_CREDRWRITEDOMAINCREDENTIALS
4168 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4169 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
4171 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4176 lsa_CREDRREADDOMAINCREDENTIALS
4178 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4179 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
4181 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4188 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4189 struct lsa_CREDRDELETE *r)
4191 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4196 lsa_CREDRGETTARGETINFO
4198 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4199 struct lsa_CREDRGETTARGETINFO *r)
4201 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4206 lsa_CREDRPROFILELOADED
4208 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4209 struct lsa_CREDRPROFILELOADED *r)
4211 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4216 lsa_CREDRGETSESSIONTYPES
4218 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4219 struct lsa_CREDRGETSESSIONTYPES *r)
4221 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4226 lsa_LSARREGISTERAUDITEVENT
4228 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4229 struct lsa_LSARREGISTERAUDITEVENT *r)
4231 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4236 lsa_LSARGENAUDITEVENT
4238 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4239 struct lsa_LSARGENAUDITEVENT *r)
4241 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4246 lsa_LSARUNREGISTERAUDITEVENT
4248 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4249 struct lsa_LSARUNREGISTERAUDITEVENT *r)
4251 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4256 lsa_lsaRQueryForestTrustInformation
4258 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4259 struct lsa_lsaRQueryForestTrustInformation *r)
4261 struct dcesrv_handle *h = NULL;
4262 struct lsa_policy_state *p_state = NULL;
4263 int forest_level = DS_DOMAIN_FUNCTION_2000;
4264 const char * const trust_attrs[] = {
4265 "securityIdentifier",
4271 "msDS-TrustForestTrustInfo",
4274 struct ldb_message *trust_tdo_msg = NULL;
4275 struct lsa_TrustDomainInfoInfoEx *trust_tdo = NULL;
4276 struct ForestTrustInfo *trust_fti = NULL;
4277 struct lsa_ForestTrustInformation *trust_lfti = NULL;
4280 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4284 if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
4285 return NT_STATUS_INVALID_DOMAIN_STATE;
4288 forest_level = dsdb_forest_functional_level(p_state->sam_ldb);
4289 if (forest_level < DS_DOMAIN_FUNCTION_2003) {
4290 return NT_STATUS_INVALID_DOMAIN_STATE;
4293 if (r->in.trusted_domain_name->string == NULL) {
4294 return NT_STATUS_NO_SUCH_DOMAIN;
4297 status = dsdb_trust_search_tdo(p_state->sam_ldb,
4298 r->in.trusted_domain_name->string,
4299 r->in.trusted_domain_name->string,
4300 trust_attrs, mem_ctx, &trust_tdo_msg);
4301 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4302 return NT_STATUS_NO_SUCH_DOMAIN;
4304 if (!NT_STATUS_IS_OK(status)) {
4308 status = dsdb_trust_parse_tdo_info(mem_ctx, trust_tdo_msg, &trust_tdo);
4309 if (!NT_STATUS_IS_OK(status)) {
4313 if (!(trust_tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4314 return NT_STATUS_INVALID_PARAMETER;
4317 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4318 return NT_STATUS_INVALID_PARAMETER;
4321 status = dsdb_trust_parse_forest_info(mem_ctx,
4324 if (!NT_STATUS_IS_OK(status)) {
4328 status = dsdb_trust_forest_info_to_lsa(mem_ctx, trust_fti,
4330 if (!NT_STATUS_IS_OK(status)) {
4334 *r->out.forest_trust_info = trust_lfti;
4335 return NT_STATUS_OK;
4339 lsa_lsaRSetForestTrustInformation
4341 static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_state *dce_call,
4342 TALLOC_CTX *mem_ctx,
4343 struct lsa_lsaRSetForestTrustInformation *r)
4345 struct dcesrv_handle *h;
4346 struct lsa_policy_state *p_state;
4347 const char * const trust_attrs[] = {
4348 "securityIdentifier",
4354 "msDS-TrustForestTrustInfo",
4357 struct ldb_message *trust_tdo_msg = NULL;
4358 struct lsa_TrustDomainInfoInfoEx *trust_tdo = NULL;
4359 struct lsa_ForestTrustInformation *step1_lfti = NULL;
4360 struct lsa_ForestTrustInformation *step2_lfti = NULL;
4361 struct ForestTrustInfo *trust_fti = NULL;
4362 struct ldb_result *trusts_res = NULL;
4364 struct lsa_TrustDomainInfoInfoEx *xref_tdo = NULL;
4365 struct lsa_ForestTrustInformation *xref_lfti = NULL;
4366 struct lsa_ForestTrustCollisionInfo *c_info = NULL;
4367 DATA_BLOB ft_blob = {};
4368 struct ldb_message *msg = NULL;
4369 struct server_id *server_ids = NULL;
4370 uint32_t num_server_ids = 0;
4372 enum ndr_err_code ndr_err;
4374 bool in_transaction = false;
4376 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4380 if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
4381 return NT_STATUS_INVALID_DOMAIN_STATE;
4384 if (r->in.check_only == 0) {
4385 ret = ldb_transaction_start(p_state->sam_ldb);
4386 if (ret != LDB_SUCCESS) {
4387 return NT_STATUS_INTERNAL_DB_CORRUPTION;
4389 in_transaction = true;
4393 * abort if we are not a PDC
4395 * In future we should use a function like IsEffectiveRoleOwner()
4397 if (!samdb_is_pdc(p_state->sam_ldb)) {
4398 status = NT_STATUS_INVALID_DOMAIN_ROLE;
4402 if (r->in.trusted_domain_name->string == NULL) {
4403 status = NT_STATUS_NO_SUCH_DOMAIN;
4407 status = dsdb_trust_search_tdo(p_state->sam_ldb,
4408 r->in.trusted_domain_name->string,
4409 r->in.trusted_domain_name->string,
4410 trust_attrs, mem_ctx, &trust_tdo_msg);
4411 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4412 status = NT_STATUS_NO_SUCH_DOMAIN;
4415 if (!NT_STATUS_IS_OK(status)) {
4419 status = dsdb_trust_parse_tdo_info(mem_ctx, trust_tdo_msg, &trust_tdo);
4420 if (!NT_STATUS_IS_OK(status)) {
4424 if (!(trust_tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4425 status = NT_STATUS_INVALID_PARAMETER;
4429 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4430 status = NT_STATUS_INVALID_PARAMETER;
4435 * verify and normalize the given forest trust info.
4437 * Step1: doesn't reorder yet, so step1_lfti might contain
4438 * NULL entries. This means dsdb_trust_verify_forest_info()
4439 * can generate collision entries with the callers index.
4441 status = dsdb_trust_normalize_forest_info_step1(mem_ctx,
4442 r->in.forest_trust_info,
4444 if (!NT_STATUS_IS_OK(status)) {
4448 c_info = talloc_zero(r->out.collision_info,
4449 struct lsa_ForestTrustCollisionInfo);
4450 if (c_info == NULL) {
4451 status = NT_STATUS_NO_MEMORY;
4456 * First check our own forest, then other domains/forests
4459 status = dsdb_trust_xref_tdo_info(mem_ctx, p_state->sam_ldb,
4461 if (!NT_STATUS_IS_OK(status)) {
4464 status = dsdb_trust_xref_forest_info(mem_ctx, p_state->sam_ldb,
4466 if (!NT_STATUS_IS_OK(status)) {
4471 * The documentation proposed to generate
4472 * LSA_FOREST_TRUST_COLLISION_XREF collisions.
4473 * But Windows always uses LSA_FOREST_TRUST_COLLISION_TDO.
4475 status = dsdb_trust_verify_forest_info(xref_tdo, xref_lfti,
4476 LSA_FOREST_TRUST_COLLISION_TDO,
4477 c_info, step1_lfti);
4478 if (!NT_STATUS_IS_OK(status)) {
4482 /* fetch all other trusted domain objects */
4483 status = dsdb_trust_search_tdos(p_state->sam_ldb,
4484 trust_tdo->domain_name.string,
4486 mem_ctx, &trusts_res);
4487 if (!NT_STATUS_IS_OK(status)) {
4492 * now check against the other domains.
4493 * and generate LSA_FOREST_TRUST_COLLISION_TDO collisions.
4495 for (i = 0; i < trusts_res->count; i++) {
4496 struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
4497 struct ForestTrustInfo *fti = NULL;
4498 struct lsa_ForestTrustInformation *lfti = NULL;
4500 status = dsdb_trust_parse_tdo_info(mem_ctx,
4501 trusts_res->msgs[i],
4503 if (!NT_STATUS_IS_OK(status)) {
4507 status = dsdb_trust_parse_forest_info(tdo,
4508 trusts_res->msgs[i],
4510 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
4513 if (!NT_STATUS_IS_OK(status)) {
4517 status = dsdb_trust_forest_info_to_lsa(tdo, fti, &lfti);
4518 if (!NT_STATUS_IS_OK(status)) {
4522 status = dsdb_trust_verify_forest_info(tdo, lfti,
4523 LSA_FOREST_TRUST_COLLISION_TDO,
4524 c_info, step1_lfti);
4525 if (!NT_STATUS_IS_OK(status)) {
4532 if (r->in.check_only != 0) {
4533 status = NT_STATUS_OK;
4538 * not just a check, write info back
4542 * normalize the given forest trust info.
4544 * Step2: adds TOP_LEVEL_NAME[_EX] in reverse order,
4545 * followed by DOMAIN_INFO in reverse order. It also removes
4546 * possible NULL entries from Step1.
4548 status = dsdb_trust_normalize_forest_info_step2(mem_ctx, step1_lfti,
4550 if (!NT_STATUS_IS_OK(status)) {
4554 status = dsdb_trust_forest_info_from_lsa(mem_ctx, step2_lfti,
4556 if (!NT_STATUS_IS_OK(status)) {
4560 ndr_err = ndr_push_struct_blob(&ft_blob, mem_ctx, trust_fti,
4561 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4562 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4563 status = NT_STATUS_INVALID_PARAMETER;
4567 msg = ldb_msg_new(mem_ctx);
4569 status = NT_STATUS_NO_MEMORY;
4573 msg->dn = ldb_dn_copy(mem_ctx, trust_tdo_msg->dn);
4575 status = NT_STATUS_NO_MEMORY;
4579 ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo",
4580 LDB_FLAG_MOD_REPLACE, NULL);
4581 if (ret != LDB_SUCCESS) {
4582 status = NT_STATUS_NO_MEMORY;
4585 ret = ldb_msg_add_value(msg, "msDS-TrustForestTrustInfo",
4587 if (ret != LDB_SUCCESS) {
4588 status = NT_STATUS_NO_MEMORY;
4592 ret = ldb_modify(p_state->sam_ldb, msg);
4593 if (ret != LDB_SUCCESS) {
4594 status = dsdb_ldb_err_to_ntstatus(ret);
4596 DEBUG(0, ("Failed to store Forest Trust Info: %s\n",
4597 ldb_errstring(p_state->sam_ldb)));
4602 /* ok, all fine, commit transaction and return */
4603 in_transaction = false;
4604 ret = ldb_transaction_commit(p_state->sam_ldb);
4605 if (ret != LDB_SUCCESS) {
4606 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
4611 * Notify winbindd that we have a acquired forest trust info
4613 status = irpc_servers_byname(dce_call->msg_ctx,
4616 &num_server_ids, &server_ids);
4617 if (!NT_STATUS_IS_OK(status)) {
4618 DBG_ERR("irpc_servers_byname failed\n");
4622 imessaging_send(dce_call->msg_ctx, server_ids[0],
4623 MSG_WINBIND_RELOAD_TRUSTED_DOMAINS, NULL);
4625 status = NT_STATUS_OK;
4628 if (NT_STATUS_IS_OK(status) && c_info->count != 0) {
4629 *r->out.collision_info = c_info;
4632 if (in_transaction) {
4633 ldb_transaction_cancel(p_state->sam_ldb);
4642 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4643 struct lsa_CREDRRENAME *r)
4645 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4651 lsa_LSAROPENPOLICYSCE
4653 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4654 struct lsa_LSAROPENPOLICYSCE *r)
4656 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4661 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
4663 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4664 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4666 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4671 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
4673 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4674 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4676 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4681 lsa_LSARADTREPORTSECURITYEVENT
4683 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4684 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4686 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4690 /* include the generated boilerplate */
4691 #include "librpc/gen_ndr/ndr_lsa_s.c"
4695 /*****************************************
4696 NOTE! The remaining calls below were
4697 removed in w2k3, so the DCESRV_FAULT()
4698 replies are the correct implementation. Do
4699 not try and fill these in with anything else
4700 ******************************************/
4703 dssetup_DsRoleDnsNameToFlatName
4705 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4706 struct dssetup_DsRoleDnsNameToFlatName *r)
4708 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4713 dssetup_DsRoleDcAsDc
4715 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4716 struct dssetup_DsRoleDcAsDc *r)
4718 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4723 dssetup_DsRoleDcAsReplica
4725 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4726 struct dssetup_DsRoleDcAsReplica *r)
4728 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4733 dssetup_DsRoleDemoteDc
4735 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4736 struct dssetup_DsRoleDemoteDc *r)
4738 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4743 dssetup_DsRoleGetDcOperationProgress
4745 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4746 struct dssetup_DsRoleGetDcOperationProgress *r)
4748 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4753 dssetup_DsRoleGetDcOperationResults
4755 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4756 struct dssetup_DsRoleGetDcOperationResults *r)
4758 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4763 dssetup_DsRoleCancel
4765 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4766 struct dssetup_DsRoleCancel *r)
4768 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4773 dssetup_DsRoleServerSaveStateForUpgrade
4775 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4776 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
4778 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4783 dssetup_DsRoleUpgradeDownlevelServer
4785 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4786 struct dssetup_DsRoleUpgradeDownlevelServer *r)
4788 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4793 dssetup_DsRoleAbortDownlevelServerUpgrade
4795 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4796 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
4798 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4802 /* include the generated boilerplate */
4803 #include "librpc/gen_ndr/ndr_dssetup_s.c"
4805 NTSTATUS dcerpc_server_lsa_init(TALLOC_CTX *ctx)
4809 ret = dcerpc_server_dssetup_init(ctx);
4810 if (!NT_STATUS_IS_OK(ret)) {
4813 ret = dcerpc_server_lsarpc_init(ctx);
4814 if (!NT_STATUS_IS_OK(ret)) {