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;
1702 orig_val = ldb_msg_find_ldb_val(orig, attribute);
1703 if (!orig_val || !orig_val->data) {
1704 /* add new attribute */
1705 flags = LDB_FLAG_MOD_ADD;
1709 orig_uint = strtoul((const char *)orig_val->data, NULL, 0);
1710 if (errno != 0 || orig_uint != value) {
1711 /* replace also if can't get value */
1712 flags = LDB_FLAG_MOD_REPLACE;
1717 /* stored value is identical, nothing to change */
1721 ret = ldb_msg_add_empty(dest, attribute, flags, NULL);
1722 if (ret != LDB_SUCCESS) {
1723 return NT_STATUS_NO_MEMORY;
1726 ret = samdb_msg_add_uint(sam_ldb, dest, dest, attribute, value);
1727 if (ret != LDB_SUCCESS) {
1728 return NT_STATUS_NO_MEMORY;
1733 *orig_value = orig_uint;
1735 return NT_STATUS_OK;
1738 static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx,
1739 struct ldb_context *sam_ldb,
1740 struct ldb_dn *base_dn,
1742 const char *netbios_name,
1743 struct trustAuthInOutBlob *in)
1745 const char *attrs[] = { "userAccountControl", NULL };
1746 struct ldb_message **msgs;
1747 struct ldb_message *msg;
1752 ret = gendb_search(sam_ldb, mem_ctx,
1753 base_dn, &msgs, attrs,
1754 "samAccountName=%s$", netbios_name);
1756 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1761 return NT_STATUS_OK;
1764 /* ok no existing user, add it from scratch */
1765 return add_trust_user(mem_ctx, sam_ldb, base_dn,
1766 netbios_name, in, NULL);
1769 /* check user is what we are looking for */
1770 uac = ldb_msg_find_attr_as_uint(msgs[0],
1771 "userAccountControl", 0);
1772 if (!(uac & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
1773 return NT_STATUS_OBJECT_NAME_COLLISION;
1777 ret = ldb_delete(sam_ldb, msgs[0]->dn);
1780 return NT_STATUS_OK;
1781 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1782 return NT_STATUS_ACCESS_DENIED;
1784 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1788 /* entry exists, just modify secret if any */
1789 if (in == NULL || in->count == 0) {
1790 return NT_STATUS_OK;
1793 msg = ldb_msg_new(mem_ctx);
1795 return NT_STATUS_NO_MEMORY;
1797 msg->dn = msgs[0]->dn;
1799 for (i = 0; i < in->count; i++) {
1800 const char *attribute;
1802 switch (in->current.array[i].AuthType) {
1803 case TRUST_AUTH_TYPE_NT4OWF:
1804 attribute = "unicodePwd";
1805 v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
1808 case TRUST_AUTH_TYPE_CLEAR:
1809 attribute = "clearTextPassword";
1810 v.data = in->current.array[i].AuthInfo.clear.password;
1811 v.length = in->current.array[i].AuthInfo.clear.size;
1817 ret = ldb_msg_add_empty(msg, attribute,
1818 LDB_FLAG_MOD_REPLACE, NULL);
1819 if (ret != LDB_SUCCESS) {
1820 return NT_STATUS_NO_MEMORY;
1823 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
1824 if (ret != LDB_SUCCESS) {
1825 return NT_STATUS_NO_MEMORY;
1829 /* create the trusted_domain user account */
1830 ret = ldb_modify(sam_ldb, msg);
1831 if (ret != LDB_SUCCESS) {
1832 DEBUG(0,("Failed to create user record %s: %s\n",
1833 ldb_dn_get_linearized(msg->dn),
1834 ldb_errstring(sam_ldb)));
1837 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1838 return NT_STATUS_DOMAIN_EXISTS;
1839 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1840 return NT_STATUS_ACCESS_DENIED;
1842 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1846 return NT_STATUS_OK;
1850 static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call,
1851 struct lsa_policy_state *p_state,
1852 TALLOC_CTX *mem_ctx,
1853 struct ldb_message *dom_msg,
1854 enum lsa_TrustDomInfoEnum level,
1855 union lsa_TrustedDomainInfo *info)
1857 uint32_t *posix_offset = NULL;
1858 struct lsa_TrustDomainInfoInfoEx *info_ex = NULL;
1859 struct lsa_TrustDomainInfoAuthInfo *auth_info = NULL;
1860 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
1861 uint32_t *enc_types = NULL;
1862 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
1863 struct trustDomainPasswords auth_struct;
1864 struct trustAuthInOutBlob *current_passwords = NULL;
1866 struct ldb_message **msgs;
1867 struct ldb_message *msg;
1868 bool add_outgoing = false;
1869 bool add_incoming = false;
1870 bool del_outgoing = false;
1871 bool del_incoming = false;
1872 bool del_forest_info = false;
1873 bool in_transaction = false;
1878 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1879 posix_offset = &info->posix_offset.posix_offset;
1881 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1882 info_ex = &info->info_ex;
1884 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1885 auth_info = &info->auth_info;
1887 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1888 posix_offset = &info->full_info.posix_offset.posix_offset;
1889 info_ex = &info->full_info.info_ex;
1890 auth_info = &info->full_info.auth_info;
1892 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1893 auth_info_int = &info->auth_info_internal;
1895 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1896 posix_offset = &info->full_info_internal.posix_offset.posix_offset;
1897 info_ex = &info->full_info_internal.info_ex;
1898 auth_info_int = &info->full_info_internal.auth_info;
1900 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1901 enc_types = &info->enc_types.enc_types;
1904 return NT_STATUS_INVALID_PARAMETER;
1908 nt_status = auth_info_2_auth_blob(mem_ctx, auth_info,
1910 &trustAuthOutgoing);
1911 if (!NT_STATUS_IS_OK(nt_status)) {
1914 if (trustAuthIncoming.data) {
1915 /* This does the decode of some of this twice, but it is easier that way */
1916 nt_status = auth_info_2_trustauth_inout(mem_ctx,
1917 auth_info->incoming_count,
1918 auth_info->incoming_current_auth_info,
1920 ¤t_passwords);
1921 if (!NT_STATUS_IS_OK(nt_status)) {
1927 /* decode auth_info_int if set */
1928 if (auth_info_int) {
1930 /* now decrypt blob */
1931 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
1932 auth_info_int->auth_blob.size);
1934 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
1935 &auth_blob, &auth_struct);
1936 if (!NT_STATUS_IS_OK(nt_status)) {
1942 /* verify data matches */
1943 if (info_ex->trust_attributes &
1944 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1945 /* TODO: check what behavior level we have */
1946 if (strcasecmp_m(p_state->domain_dns,
1947 p_state->forest_dns) != 0) {
1948 return NT_STATUS_INVALID_DOMAIN_STATE;
1952 ret = samdb_rodc(p_state->sam_ldb, &am_rodc);
1953 if (ret == LDB_SUCCESS && am_rodc) {
1954 return NT_STATUS_NO_SUCH_DOMAIN;
1957 /* verify only one object matches the dns/netbios/sid
1958 * triplet and that this is the one we already have */
1959 nt_status = get_tdo(p_state->sam_ldb, mem_ctx,
1961 info_ex->domain_name.string,
1962 info_ex->netbios_name.string,
1963 info_ex->sid, &msgs);
1964 if (!NT_STATUS_IS_OK(nt_status)) {
1967 if (ldb_dn_compare(dom_msg->dn, msgs[0]->dn) != 0) {
1968 return NT_STATUS_OBJECT_NAME_COLLISION;
1973 /* TODO: should we fetch previous values from the existing entry
1974 * and append them ? */
1975 if (auth_info_int && auth_struct.incoming.count) {
1976 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1977 &auth_struct.incoming,
1978 &trustAuthIncoming);
1979 if (!NT_STATUS_IS_OK(nt_status)) {
1983 current_passwords = &auth_struct.incoming;
1986 trustAuthIncoming = data_blob(NULL, 0);
1989 if (auth_info_int && auth_struct.outgoing.count) {
1990 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1991 &auth_struct.outgoing,
1992 &trustAuthOutgoing);
1993 if (!NT_STATUS_IS_OK(nt_status)) {
1997 trustAuthOutgoing = data_blob(NULL, 0);
2000 msg = ldb_msg_new(mem_ctx);
2002 return NT_STATUS_NO_MEMORY;
2004 msg->dn = dom_msg->dn;
2007 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2010 *posix_offset, NULL);
2011 if (!NT_STATUS_IS_OK(nt_status)) {
2018 uint32_t changed_attrs;
2022 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2025 info_ex->trust_direction,
2027 if (!NT_STATUS_IS_OK(nt_status)) {
2031 if (info_ex->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
2032 if (auth_info != NULL && trustAuthIncoming.length > 0) {
2033 add_incoming = true;
2036 if (info_ex->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) {
2037 if (auth_info != NULL && trustAuthOutgoing.length > 0) {
2038 add_outgoing = true;
2042 if ((origdir & LSA_TRUST_DIRECTION_INBOUND) &&
2043 !(info_ex->trust_direction & LSA_TRUST_DIRECTION_INBOUND)) {
2044 del_incoming = true;
2046 if ((origdir & LSA_TRUST_DIRECTION_OUTBOUND) &&
2047 !(info_ex->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND)) {
2048 del_outgoing = true;
2051 origtype = ldb_msg_find_attr_as_int(dom_msg, "trustType", -1);
2052 if (origtype == -1 || origtype != info_ex->trust_type) {
2053 DEBUG(1, ("Attempted to change trust type! "
2054 "Operation not handled\n"));
2055 return NT_STATUS_INVALID_PARAMETER;
2058 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2061 info_ex->trust_attributes,
2063 if (!NT_STATUS_IS_OK(nt_status)) {
2066 /* TODO: check forestFunctionality from ldb opaque */
2067 /* TODO: check what is set makes sense */
2069 changed_attrs = origattrs ^ info_ex->trust_attributes;
2070 if (changed_attrs & ~LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2072 * For now we only allow
2073 * LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE to be changed.
2075 * TODO: we may need to support more attribute changes
2077 DEBUG(1, ("Attempted to change trust attributes "
2078 "(0x%08x != 0x%08x)! "
2079 "Operation not handled yet...\n",
2080 (unsigned)origattrs,
2081 (unsigned)info_ex->trust_attributes));
2082 return NT_STATUS_INVALID_PARAMETER;
2085 if (!(info_ex->trust_attributes &
2086 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE))
2088 struct ldb_message_element *orig_forest_el = NULL;
2090 orig_forest_el = ldb_msg_find_element(dom_msg,
2091 "msDS-TrustForestTrustInfo");
2092 if (orig_forest_el != NULL) {
2093 del_forest_info = true;
2099 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2101 "msDS-SupportedEncryptionTypes",
2103 if (!NT_STATUS_IS_OK(nt_status)) {
2108 if (add_incoming || del_incoming) {
2109 ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
2110 LDB_FLAG_MOD_REPLACE, NULL);
2111 if (ret != LDB_SUCCESS) {
2112 return NT_STATUS_NO_MEMORY;
2115 ret = ldb_msg_add_value(msg, "trustAuthIncoming",
2116 &trustAuthIncoming, NULL);
2117 if (ret != LDB_SUCCESS) {
2118 return NT_STATUS_NO_MEMORY;
2122 if (add_outgoing || del_outgoing) {
2123 ret = ldb_msg_add_empty(msg, "trustAuthOutgoing",
2124 LDB_FLAG_MOD_REPLACE, NULL);
2125 if (ret != LDB_SUCCESS) {
2126 return NT_STATUS_NO_MEMORY;
2129 ret = ldb_msg_add_value(msg, "trustAuthOutgoing",
2130 &trustAuthOutgoing, NULL);
2131 if (ret != LDB_SUCCESS) {
2132 return NT_STATUS_NO_MEMORY;
2136 if (del_forest_info) {
2137 ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo",
2138 LDB_FLAG_MOD_REPLACE, NULL);
2139 if (ret != LDB_SUCCESS) {
2140 return NT_STATUS_NO_MEMORY;
2144 /* start transaction */
2145 ret = ldb_transaction_start(p_state->sam_ldb);
2146 if (ret != LDB_SUCCESS) {
2147 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2149 in_transaction = true;
2151 if (msg->num_elements) {
2152 ret = ldb_modify(p_state->sam_ldb, msg);
2153 if (ret != LDB_SUCCESS) {
2154 DEBUG(1,("Failed to modify trusted domain record %s: %s\n",
2155 ldb_dn_get_linearized(msg->dn),
2156 ldb_errstring(p_state->sam_ldb)));
2157 nt_status = dsdb_ldb_err_to_ntstatus(ret);
2162 if (add_incoming || del_incoming) {
2163 const char *netbios_name;
2165 netbios_name = ldb_msg_find_attr_as_string(dom_msg,
2167 if (!netbios_name) {
2168 nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
2172 /* We use trustAuthIncoming.data to incidate that auth_struct.incoming is valid */
2173 nt_status = update_trust_user(mem_ctx,
2179 if (!NT_STATUS_IS_OK(nt_status)) {
2184 /* ok, all fine, commit transaction and return */
2185 ret = ldb_transaction_commit(p_state->sam_ldb);
2186 if (ret != LDB_SUCCESS) {
2187 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2189 in_transaction = false;
2191 nt_status = NT_STATUS_OK;
2194 if (in_transaction) {
2195 ldb_transaction_cancel(p_state->sam_ldb);
2201 lsa_SetInfomrationTrustedDomain
2203 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(
2204 struct dcesrv_call_state *dce_call,
2205 TALLOC_CTX *mem_ctx,
2206 struct lsa_SetInformationTrustedDomain *r)
2208 struct dcesrv_handle *h;
2209 struct lsa_trusted_domain_state *td_state;
2210 struct ldb_message **msgs;
2213 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle,
2214 LSA_HANDLE_TRUSTED_DOMAIN);
2216 td_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
2218 /* get the trusted domain object */
2219 nt_status = get_tdo(td_state->policy->sam_ldb, mem_ctx,
2220 td_state->trusted_domain_dn,
2221 NULL, NULL, NULL, &msgs);
2222 if (!NT_STATUS_IS_OK(nt_status)) {
2223 if (NT_STATUS_EQUAL(nt_status,
2224 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2227 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2230 return setInfoTrustedDomain_base(dce_call, td_state->policy, mem_ctx,
2231 msgs[0], r->in.level, r->in.info);
2236 lsa_DeleteTrustedDomain
2238 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2239 struct lsa_DeleteTrustedDomain *r)
2242 struct lsa_OpenTrustedDomain opn = {{0},{0}};
2243 struct lsa_DeleteObject del;
2244 struct dcesrv_handle *h;
2246 opn.in.handle = r->in.handle;
2247 opn.in.sid = r->in.dom_sid;
2248 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2249 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2250 if (!opn.out.trustdom_handle) {
2251 return NT_STATUS_NO_MEMORY;
2253 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
2254 if (!NT_STATUS_IS_OK(status)) {
2258 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2259 talloc_steal(mem_ctx, h);
2261 del.in.handle = opn.out.trustdom_handle;
2262 del.out.handle = opn.out.trustdom_handle;
2263 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
2264 if (!NT_STATUS_IS_OK(status)) {
2267 return NT_STATUS_OK;
2270 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
2271 struct ldb_message *msg,
2272 struct lsa_TrustDomainInfoInfoEx *info_ex)
2274 info_ex->domain_name.string
2275 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
2276 info_ex->netbios_name.string
2277 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2279 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
2280 info_ex->trust_direction
2281 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
2283 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
2284 info_ex->trust_attributes
2285 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
2286 return NT_STATUS_OK;
2290 lsa_QueryTrustedDomainInfo
2292 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2293 struct lsa_QueryTrustedDomainInfo *r)
2295 union lsa_TrustedDomainInfo *info = NULL;
2296 struct dcesrv_handle *h;
2297 struct lsa_trusted_domain_state *trusted_domain_state;
2298 struct ldb_message *msg;
2300 struct ldb_message **res;
2301 const char *attrs[] = {
2304 "securityIdentifier",
2308 "msDs-supportedEncryptionTypes",
2312 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
2314 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
2316 /* pull all the user attributes */
2317 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
2318 trusted_domain_state->trusted_domain_dn, &res, attrs);
2320 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2324 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
2326 return NT_STATUS_NO_MEMORY;
2328 *r->out.info = info;
2330 switch (r->in.level) {
2331 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2332 info->name.netbios_name.string
2333 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2335 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2336 info->posix_offset.posix_offset
2337 = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
2339 #if 0 /* Win2k3 doesn't implement this */
2340 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2341 r->out.info->info_basic.netbios_name.string
2342 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2343 r->out.info->info_basic.sid
2344 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
2347 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2348 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
2350 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2351 ZERO_STRUCT(info->full_info);
2352 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
2353 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2354 ZERO_STRUCT(info->full_info2_internal);
2355 info->full_info2_internal.posix_offset.posix_offset
2356 = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
2357 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
2359 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2360 info->enc_types.enc_types
2361 = ldb_msg_find_attr_as_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
2364 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2365 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2366 /* oops, we don't want to return the info after all */
2368 *r->out.info = NULL;
2369 return NT_STATUS_INVALID_PARAMETER;
2371 /* oops, we don't want to return the info after all */
2373 *r->out.info = NULL;
2374 return NT_STATUS_INVALID_INFO_CLASS;
2377 return NT_STATUS_OK;
2382 lsa_QueryTrustedDomainInfoBySid
2384 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2385 struct lsa_QueryTrustedDomainInfoBySid *r)
2388 struct lsa_OpenTrustedDomain opn = {{0},{0}};
2389 struct lsa_QueryTrustedDomainInfo query;
2390 struct dcesrv_handle *h;
2392 opn.in.handle = r->in.handle;
2393 opn.in.sid = r->in.dom_sid;
2394 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2395 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2396 if (!opn.out.trustdom_handle) {
2397 return NT_STATUS_NO_MEMORY;
2399 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
2400 if (!NT_STATUS_IS_OK(status)) {
2404 /* Ensure this handle goes away at the end of this call */
2405 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2406 talloc_steal(mem_ctx, h);
2408 query.in.trustdom_handle = opn.out.trustdom_handle;
2409 query.in.level = r->in.level;
2410 query.out.info = r->out.info;
2411 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2412 if (!NT_STATUS_IS_OK(status)) {
2416 return NT_STATUS_OK;
2420 lsa_SetTrustedDomainInfoByName
2422 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2423 TALLOC_CTX *mem_ctx,
2424 struct lsa_SetTrustedDomainInfoByName *r)
2426 struct dcesrv_handle *policy_handle;
2427 struct lsa_policy_state *policy_state;
2428 struct ldb_message **msgs;
2431 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2432 policy_state = policy_handle->data;
2434 /* get the trusted domain object */
2435 nt_status = get_tdo(policy_state->sam_ldb, mem_ctx,
2436 policy_state->domain_dn,
2437 r->in.trusted_domain->string,
2438 r->in.trusted_domain->string,
2440 if (!NT_STATUS_IS_OK(nt_status)) {
2441 if (NT_STATUS_EQUAL(nt_status,
2442 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2445 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2448 return setInfoTrustedDomain_base(dce_call, policy_state, mem_ctx,
2449 msgs[0], r->in.level, r->in.info);
2453 lsa_QueryTrustedDomainInfoByName
2455 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2456 TALLOC_CTX *mem_ctx,
2457 struct lsa_QueryTrustedDomainInfoByName *r)
2460 struct lsa_OpenTrustedDomainByName opn = {{0},{0}};
2461 struct lsa_QueryTrustedDomainInfo query;
2462 struct dcesrv_handle *h;
2464 opn.in.handle = r->in.handle;
2465 opn.in.name = *r->in.trusted_domain;
2466 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2467 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2468 if (!opn.out.trustdom_handle) {
2469 return NT_STATUS_NO_MEMORY;
2471 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
2472 if (!NT_STATUS_IS_OK(status)) {
2476 /* Ensure this handle goes away at the end of this call */
2477 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2478 talloc_steal(mem_ctx, h);
2480 query.in.trustdom_handle = opn.out.trustdom_handle;
2481 query.in.level = r->in.level;
2482 query.out.info = r->out.info;
2483 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2484 if (!NT_STATUS_IS_OK(status)) {
2488 return NT_STATUS_OK;
2492 lsa_CloseTrustedDomainEx
2494 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
2495 TALLOC_CTX *mem_ctx,
2496 struct lsa_CloseTrustedDomainEx *r)
2498 /* The result of a bad hair day from an IDL programmer? Not
2499 * implmented in Win2k3. You should always just lsa_Close
2501 return NT_STATUS_NOT_IMPLEMENTED;
2506 comparison function for sorting lsa_DomainInformation array
2508 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
2510 return strcasecmp_m(e1->name.string, e2->name.string);
2516 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2517 struct lsa_EnumTrustDom *r)
2519 struct dcesrv_handle *policy_handle;
2520 struct lsa_DomainInfo *entries;
2521 struct lsa_policy_state *policy_state;
2522 struct ldb_message **domains;
2523 const char *attrs[] = {
2525 "securityIdentifier",
2532 *r->out.resume_handle = 0;
2534 r->out.domains->domains = NULL;
2535 r->out.domains->count = 0;
2537 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2539 policy_state = policy_handle->data;
2541 /* search for all users in this domain. This could possibly be cached and
2542 resumed based on resume_key */
2543 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2544 "objectclass=trustedDomain");
2546 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2549 /* convert to lsa_TrustInformation format */
2550 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
2552 return NT_STATUS_NO_MEMORY;
2554 for (i=0;i<count;i++) {
2555 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
2556 entries[i].name.string = ldb_msg_find_attr_as_string(domains[i], "flatname", NULL);
2559 /* sort the results by name */
2560 TYPESAFE_QSORT(entries, count, compare_DomainInfo);
2562 if (*r->in.resume_handle >= count) {
2563 *r->out.resume_handle = -1;
2565 return NT_STATUS_NO_MORE_ENTRIES;
2568 /* return the rest, limit by max_size. Note that we
2569 use the w2k3 element size value of 60 */
2570 r->out.domains->count = count - *r->in.resume_handle;
2571 r->out.domains->count = MIN(r->out.domains->count,
2572 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
2574 r->out.domains->domains = entries + *r->in.resume_handle;
2576 if (r->out.domains->count < count - *r->in.resume_handle) {
2577 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2578 return STATUS_MORE_ENTRIES;
2581 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2582 * always be larger than the previous input resume handle, in
2583 * particular when hitting the last query it is vital to set the
2584 * resume handle correctly to avoid infinite client loops, as
2585 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2586 * status is NT_STATUS_OK - gd */
2588 *r->out.resume_handle = (uint32_t)-1;
2590 return NT_STATUS_OK;
2594 comparison function for sorting lsa_DomainInformation array
2596 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
2598 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
2602 lsa_EnumTrustedDomainsEx
2604 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2605 struct lsa_EnumTrustedDomainsEx *r)
2607 struct dcesrv_handle *policy_handle;
2608 struct lsa_TrustDomainInfoInfoEx *entries;
2609 struct lsa_policy_state *policy_state;
2610 struct ldb_message **domains;
2611 const char *attrs[] = {
2614 "securityIdentifier",
2624 *r->out.resume_handle = 0;
2626 r->out.domains->domains = NULL;
2627 r->out.domains->count = 0;
2629 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2631 policy_state = policy_handle->data;
2633 /* search for all users in this domain. This could possibly be cached and
2634 resumed based on resume_key */
2635 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2636 "objectclass=trustedDomain");
2638 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2641 /* convert to lsa_DomainInformation format */
2642 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
2644 return NT_STATUS_NO_MEMORY;
2646 for (i=0;i<count;i++) {
2647 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
2648 if (!NT_STATUS_IS_OK(nt_status)) {
2653 /* sort the results by name */
2654 TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
2656 if (*r->in.resume_handle >= count) {
2657 *r->out.resume_handle = -1;
2659 return NT_STATUS_NO_MORE_ENTRIES;
2662 /* return the rest, limit by max_size. Note that we
2663 use the w2k3 element size value of 60 */
2664 r->out.domains->count = count - *r->in.resume_handle;
2665 r->out.domains->count = MIN(r->out.domains->count,
2666 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
2668 r->out.domains->domains = entries + *r->in.resume_handle;
2670 if (r->out.domains->count < count - *r->in.resume_handle) {
2671 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2672 return STATUS_MORE_ENTRIES;
2675 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2677 return NT_STATUS_OK;
2684 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2685 struct lsa_OpenAccount *r)
2687 struct dcesrv_handle *h, *ah;
2688 struct lsa_policy_state *state;
2689 struct lsa_account_state *astate;
2691 ZERO_STRUCTP(r->out.acct_handle);
2693 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2697 astate = talloc(dce_call->conn, struct lsa_account_state);
2698 if (astate == NULL) {
2699 return NT_STATUS_NO_MEMORY;
2702 astate->account_sid = dom_sid_dup(astate, r->in.sid);
2703 if (astate->account_sid == NULL) {
2704 talloc_free(astate);
2705 return NT_STATUS_NO_MEMORY;
2708 astate->policy = talloc_reference(astate, state);
2709 astate->access_mask = r->in.access_mask;
2712 * For now we grant all requested access.
2714 * We will fail at the ldb layer later.
2716 if (astate->access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
2717 astate->access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
2718 astate->access_mask |= LSA_ACCOUNT_ALL_ACCESS;
2720 se_map_generic(&astate->access_mask, &dcesrv_lsa_account_mapping);
2722 DEBUG(10,("%s: %s access desired[0x%08X] granted[0x%08X] - success.\n",
2723 __func__, dom_sid_string(mem_ctx, astate->account_sid),
2724 (unsigned)r->in.access_mask,
2725 (unsigned)astate->access_mask));
2727 ah = dcesrv_handle_create(dce_call, LSA_HANDLE_ACCOUNT);
2729 talloc_free(astate);
2730 return NT_STATUS_NO_MEMORY;
2733 ah->data = talloc_steal(ah, astate);
2735 *r->out.acct_handle = ah->wire_handle;
2737 return NT_STATUS_OK;
2742 lsa_EnumPrivsAccount
2744 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
2745 TALLOC_CTX *mem_ctx,
2746 struct lsa_EnumPrivsAccount *r)
2748 struct dcesrv_handle *h;
2749 struct lsa_account_state *astate;
2752 struct ldb_message **res;
2753 const char * const attrs[] = { "privilege", NULL};
2754 struct ldb_message_element *el;
2756 struct lsa_PrivilegeSet *privs;
2758 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2762 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2763 if (privs == NULL) {
2764 return NT_STATUS_NO_MEMORY;
2770 *r->out.privs = privs;
2772 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
2773 if (sidstr == NULL) {
2774 return NT_STATUS_NO_MEMORY;
2777 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
2778 "objectSid=%s", sidstr);
2780 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2783 return NT_STATUS_OK;
2786 el = ldb_msg_find_element(res[0], "privilege");
2787 if (el == NULL || el->num_values == 0) {
2788 return NT_STATUS_OK;
2791 privs->set = talloc_array(privs,
2792 struct lsa_LUIDAttribute, el->num_values);
2793 if (privs->set == NULL) {
2794 return NT_STATUS_NO_MEMORY;
2798 for (i=0;i<el->num_values;i++) {
2799 int id = sec_privilege_id((const char *)el->values[i].data);
2800 if (id == SEC_PRIV_INVALID) {
2801 /* Perhaps an account right, not a privilege */
2804 privs->set[j].attribute = 0;
2805 privs->set[j].luid.low = id;
2806 privs->set[j].luid.high = 0;
2812 return NT_STATUS_OK;
2816 lsa_EnumAccountRights
2818 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
2819 TALLOC_CTX *mem_ctx,
2820 struct lsa_EnumAccountRights *r)
2822 struct dcesrv_handle *h;
2823 struct lsa_policy_state *state;
2826 struct ldb_message **res;
2827 const char * const attrs[] = { "privilege", NULL};
2829 struct ldb_message_element *el;
2831 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2835 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
2836 if (sidstr == NULL) {
2837 return NT_STATUS_NO_MEMORY;
2840 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2841 "(&(objectSid=%s)(privilege=*))", sidstr);
2843 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2846 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
2847 dom_sid_string(mem_ctx, r->in.sid),
2848 ldb_errstring(state->pdb)));
2849 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2852 el = ldb_msg_find_element(res[0], "privilege");
2853 if (el == NULL || el->num_values == 0) {
2854 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2857 r->out.rights->count = el->num_values;
2858 r->out.rights->names = talloc_array(r->out.rights,
2859 struct lsa_StringLarge, r->out.rights->count);
2860 if (r->out.rights->names == NULL) {
2861 return NT_STATUS_NO_MEMORY;
2864 for (i=0;i<el->num_values;i++) {
2865 r->out.rights->names[i].string = (const char *)el->values[i].data;
2868 return NT_STATUS_OK;
2874 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
2876 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
2877 TALLOC_CTX *mem_ctx,
2878 struct lsa_policy_state *state,
2880 struct dom_sid *sid,
2881 const struct lsa_RightSet *rights)
2883 struct auth_session_info *session_info =
2884 dcesrv_call_session_info(dce_call);
2885 const char *sidstr, *sidndrstr;
2886 struct ldb_message *msg;
2887 struct ldb_message_element *el;
2890 struct lsa_EnumAccountRights r2;
2893 if (security_session_user_level(session_info, NULL) <
2894 SECURITY_ADMINISTRATOR) {
2895 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
2896 return NT_STATUS_ACCESS_DENIED;
2899 msg = ldb_msg_new(mem_ctx);
2901 return NT_STATUS_NO_MEMORY;
2904 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
2905 if (sidndrstr == NULL) {
2907 return NT_STATUS_NO_MEMORY;
2910 sidstr = dom_sid_string(msg, sid);
2911 if (sidstr == NULL) {
2913 return NT_STATUS_NO_MEMORY;
2916 dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
2917 if (dnstr == NULL) {
2919 return NT_STATUS_NO_MEMORY;
2922 msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
2923 if (msg->dn == NULL) {
2925 return NT_STATUS_NO_MEMORY;
2928 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
2931 r2.in.handle = &state->handle->wire_handle;
2933 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
2935 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2936 if (!NT_STATUS_IS_OK(status)) {
2937 ZERO_STRUCTP(r2.out.rights);
2941 for (i=0;i<rights->count;i++) {
2944 ok = dcesrc_lsa_valid_AccountRight(rights->names[i].string);
2947 return NT_STATUS_NO_SUCH_PRIVILEGE;
2950 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
2952 for (j=0;j<r2.out.rights->count;j++) {
2953 if (strcasecmp_m(r2.out.rights->names[j].string,
2954 rights->names[i].string) == 0) {
2958 if (j != r2.out.rights->count) continue;
2961 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2962 if (ret != LDB_SUCCESS) {
2964 return NT_STATUS_NO_MEMORY;
2968 el = ldb_msg_find_element(msg, "privilege");
2971 return NT_STATUS_OK;
2974 el->flags = ldb_flag;
2976 ret = ldb_modify(state->pdb, msg);
2977 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
2978 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
2980 return NT_STATUS_NO_MEMORY;
2982 ldb_msg_add_string(msg, "comment", "added via LSA");
2983 ret = ldb_add(state->pdb, msg);
2985 if (ret != LDB_SUCCESS) {
2986 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2988 return NT_STATUS_OK;
2990 DEBUG(3, ("Could not %s attributes from %s: %s",
2991 LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2992 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
2994 return NT_STATUS_UNEXPECTED_IO_ERROR;
2998 return NT_STATUS_OK;
3002 lsa_AddPrivilegesToAccount
3004 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3005 struct lsa_AddPrivilegesToAccount *r)
3007 struct lsa_RightSet rights;
3008 struct dcesrv_handle *h;
3009 struct lsa_account_state *astate;
3012 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
3016 rights.count = r->in.privs->count;
3017 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
3018 if (rights.names == NULL) {
3019 return NT_STATUS_NO_MEMORY;
3021 for (i=0;i<rights.count;i++) {
3022 int id = r->in.privs->set[i].luid.low;
3023 if (r->in.privs->set[i].luid.high) {
3024 return NT_STATUS_NO_SUCH_PRIVILEGE;
3026 rights.names[i].string = sec_privilege_name(id);
3027 if (rights.names[i].string == NULL) {
3028 return NT_STATUS_NO_SUCH_PRIVILEGE;
3032 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
3033 LDB_FLAG_MOD_ADD, astate->account_sid,
3039 lsa_RemovePrivilegesFromAccount
3041 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3042 struct lsa_RemovePrivilegesFromAccount *r)
3044 struct lsa_RightSet *rights;
3045 struct dcesrv_handle *h;
3046 struct lsa_account_state *astate;
3049 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
3053 rights = talloc(mem_ctx, struct lsa_RightSet);
3055 if (r->in.remove_all == 1 &&
3056 r->in.privs == NULL) {
3057 struct lsa_EnumAccountRights r2;
3060 r2.in.handle = &astate->policy->handle->wire_handle;
3061 r2.in.sid = astate->account_sid;
3062 r2.out.rights = rights;
3064 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
3065 if (!NT_STATUS_IS_OK(status)) {
3069 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
3070 LDB_FLAG_MOD_DELETE, astate->account_sid,
3074 if (r->in.remove_all != 0) {
3075 return NT_STATUS_INVALID_PARAMETER;
3078 rights->count = r->in.privs->count;
3079 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
3080 if (rights->names == NULL) {
3081 return NT_STATUS_NO_MEMORY;
3083 for (i=0;i<rights->count;i++) {
3084 int id = r->in.privs->set[i].luid.low;
3085 if (r->in.privs->set[i].luid.high) {
3086 return NT_STATUS_NO_SUCH_PRIVILEGE;
3088 rights->names[i].string = sec_privilege_name(id);
3089 if (rights->names[i].string == NULL) {
3090 return NT_STATUS_NO_SUCH_PRIVILEGE;
3094 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
3095 LDB_FLAG_MOD_DELETE, astate->account_sid,
3101 lsa_GetQuotasForAccount
3103 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3104 struct lsa_GetQuotasForAccount *r)
3106 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3111 lsa_SetQuotasForAccount
3113 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3114 struct lsa_SetQuotasForAccount *r)
3116 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3121 lsa_GetSystemAccessAccount
3123 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3124 struct lsa_GetSystemAccessAccount *r)
3126 struct dcesrv_handle *h;
3127 struct lsa_account_state *astate;
3130 struct ldb_message **res;
3131 const char * const attrs[] = { "privilege", NULL};
3132 struct ldb_message_element *el;
3135 *(r->out.access_mask) = 0x00000000;
3137 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
3141 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
3142 if (sidstr == NULL) {
3143 return NT_STATUS_NO_MEMORY;
3146 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
3147 "objectSid=%s", sidstr);
3149 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3152 return NT_STATUS_OK;
3155 el = ldb_msg_find_element(res[0], "privilege");
3156 if (el == NULL || el->num_values == 0) {
3157 return NT_STATUS_OK;
3160 for (i=0;i<el->num_values;i++) {
3161 uint32_t right_bit = sec_right_bit((const char *)el->values[i].data);
3162 if (right_bit == 0) {
3163 /* Perhaps an privilege, not a right */
3166 *(r->out.access_mask) |= right_bit;
3169 return NT_STATUS_OK;
3174 lsa_SetSystemAccessAccount
3176 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3177 struct lsa_SetSystemAccessAccount *r)
3179 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3184 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3185 struct lsa_CreateSecret *r)
3187 struct auth_session_info *session_info =
3188 dcesrv_call_session_info(dce_call);
3189 struct dcesrv_handle *policy_handle;
3190 struct lsa_policy_state *policy_state;
3191 struct lsa_secret_state *secret_state;
3192 struct dcesrv_handle *handle;
3193 struct ldb_message **msgs, *msg;
3194 struct ldb_context *samdb = NULL;
3195 const char *attrs[] = {
3203 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3204 ZERO_STRUCTP(r->out.sec_handle);
3206 switch (security_session_user_level(session_info, NULL))
3208 case SECURITY_SYSTEM:
3209 case SECURITY_ADMINISTRATOR:
3212 /* Users and annonymous are not allowed create secrets */
3213 return NT_STATUS_ACCESS_DENIED;
3216 policy_state = policy_handle->data;
3218 if (!r->in.name.string) {
3219 return NT_STATUS_INVALID_PARAMETER;
3222 secret_state = talloc(mem_ctx, struct lsa_secret_state);
3223 NT_STATUS_HAVE_NO_MEMORY(secret_state);
3224 secret_state->policy = policy_state;
3226 msg = ldb_msg_new(mem_ctx);
3228 return NT_STATUS_NO_MEMORY;
3231 if (strncmp("G$", r->in.name.string, 2) == 0) {
3234 secret_state->global = true;
3236 name = &r->in.name.string[2];
3237 if (strlen(name) == 0) {
3238 return NT_STATUS_INVALID_PARAMETER;
3241 name2 = talloc_asprintf(mem_ctx, "%s Secret",
3242 ldb_binary_encode_string(mem_ctx, name));
3243 NT_STATUS_HAVE_NO_MEMORY(name2);
3246 * We need to connect to the database as system, as this is
3247 * one of the rare RPC calls that must read the secrets
3248 * (and this is denied otherwise)
3250 * We also save the current remote session details so they can
3251 * used by the audit logging module. This allows the audit
3252 * logging to report the remote users details, rather than the
3253 * system users details.
3255 samdb = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
3256 secret_state->sam_ldb = talloc_reference(secret_state, samdb);
3257 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
3259 /* search for the secret record */
3260 ret = gendb_search(secret_state->sam_ldb,
3261 mem_ctx, policy_state->system_dn, &msgs, attrs,
3262 "(&(cn=%s)(objectclass=secret))",
3265 return NT_STATUS_OBJECT_NAME_COLLISION;
3269 DEBUG(0,("Failure searching for CN=%s: %s\n",
3270 name2, ldb_errstring(secret_state->sam_ldb)));
3271 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3274 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
3275 NT_STATUS_HAVE_NO_MEMORY(msg->dn);
3276 if (!ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
3277 return NT_STATUS_NO_MEMORY;
3280 ret = ldb_msg_add_string(msg, "cn", name2);
3281 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
3283 secret_state->global = false;
3285 name = r->in.name.string;
3286 if (strlen(name) == 0) {
3287 return NT_STATUS_INVALID_PARAMETER;
3290 secret_state->sam_ldb = talloc_reference(secret_state,
3291 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, 0));
3292 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
3294 /* search for the secret record */
3295 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
3296 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
3298 "(&(cn=%s)(objectclass=secret))",
3299 ldb_binary_encode_string(mem_ctx, name));
3301 return NT_STATUS_OBJECT_NAME_COLLISION;
3305 DEBUG(0,("Failure searching for CN=%s: %s\n",
3306 name, ldb_errstring(secret_state->sam_ldb)));
3307 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3310 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb,
3311 "cn=%s,cn=LSA Secrets", name);
3312 NT_STATUS_HAVE_NO_MEMORY(msg->dn);
3313 ret = ldb_msg_add_string(msg, "cn", name);
3314 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
3317 ret = ldb_msg_add_string(msg, "objectClass", "secret");
3318 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
3320 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
3321 NT_STATUS_HAVE_NO_MEMORY(secret_state->secret_dn);
3323 /* create the secret */
3324 ret = ldb_add(secret_state->sam_ldb, msg);
3325 if (ret != LDB_SUCCESS) {
3326 DEBUG(0,("Failed to create secret record %s: %s\n",
3327 ldb_dn_get_linearized(msg->dn),
3328 ldb_errstring(secret_state->sam_ldb)));
3329 return NT_STATUS_ACCESS_DENIED;
3332 handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET);
3333 NT_STATUS_HAVE_NO_MEMORY(handle);
3335 handle->data = talloc_steal(handle, secret_state);
3337 secret_state->access_mask = r->in.access_mask;
3338 secret_state->policy = talloc_reference(secret_state, policy_state);
3339 NT_STATUS_HAVE_NO_MEMORY(secret_state->policy);
3341 *r->out.sec_handle = handle->wire_handle;
3343 return NT_STATUS_OK;
3350 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3351 struct lsa_OpenSecret *r)
3353 struct auth_session_info *session_info =
3354 dcesrv_call_session_info(dce_call);
3355 struct dcesrv_handle *policy_handle;
3356 struct lsa_policy_state *policy_state;
3357 struct lsa_secret_state *secret_state;
3358 struct dcesrv_handle *handle;
3359 struct ldb_message **msgs;
3360 struct ldb_context *samdb = NULL;
3361 const char *attrs[] = {
3367 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3368 ZERO_STRUCTP(r->out.sec_handle);
3369 policy_state = policy_handle->data;
3371 if (!r->in.name.string) {
3372 return NT_STATUS_INVALID_PARAMETER;
3375 switch (security_session_user_level(session_info, NULL))
3377 case SECURITY_SYSTEM:
3378 case SECURITY_ADMINISTRATOR:
3381 /* Users and annonymous are not allowed to access secrets */
3382 return NT_STATUS_ACCESS_DENIED;
3385 secret_state = talloc(mem_ctx, struct lsa_secret_state);
3386 if (!secret_state) {
3387 return NT_STATUS_NO_MEMORY;
3389 secret_state->policy = policy_state;
3391 if (strncmp("G$", r->in.name.string, 2) == 0) {
3392 name = &r->in.name.string[2];
3394 * We need to connect to the database as system, as this is
3395 * one of the rare RPC calls that must read the secrets
3396 * (and this is denied otherwise)
3398 * We also save the current remote session details so they can
3399 * used by the audit logging module. This allows the audit
3400 * logging to report the remote users details, rather than the
3401 * system users details.
3403 samdb = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
3404 secret_state->sam_ldb = talloc_reference(secret_state, samdb);
3405 secret_state->global = true;
3407 if (strlen(name) < 1) {
3408 return NT_STATUS_INVALID_PARAMETER;
3411 /* search for the secret record */
3412 ret = gendb_search(secret_state->sam_ldb,
3413 mem_ctx, policy_state->system_dn, &msgs, attrs,
3414 "(&(cn=%s Secret)(objectclass=secret))",
3415 ldb_binary_encode_string(mem_ctx, name));
3417 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3421 DEBUG(0,("Found %d records matching DN %s\n", ret,
3422 ldb_dn_get_linearized(policy_state->system_dn)));
3423 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3426 secret_state->global = false;
3427 secret_state->sam_ldb = talloc_reference(secret_state,
3428 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, 0));
3430 name = r->in.name.string;
3431 if (strlen(name) < 1) {
3432 return NT_STATUS_INVALID_PARAMETER;
3435 /* search for the secret record */
3436 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
3437 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
3439 "(&(cn=%s)(objectclass=secret))",
3440 ldb_binary_encode_string(mem_ctx, name));
3442 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3446 DEBUG(0,("Found %d records matching CN=%s\n",
3447 ret, ldb_binary_encode_string(mem_ctx, name)));
3448 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3452 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
3454 handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET);
3456 return NT_STATUS_NO_MEMORY;
3459 handle->data = talloc_steal(handle, secret_state);
3461 secret_state->access_mask = r->in.access_mask;
3462 secret_state->policy = talloc_reference(secret_state, policy_state);
3464 *r->out.sec_handle = handle->wire_handle;
3466 return NT_STATUS_OK;
3473 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3474 struct lsa_SetSecret *r)
3477 struct dcesrv_handle *h;
3478 struct lsa_secret_state *secret_state;
3479 struct ldb_message *msg;
3480 DATA_BLOB session_key;
3481 DATA_BLOB crypt_secret, secret;
3484 NTSTATUS status = NT_STATUS_OK;
3486 struct timeval now = timeval_current();
3487 NTTIME nt_now = timeval_to_nttime(&now);
3489 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3491 secret_state = h->data;
3493 msg = ldb_msg_new(mem_ctx);
3495 return NT_STATUS_NO_MEMORY;
3498 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
3500 return NT_STATUS_NO_MEMORY;
3502 status = dcesrv_transport_session_key(dce_call, &session_key);
3503 if (!NT_STATUS_IS_OK(status)) {
3507 if (r->in.old_val) {
3509 crypt_secret.data = r->in.old_val->data;
3510 crypt_secret.length = r->in.old_val->size;
3512 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3513 if (!NT_STATUS_IS_OK(status)) {
3517 val.data = secret.data;
3518 val.length = secret.length;
3521 if (ldb_msg_add_value(msg, "priorValue", &val, NULL) != LDB_SUCCESS) {
3522 return NT_STATUS_NO_MEMORY;
3525 /* set old value mtime */
3526 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3527 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3528 return NT_STATUS_NO_MEMORY;
3532 /* If the old value is not set, then migrate the
3533 * current value to the old value */
3534 const struct ldb_val *old_val;
3535 NTTIME last_set_time;
3536 struct ldb_message **res;
3537 const char *attrs[] = {
3543 /* search for the secret record */
3544 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
3545 secret_state->secret_dn, &res, attrs);
3547 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3551 DEBUG(0,("Found %d records matching dn=%s\n", ret,
3552 ldb_dn_get_linearized(secret_state->secret_dn)));
3553 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3556 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3557 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3561 if (ldb_msg_add_value(msg, "priorValue",
3562 old_val, NULL) != LDB_SUCCESS) {
3563 return NT_STATUS_NO_MEMORY;
3566 if (samdb_msg_add_delete(secret_state->sam_ldb,
3567 mem_ctx, msg, "priorValue") != LDB_SUCCESS) {
3568 return NT_STATUS_NO_MEMORY;
3572 /* set old value mtime */
3573 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
3574 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3575 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
3576 return NT_STATUS_NO_MEMORY;
3579 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3580 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3581 return NT_STATUS_NO_MEMORY;
3586 if (r->in.new_val) {
3588 crypt_secret.data = r->in.new_val->data;
3589 crypt_secret.length = r->in.new_val->size;
3591 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3592 if (!NT_STATUS_IS_OK(status)) {
3596 val.data = secret.data;
3597 val.length = secret.length;
3600 if (ldb_msg_add_value(msg, "currentValue", &val, NULL) != LDB_SUCCESS) {
3601 return NT_STATUS_NO_MEMORY;
3604 /* set new value mtime */
3605 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3606 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3607 return NT_STATUS_NO_MEMORY;
3610 /* NULL out the NEW value */
3611 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3612 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3613 return NT_STATUS_NO_MEMORY;
3615 if (samdb_msg_add_delete(secret_state->sam_ldb,
3616 mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
3617 return NT_STATUS_NO_MEMORY;
3621 /* modify the samdb record */
3622 ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
3623 if (ret != LDB_SUCCESS) {
3624 return dsdb_ldb_err_to_ntstatus(ret);
3627 return NT_STATUS_OK;
3634 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3635 struct lsa_QuerySecret *r)
3637 struct auth_session_info *session_info =
3638 dcesrv_call_session_info(dce_call);
3639 struct dcesrv_handle *h;
3640 struct lsa_secret_state *secret_state;
3641 struct ldb_message *msg;
3642 DATA_BLOB session_key;
3643 DATA_BLOB crypt_secret, secret;
3645 struct ldb_message **res;
3646 const char *attrs[] = {
3656 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3658 /* Ensure user is permitted to read this... */
3659 switch (security_session_user_level(session_info, NULL))
3661 case SECURITY_SYSTEM:
3662 case SECURITY_ADMINISTRATOR:
3665 /* Users and annonymous are not allowed to read secrets */
3666 return NT_STATUS_ACCESS_DENIED;
3669 secret_state = h->data;
3671 /* pull all the user attributes */
3672 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
3673 secret_state->secret_dn, &res, attrs);
3675 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3679 nt_status = dcesrv_transport_session_key(dce_call, &session_key);
3680 if (!NT_STATUS_IS_OK(nt_status)) {
3684 if (r->in.old_val) {
3685 const struct ldb_val *prior_val;
3686 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3687 if (!r->out.old_val) {
3688 return NT_STATUS_NO_MEMORY;
3690 prior_val = ldb_msg_find_ldb_val(msg, "priorValue");
3692 if (prior_val && prior_val->length) {
3693 secret.data = prior_val->data;
3694 secret.length = prior_val->length;
3697 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3698 if (!crypt_secret.length) {
3699 return NT_STATUS_NO_MEMORY;
3701 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3702 if (!r->out.old_val->buf) {
3703 return NT_STATUS_NO_MEMORY;
3705 r->out.old_val->buf->size = crypt_secret.length;
3706 r->out.old_val->buf->length = crypt_secret.length;
3707 r->out.old_val->buf->data = crypt_secret.data;
3711 if (r->in.old_mtime) {
3712 r->out.old_mtime = talloc(mem_ctx, NTTIME);
3713 if (!r->out.old_mtime) {
3714 return NT_STATUS_NO_MEMORY;
3716 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(msg, "priorSetTime", 0);
3719 if (r->in.new_val) {
3720 const struct ldb_val *new_val;
3721 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3722 if (!r->out.new_val) {
3723 return NT_STATUS_NO_MEMORY;
3726 new_val = ldb_msg_find_ldb_val(msg, "currentValue");
3728 if (new_val && new_val->length) {
3729 secret.data = new_val->data;
3730 secret.length = new_val->length;
3733 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3734 if (!crypt_secret.length) {
3735 return NT_STATUS_NO_MEMORY;
3737 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3738 if (!r->out.new_val->buf) {
3739 return NT_STATUS_NO_MEMORY;
3741 r->out.new_val->buf->length = crypt_secret.length;
3742 r->out.new_val->buf->size = crypt_secret.length;
3743 r->out.new_val->buf->data = crypt_secret.data;
3747 if (r->in.new_mtime) {
3748 r->out.new_mtime = talloc(mem_ctx, NTTIME);
3749 if (!r->out.new_mtime) {
3750 return NT_STATUS_NO_MEMORY;
3752 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(msg, "lastSetTime", 0);
3755 return NT_STATUS_OK;
3762 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
3763 TALLOC_CTX *mem_ctx,
3764 struct lsa_LookupPrivValue *r)
3766 struct dcesrv_handle *h;
3769 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3771 id = sec_privilege_id(r->in.name->string);
3772 if (id == SEC_PRIV_INVALID) {
3773 return NT_STATUS_NO_SUCH_PRIVILEGE;
3776 r->out.luid->low = id;
3777 r->out.luid->high = 0;
3779 return NT_STATUS_OK;
3786 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
3787 TALLOC_CTX *mem_ctx,
3788 struct lsa_LookupPrivName *r)
3790 struct dcesrv_handle *h;
3791 struct lsa_StringLarge *name;
3792 const char *privname;
3794 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3796 if (r->in.luid->high != 0) {
3797 return NT_STATUS_NO_SUCH_PRIVILEGE;
3800 privname = sec_privilege_name(r->in.luid->low);
3801 if (privname == NULL) {
3802 return NT_STATUS_NO_SUCH_PRIVILEGE;
3805 name = talloc(mem_ctx, struct lsa_StringLarge);
3807 return NT_STATUS_NO_MEMORY;
3810 name->string = privname;
3812 *r->out.name = name;
3814 return NT_STATUS_OK;
3819 lsa_LookupPrivDisplayName
3821 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
3822 TALLOC_CTX *mem_ctx,
3823 struct lsa_LookupPrivDisplayName *r)
3825 struct dcesrv_handle *h;
3826 struct lsa_StringLarge *disp_name = NULL;
3827 enum sec_privilege id;
3829 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3831 id = sec_privilege_id(r->in.name->string);
3832 if (id == SEC_PRIV_INVALID) {
3833 return NT_STATUS_NO_SUCH_PRIVILEGE;
3836 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
3837 if (disp_name == NULL) {
3838 return NT_STATUS_NO_MEMORY;
3841 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
3842 if (disp_name->string == NULL) {
3843 return NT_STATUS_INTERNAL_ERROR;
3846 *r->out.disp_name = disp_name;
3847 *r->out.returned_language_id = 0;
3849 return NT_STATUS_OK;
3854 lsa_EnumAccountsWithUserRight
3856 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
3857 TALLOC_CTX *mem_ctx,
3858 struct lsa_EnumAccountsWithUserRight *r)
3860 struct dcesrv_handle *h;
3861 struct lsa_policy_state *state;
3863 struct ldb_message **res;
3864 const char * const attrs[] = { "objectSid", NULL};
3865 const char *privname;
3868 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3872 if (r->in.name == NULL) {
3873 return NT_STATUS_NO_SUCH_PRIVILEGE;
3876 privname = r->in.name->string;
3878 ok = dcesrc_lsa_valid_AccountRight(privname);
3880 return NT_STATUS_NO_SUCH_PRIVILEGE;
3883 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
3884 "privilege=%s", privname);
3886 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3889 return NT_STATUS_NO_MORE_ENTRIES;
3892 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
3893 if (r->out.sids->sids == NULL) {
3894 return NT_STATUS_NO_MEMORY;
3896 for (i=0;i<ret;i++) {
3897 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
3898 res[i], "objectSid");
3899 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
3901 r->out.sids->num_sids = ret;
3903 return NT_STATUS_OK;
3908 lsa_AddAccountRights
3910 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
3911 TALLOC_CTX *mem_ctx,
3912 struct lsa_AddAccountRights *r)
3914 struct dcesrv_handle *h;
3915 struct lsa_policy_state *state;
3917 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3921 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3923 r->in.sid, r->in.rights);
3928 lsa_RemoveAccountRights
3930 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
3931 TALLOC_CTX *mem_ctx,
3932 struct lsa_RemoveAccountRights *r)
3934 struct dcesrv_handle *h;
3935 struct lsa_policy_state *state;
3937 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3941 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3942 LDB_FLAG_MOD_DELETE,
3943 r->in.sid, r->in.rights);
3948 lsa_StorePrivateData
3950 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3951 struct lsa_StorePrivateData *r)
3953 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3958 lsa_RetrievePrivateData
3960 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3961 struct lsa_RetrievePrivateData *r)
3963 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3970 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3971 struct lsa_GetUserName *r)
3973 enum dcerpc_transport_t transport =
3974 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
3975 struct auth_session_info *session_info =
3976 dcesrv_call_session_info(dce_call);
3977 NTSTATUS status = NT_STATUS_OK;
3978 const char *account_name;
3979 const char *authority_name;
3980 struct lsa_String *_account_name;
3981 struct lsa_String *_authority_name = NULL;
3983 if (transport != NCACN_NP && transport != NCALRPC) {
3984 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
3987 /* this is what w2k3 does */
3988 r->out.account_name = r->in.account_name;
3989 r->out.authority_name = r->in.authority_name;
3991 if (r->in.account_name
3992 && *r->in.account_name
3993 /* && *(*r->in.account_name)->string */
3995 return NT_STATUS_INVALID_PARAMETER;
3998 if (r->in.authority_name
3999 && *r->in.authority_name
4000 /* && *(*r->in.authority_name)->string */
4002 return NT_STATUS_INVALID_PARAMETER;
4005 account_name = talloc_reference(mem_ctx, session_info->info->account_name);
4006 authority_name = talloc_reference(mem_ctx, session_info->info->domain_name);
4008 _account_name = talloc(mem_ctx, struct lsa_String);
4009 NT_STATUS_HAVE_NO_MEMORY(_account_name);
4010 _account_name->string = account_name;
4012 if (r->in.authority_name) {
4013 _authority_name = talloc(mem_ctx, struct lsa_String);
4014 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
4015 _authority_name->string = authority_name;
4018 *r->out.account_name = _account_name;
4019 if (r->out.authority_name) {
4020 *r->out.authority_name = _authority_name;
4029 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
4030 TALLOC_CTX *mem_ctx,
4031 struct lsa_SetInfoPolicy2 *r)
4033 /* need to support these */
4034 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4037 static void kdc_get_policy(TALLOC_CTX *mem_ctx,
4038 struct loadparm_context *lp_ctx,
4039 struct smb_krb5_context *smb_krb5_context,
4040 struct lsa_DomainInfoKerberos *k)
4042 time_t svc_tkt_lifetime;
4043 time_t usr_tkt_lifetime;
4044 time_t renewal_lifetime;
4046 /* Our KDC always re-validates the client */
4047 k->authentication_options = LSA_POLICY_KERBEROS_VALIDATE_CLIENT;
4049 lpcfg_default_kdc_policy(mem_ctx, lp_ctx, &svc_tkt_lifetime,
4050 &usr_tkt_lifetime, &renewal_lifetime);
4052 unix_to_nt_time(&k->service_tkt_lifetime, svc_tkt_lifetime);
4053 unix_to_nt_time(&k->user_tkt_lifetime, usr_tkt_lifetime);
4054 unix_to_nt_time(&k->user_tkt_renewaltime, renewal_lifetime);
4055 #ifdef SAMBA4_USES_HEIMDAL /* MIT lacks krb5_get_max_time_skew.
4056 However in the parent function we basically just did a full
4057 krb5_context init with the only purpose of getting a global
4058 config option (the max skew), it would probably make more sense
4059 to have a lp_ or ldb global option as the samba default */
4060 if (smb_krb5_context) {
4061 unix_to_nt_time(&k->clock_skew,
4062 krb5_get_max_time_skew(smb_krb5_context->krb5_context));
4068 lsa_QueryDomainInformationPolicy
4070 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
4071 TALLOC_CTX *mem_ctx,
4072 struct lsa_QueryDomainInformationPolicy *r)
4074 union lsa_DomainInformationPolicy *info;
4076 info = talloc_zero(r->out.info, union lsa_DomainInformationPolicy);
4078 return NT_STATUS_NO_MEMORY;
4081 switch (r->in.level) {
4082 case LSA_DOMAIN_INFO_POLICY_EFS:
4084 *r->out.info = NULL;
4085 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4086 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
4088 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
4089 struct smb_krb5_context *smb_krb5_context;
4090 int ret = smb_krb5_init_context(mem_ctx,
4091 dce_call->conn->dce_ctx->lp_ctx,
4095 *r->out.info = NULL;
4096 return NT_STATUS_INTERNAL_ERROR;
4098 kdc_get_policy(mem_ctx, dce_call->conn->dce_ctx->lp_ctx,
4101 talloc_free(smb_krb5_context);
4102 *r->out.info = info;
4103 return NT_STATUS_OK;
4107 *r->out.info = NULL;
4108 return NT_STATUS_INVALID_INFO_CLASS;
4113 lsa_SetDomInfoPolicy
4115 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
4116 TALLOC_CTX *mem_ctx,
4117 struct lsa_SetDomainInformationPolicy *r)
4119 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4125 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
4126 TALLOC_CTX *mem_ctx,
4127 struct lsa_TestCall *r)
4129 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4135 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4136 struct lsa_CREDRWRITE *r)
4138 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4145 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4146 struct lsa_CREDRREAD *r)
4148 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4155 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4156 struct lsa_CREDRENUMERATE *r)
4158 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4163 lsa_CREDRWRITEDOMAINCREDENTIALS
4165 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4166 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
4168 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4173 lsa_CREDRREADDOMAINCREDENTIALS
4175 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4176 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
4178 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4185 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4186 struct lsa_CREDRDELETE *r)
4188 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4193 lsa_CREDRGETTARGETINFO
4195 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4196 struct lsa_CREDRGETTARGETINFO *r)
4198 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4203 lsa_CREDRPROFILELOADED
4205 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4206 struct lsa_CREDRPROFILELOADED *r)
4208 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4213 lsa_CREDRGETSESSIONTYPES
4215 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4216 struct lsa_CREDRGETSESSIONTYPES *r)
4218 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4223 lsa_LSARREGISTERAUDITEVENT
4225 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4226 struct lsa_LSARREGISTERAUDITEVENT *r)
4228 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4233 lsa_LSARGENAUDITEVENT
4235 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4236 struct lsa_LSARGENAUDITEVENT *r)
4238 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4243 lsa_LSARUNREGISTERAUDITEVENT
4245 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4246 struct lsa_LSARUNREGISTERAUDITEVENT *r)
4248 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4253 lsa_lsaRQueryForestTrustInformation
4255 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4256 struct lsa_lsaRQueryForestTrustInformation *r)
4258 struct dcesrv_handle *h = NULL;
4259 struct lsa_policy_state *p_state = NULL;
4260 int forest_level = DS_DOMAIN_FUNCTION_2000;
4261 const char * const trust_attrs[] = {
4262 "securityIdentifier",
4268 "msDS-TrustForestTrustInfo",
4271 struct ldb_message *trust_tdo_msg = NULL;
4272 struct lsa_TrustDomainInfoInfoEx *trust_tdo = NULL;
4273 struct ForestTrustInfo *trust_fti = NULL;
4274 struct lsa_ForestTrustInformation *trust_lfti = NULL;
4277 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4281 if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
4282 return NT_STATUS_INVALID_DOMAIN_STATE;
4285 forest_level = dsdb_forest_functional_level(p_state->sam_ldb);
4286 if (forest_level < DS_DOMAIN_FUNCTION_2003) {
4287 return NT_STATUS_INVALID_DOMAIN_STATE;
4290 if (r->in.trusted_domain_name->string == NULL) {
4291 return NT_STATUS_NO_SUCH_DOMAIN;
4294 status = dsdb_trust_search_tdo(p_state->sam_ldb,
4295 r->in.trusted_domain_name->string,
4296 r->in.trusted_domain_name->string,
4297 trust_attrs, mem_ctx, &trust_tdo_msg);
4298 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4299 return NT_STATUS_NO_SUCH_DOMAIN;
4301 if (!NT_STATUS_IS_OK(status)) {
4305 status = dsdb_trust_parse_tdo_info(mem_ctx, trust_tdo_msg, &trust_tdo);
4306 if (!NT_STATUS_IS_OK(status)) {
4310 if (!(trust_tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4311 return NT_STATUS_INVALID_PARAMETER;
4314 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4315 return NT_STATUS_INVALID_PARAMETER;
4318 status = dsdb_trust_parse_forest_info(mem_ctx,
4321 if (!NT_STATUS_IS_OK(status)) {
4325 status = dsdb_trust_forest_info_to_lsa(mem_ctx, trust_fti,
4327 if (!NT_STATUS_IS_OK(status)) {
4331 *r->out.forest_trust_info = trust_lfti;
4332 return NT_STATUS_OK;
4336 lsa_lsaRSetForestTrustInformation
4338 static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_state *dce_call,
4339 TALLOC_CTX *mem_ctx,
4340 struct lsa_lsaRSetForestTrustInformation *r)
4342 struct dcesrv_handle *h;
4343 struct lsa_policy_state *p_state;
4344 const char * const trust_attrs[] = {
4345 "securityIdentifier",
4351 "msDS-TrustForestTrustInfo",
4354 struct ldb_message *trust_tdo_msg = NULL;
4355 struct lsa_TrustDomainInfoInfoEx *trust_tdo = NULL;
4356 struct lsa_ForestTrustInformation *step1_lfti = NULL;
4357 struct lsa_ForestTrustInformation *step2_lfti = NULL;
4358 struct ForestTrustInfo *trust_fti = NULL;
4359 struct ldb_result *trusts_res = NULL;
4361 struct lsa_TrustDomainInfoInfoEx *xref_tdo = NULL;
4362 struct lsa_ForestTrustInformation *xref_lfti = NULL;
4363 struct lsa_ForestTrustCollisionInfo *c_info = NULL;
4364 DATA_BLOB ft_blob = {};
4365 struct ldb_message *msg = NULL;
4366 struct server_id *server_ids = NULL;
4367 uint32_t num_server_ids = 0;
4369 enum ndr_err_code ndr_err;
4371 bool in_transaction = false;
4373 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4377 if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
4378 return NT_STATUS_INVALID_DOMAIN_STATE;
4381 if (r->in.check_only == 0) {
4382 ret = ldb_transaction_start(p_state->sam_ldb);
4383 if (ret != LDB_SUCCESS) {
4384 return NT_STATUS_INTERNAL_DB_CORRUPTION;
4386 in_transaction = true;
4390 * abort if we are not a PDC
4392 * In future we should use a function like IsEffectiveRoleOwner()
4394 if (!samdb_is_pdc(p_state->sam_ldb)) {
4395 status = NT_STATUS_INVALID_DOMAIN_ROLE;
4399 if (r->in.trusted_domain_name->string == NULL) {
4400 status = NT_STATUS_NO_SUCH_DOMAIN;
4404 status = dsdb_trust_search_tdo(p_state->sam_ldb,
4405 r->in.trusted_domain_name->string,
4406 r->in.trusted_domain_name->string,
4407 trust_attrs, mem_ctx, &trust_tdo_msg);
4408 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4409 status = NT_STATUS_NO_SUCH_DOMAIN;
4412 if (!NT_STATUS_IS_OK(status)) {
4416 status = dsdb_trust_parse_tdo_info(mem_ctx, trust_tdo_msg, &trust_tdo);
4417 if (!NT_STATUS_IS_OK(status)) {
4421 if (!(trust_tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4422 status = NT_STATUS_INVALID_PARAMETER;
4426 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4427 status = NT_STATUS_INVALID_PARAMETER;
4432 * verify and normalize the given forest trust info.
4434 * Step1: doesn't reorder yet, so step1_lfti might contain
4435 * NULL entries. This means dsdb_trust_verify_forest_info()
4436 * can generate collision entries with the callers index.
4438 status = dsdb_trust_normalize_forest_info_step1(mem_ctx,
4439 r->in.forest_trust_info,
4441 if (!NT_STATUS_IS_OK(status)) {
4445 c_info = talloc_zero(r->out.collision_info,
4446 struct lsa_ForestTrustCollisionInfo);
4447 if (c_info == NULL) {
4448 status = NT_STATUS_NO_MEMORY;
4453 * First check our own forest, then other domains/forests
4456 status = dsdb_trust_xref_tdo_info(mem_ctx, p_state->sam_ldb,
4458 if (!NT_STATUS_IS_OK(status)) {
4461 status = dsdb_trust_xref_forest_info(mem_ctx, p_state->sam_ldb,
4463 if (!NT_STATUS_IS_OK(status)) {
4468 * The documentation proposed to generate
4469 * LSA_FOREST_TRUST_COLLISION_XREF collisions.
4470 * But Windows always uses LSA_FOREST_TRUST_COLLISION_TDO.
4472 status = dsdb_trust_verify_forest_info(xref_tdo, xref_lfti,
4473 LSA_FOREST_TRUST_COLLISION_TDO,
4474 c_info, step1_lfti);
4475 if (!NT_STATUS_IS_OK(status)) {
4479 /* fetch all other trusted domain objects */
4480 status = dsdb_trust_search_tdos(p_state->sam_ldb,
4481 trust_tdo->domain_name.string,
4483 mem_ctx, &trusts_res);
4484 if (!NT_STATUS_IS_OK(status)) {
4489 * now check against the other domains.
4490 * and generate LSA_FOREST_TRUST_COLLISION_TDO collisions.
4492 for (i = 0; i < trusts_res->count; i++) {
4493 struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
4494 struct ForestTrustInfo *fti = NULL;
4495 struct lsa_ForestTrustInformation *lfti = NULL;
4497 status = dsdb_trust_parse_tdo_info(mem_ctx,
4498 trusts_res->msgs[i],
4500 if (!NT_STATUS_IS_OK(status)) {
4504 status = dsdb_trust_parse_forest_info(tdo,
4505 trusts_res->msgs[i],
4507 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
4510 if (!NT_STATUS_IS_OK(status)) {
4514 status = dsdb_trust_forest_info_to_lsa(tdo, fti, &lfti);
4515 if (!NT_STATUS_IS_OK(status)) {
4519 status = dsdb_trust_verify_forest_info(tdo, lfti,
4520 LSA_FOREST_TRUST_COLLISION_TDO,
4521 c_info, step1_lfti);
4522 if (!NT_STATUS_IS_OK(status)) {
4529 if (r->in.check_only != 0) {
4530 status = NT_STATUS_OK;
4535 * not just a check, write info back
4539 * normalize the given forest trust info.
4541 * Step2: adds TOP_LEVEL_NAME[_EX] in reverse order,
4542 * followed by DOMAIN_INFO in reverse order. It also removes
4543 * possible NULL entries from Step1.
4545 status = dsdb_trust_normalize_forest_info_step2(mem_ctx, step1_lfti,
4547 if (!NT_STATUS_IS_OK(status)) {
4551 status = dsdb_trust_forest_info_from_lsa(mem_ctx, step2_lfti,
4553 if (!NT_STATUS_IS_OK(status)) {
4557 ndr_err = ndr_push_struct_blob(&ft_blob, mem_ctx, trust_fti,
4558 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4559 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4560 status = NT_STATUS_INVALID_PARAMETER;
4564 msg = ldb_msg_new(mem_ctx);
4566 status = NT_STATUS_NO_MEMORY;
4570 msg->dn = ldb_dn_copy(mem_ctx, trust_tdo_msg->dn);
4572 status = NT_STATUS_NO_MEMORY;
4576 ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo",
4577 LDB_FLAG_MOD_REPLACE, NULL);
4578 if (ret != LDB_SUCCESS) {
4579 status = NT_STATUS_NO_MEMORY;
4582 ret = ldb_msg_add_value(msg, "msDS-TrustForestTrustInfo",
4584 if (ret != LDB_SUCCESS) {
4585 status = NT_STATUS_NO_MEMORY;
4589 ret = ldb_modify(p_state->sam_ldb, msg);
4590 if (ret != LDB_SUCCESS) {
4591 status = dsdb_ldb_err_to_ntstatus(ret);
4593 DEBUG(0, ("Failed to store Forest Trust Info: %s\n",
4594 ldb_errstring(p_state->sam_ldb)));
4599 /* ok, all fine, commit transaction and return */
4600 in_transaction = false;
4601 ret = ldb_transaction_commit(p_state->sam_ldb);
4602 if (ret != LDB_SUCCESS) {
4603 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
4608 * Notify winbindd that we have a acquired forest trust info
4610 status = irpc_servers_byname(dce_call->msg_ctx,
4613 &num_server_ids, &server_ids);
4614 if (!NT_STATUS_IS_OK(status)) {
4615 DBG_ERR("irpc_servers_byname failed\n");
4619 imessaging_send(dce_call->msg_ctx, server_ids[0],
4620 MSG_WINBIND_RELOAD_TRUSTED_DOMAINS, NULL);
4622 status = NT_STATUS_OK;
4625 if (NT_STATUS_IS_OK(status) && c_info->count != 0) {
4626 *r->out.collision_info = c_info;
4629 if (in_transaction) {
4630 ldb_transaction_cancel(p_state->sam_ldb);
4639 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4640 struct lsa_CREDRRENAME *r)
4642 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4648 lsa_LSAROPENPOLICYSCE
4650 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4651 struct lsa_LSAROPENPOLICYSCE *r)
4653 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4658 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
4660 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4661 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4663 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4668 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
4670 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4671 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4673 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4678 lsa_LSARADTREPORTSECURITYEVENT
4680 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4681 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4683 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4687 /* include the generated boilerplate */
4688 #include "librpc/gen_ndr/ndr_lsa_s.c"
4692 /*****************************************
4693 NOTE! The remaining calls below were
4694 removed in w2k3, so the DCESRV_FAULT()
4695 replies are the correct implementation. Do
4696 not try and fill these in with anything else
4697 ******************************************/
4700 dssetup_DsRoleDnsNameToFlatName
4702 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4703 struct dssetup_DsRoleDnsNameToFlatName *r)
4705 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4710 dssetup_DsRoleDcAsDc
4712 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4713 struct dssetup_DsRoleDcAsDc *r)
4715 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4720 dssetup_DsRoleDcAsReplica
4722 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4723 struct dssetup_DsRoleDcAsReplica *r)
4725 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4730 dssetup_DsRoleDemoteDc
4732 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4733 struct dssetup_DsRoleDemoteDc *r)
4735 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4740 dssetup_DsRoleGetDcOperationProgress
4742 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4743 struct dssetup_DsRoleGetDcOperationProgress *r)
4745 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4750 dssetup_DsRoleGetDcOperationResults
4752 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4753 struct dssetup_DsRoleGetDcOperationResults *r)
4755 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4760 dssetup_DsRoleCancel
4762 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4763 struct dssetup_DsRoleCancel *r)
4765 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4770 dssetup_DsRoleServerSaveStateForUpgrade
4772 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4773 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
4775 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4780 dssetup_DsRoleUpgradeDownlevelServer
4782 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4783 struct dssetup_DsRoleUpgradeDownlevelServer *r)
4785 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4790 dssetup_DsRoleAbortDownlevelServerUpgrade
4792 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4793 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
4795 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4799 /* include the generated boilerplate */
4800 #include "librpc/gen_ndr/ndr_dssetup_s.c"
4802 NTSTATUS dcerpc_server_lsa_init(TALLOC_CTX *ctx)
4806 ret = dcerpc_server_dssetup_init(ctx);
4807 if (!NT_STATUS_IS_OK(ret)) {
4810 ret = dcerpc_server_lsarpc_init(ctx);
4811 if (!NT_STATUS_IS_OK(ret)) {