vfs_ceph_new: common prefix to debug-log messages
[Samba.git] / source4 / rpc_server / lsa / dcesrv_lsa.c
blob948e296eade963f59c2a5e551b2123336fac179e
1 /* need access mask/acl implementation */
3 /*
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/util/tsort.h"
31 #include "dsdb/common/util.h"
32 #include "libcli/security/session.h"
33 #include "libcli/lsarpc/util_lsarpc.h"
34 #include "lib/messaging/irpc.h"
35 #include "libds/common/roles.h"
36 #include "lib/util/smb_strtox.h"
37 #include "lib/param/loadparm.h"
38 #include "librpc/rpc/dcerpc_helper.h"
39 #include "librpc/rpc/dcerpc_lsa.h"
41 #include "lib/crypto/gnutls_helpers.h"
42 #include <gnutls/gnutls.h>
43 #include <gnutls/crypto.h>
45 #undef strcasecmp
47 #define DCESRV_INTERFACE_LSARPC_BIND(context, iface) \
48 dcesrv_interface_lsarpc_bind(context, iface)
49 static NTSTATUS dcesrv_interface_lsarpc_bind(struct dcesrv_connection_context *context,
50 const struct dcesrv_interface *iface)
52 return dcesrv_interface_bind_reject_connect(context, iface);
55 static NTSTATUS lsarpc__op_init_server(struct dcesrv_context *dce_ctx,
56 const struct dcesrv_endpoint_server *ep_server);
57 static const struct dcesrv_interface dcesrv_lsarpc_interface;
59 #define NCACN_NP_PIPE_NETLOGON "ncacn_np:[\\pipe\\netlogon]"
60 #define NCACN_NP_PIPE_LSASS "ncacn_np:[\\pipe\\lsass]"
61 #define DCESRV_INTERFACE_LSARPC_NCACN_NP_SECONDARY_ENDPOINT NCACN_NP_PIPE_LSASS
63 #define DCESRV_INTERFACE_LSARPC_INIT_SERVER \
64 dcesrv_interface_lsarpc_init_server
65 static NTSTATUS dcesrv_interface_lsarpc_init_server(struct dcesrv_context *dce_ctx,
66 const struct dcesrv_endpoint_server *ep_server)
68 if (lpcfg_lsa_over_netlogon(dce_ctx->lp_ctx)) {
69 NTSTATUS ret = dcesrv_interface_register(dce_ctx,
70 NCACN_NP_PIPE_NETLOGON,
71 NCACN_NP_PIPE_LSASS,
72 &dcesrv_lsarpc_interface, NULL);
73 if (!NT_STATUS_IS_OK(ret)) {
74 DEBUG(1,("lsarpc_op_init_server: failed to register endpoint '\\pipe\\netlogon'\n"));
75 return ret;
78 return lsarpc__op_init_server(dce_ctx, ep_server);
82 this type allows us to distinguish handle types
86 state associated with a lsa_OpenAccount() operation
88 struct lsa_account_state {
89 struct lsa_policy_state *policy;
90 uint32_t access_mask;
91 struct dom_sid *account_sid;
96 state associated with a lsa_OpenSecret() operation
98 struct lsa_secret_state {
99 struct lsa_policy_state *policy;
100 uint32_t access_mask;
101 struct ldb_dn *secret_dn;
102 struct ldb_context *sam_ldb;
103 bool global;
107 state associated with a lsa_OpenTrustedDomain() operation
109 struct lsa_trusted_domain_state {
110 struct lsa_policy_state *policy;
111 uint32_t access_mask;
112 struct ldb_dn *trusted_domain_dn;
113 struct ldb_dn *trusted_domain_user_dn;
116 static bool dcesrc_lsa_valid_AccountRight(const char *right)
118 enum sec_privilege priv_id;
119 uint32_t right_bit;
121 priv_id = sec_privilege_id(right);
122 if (priv_id != SEC_PRIV_INVALID) {
123 return true;
126 right_bit = sec_right_bit(right);
127 if (right_bit != 0) {
128 return true;
131 return false;
135 this is based on the samba3 function make_lsa_object_sd()
136 It uses the same logic, but with samba4 helper functions
138 static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
139 struct security_descriptor **sd,
140 struct dom_sid *sid,
141 uint32_t sid_access)
143 NTSTATUS status;
144 uint32_t rid;
145 struct dom_sid *domain_sid, *domain_admins_sid;
146 const char *domain_admins_sid_str, *sidstr;
147 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
149 status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
150 if (!NT_STATUS_IS_OK(status)) {
151 TALLOC_FREE(tmp_ctx);
152 return status;
155 domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
156 if (domain_admins_sid == NULL) {
157 TALLOC_FREE(tmp_ctx);
158 return NT_STATUS_NO_MEMORY;
161 domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
162 if (domain_admins_sid_str == NULL) {
163 TALLOC_FREE(tmp_ctx);
164 return NT_STATUS_NO_MEMORY;
167 sidstr = dom_sid_string(tmp_ctx, sid);
168 if (sidstr == NULL) {
169 TALLOC_FREE(tmp_ctx);
170 return NT_STATUS_NO_MEMORY;
173 *sd = security_descriptor_dacl_create(mem_ctx,
174 0, sidstr, NULL,
176 SID_WORLD,
177 SEC_ACE_TYPE_ACCESS_ALLOWED,
178 SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,
180 SID_BUILTIN_ADMINISTRATORS,
181 SEC_ACE_TYPE_ACCESS_ALLOWED,
182 SEC_GENERIC_ALL, 0,
184 SID_BUILTIN_ACCOUNT_OPERATORS,
185 SEC_ACE_TYPE_ACCESS_ALLOWED,
186 SEC_GENERIC_ALL, 0,
188 domain_admins_sid_str,
189 SEC_ACE_TYPE_ACCESS_ALLOWED,
190 SEC_GENERIC_ALL, 0,
192 sidstr,
193 SEC_ACE_TYPE_ACCESS_ALLOWED,
194 sid_access, 0,
196 NULL);
197 talloc_free(tmp_ctx);
199 NT_STATUS_HAVE_NO_MEMORY(*sd);
201 return NT_STATUS_OK;
205 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
206 TALLOC_CTX *mem_ctx,
207 struct lsa_EnumAccountRights *r);
209 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
210 TALLOC_CTX *mem_ctx,
211 struct lsa_policy_state *state,
212 int ldb_flag,
213 struct dom_sid *sid,
214 const struct lsa_RightSet *rights);
217 lsa_Close
219 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
220 struct lsa_Close *r)
222 enum dcerpc_transport_t transport =
223 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
224 struct dcesrv_handle *h;
226 if (transport != NCACN_NP && transport != NCALRPC) {
227 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
230 *r->out.handle = *r->in.handle;
232 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
234 talloc_free(h);
236 ZERO_STRUCTP(r->out.handle);
238 return NT_STATUS_OK;
243 lsa_Delete
245 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
246 struct lsa_Delete *r)
248 return NT_STATUS_NOT_SUPPORTED;
253 lsa_DeleteObject
255 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
256 struct lsa_DeleteObject *r)
258 struct auth_session_info *session_info =
259 dcesrv_call_session_info(dce_call);
260 struct dcesrv_handle *h;
261 int ret;
263 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
265 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
266 struct lsa_secret_state *secret_state = h->data;
268 /* Ensure user is permitted to delete this... */
269 switch (security_session_user_level(session_info, NULL))
271 case SECURITY_SYSTEM:
272 case SECURITY_ADMINISTRATOR:
273 break;
274 default:
275 /* Users and anonymous are not allowed to delete things */
276 return NT_STATUS_ACCESS_DENIED;
279 ret = ldb_delete(secret_state->sam_ldb,
280 secret_state->secret_dn);
281 if (ret != LDB_SUCCESS) {
282 return NT_STATUS_INVALID_HANDLE;
285 ZERO_STRUCTP(r->out.handle);
287 return NT_STATUS_OK;
289 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
290 struct lsa_trusted_domain_state *trusted_domain_state =
291 talloc_get_type(h->data, struct lsa_trusted_domain_state);
292 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
293 if (ret != LDB_SUCCESS) {
294 return NT_STATUS_INTERNAL_DB_CORRUPTION;
297 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
298 trusted_domain_state->trusted_domain_dn);
299 if (ret != LDB_SUCCESS) {
300 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
301 return NT_STATUS_INVALID_HANDLE;
304 if (trusted_domain_state->trusted_domain_user_dn) {
305 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
306 trusted_domain_state->trusted_domain_user_dn);
307 if (ret != LDB_SUCCESS) {
308 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
309 return NT_STATUS_INVALID_HANDLE;
313 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
314 if (ret != LDB_SUCCESS) {
315 return NT_STATUS_INTERNAL_DB_CORRUPTION;
318 ZERO_STRUCTP(r->out.handle);
320 return NT_STATUS_OK;
322 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
323 struct lsa_RightSet *rights;
324 struct lsa_account_state *astate;
325 struct lsa_EnumAccountRights r2;
326 NTSTATUS status;
328 rights = talloc(mem_ctx, struct lsa_RightSet);
330 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
332 astate = h->data;
334 r2.in.handle = &astate->policy->handle->wire_handle;
335 r2.in.sid = astate->account_sid;
336 r2.out.rights = rights;
338 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
339 but we have a LSA_HANDLE_ACCOUNT here, so this call
340 will always fail */
341 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
342 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
343 return NT_STATUS_OK;
346 if (!NT_STATUS_IS_OK(status)) {
347 return status;
350 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
351 LDB_FLAG_MOD_DELETE, astate->account_sid,
352 r2.out.rights);
353 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
354 return NT_STATUS_OK;
357 if (!NT_STATUS_IS_OK(status)) {
358 return status;
361 ZERO_STRUCTP(r->out.handle);
363 return NT_STATUS_OK;
366 return NT_STATUS_INVALID_HANDLE;
371 lsa_EnumPrivs
373 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
374 struct lsa_EnumPrivs *r)
376 struct dcesrv_handle *h;
377 uint32_t i;
378 enum sec_privilege priv;
379 const char *privname;
381 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
383 i = *r->in.resume_handle;
385 while (((priv = sec_privilege_from_index(i)) != SEC_PRIV_INVALID) &&
386 r->out.privs->count < r->in.max_count) {
387 struct lsa_PrivEntry *e;
388 privname = sec_privilege_name(priv);
389 r->out.privs->privs = talloc_realloc(r->out.privs,
390 r->out.privs->privs,
391 struct lsa_PrivEntry,
392 r->out.privs->count+1);
393 if (r->out.privs->privs == NULL) {
394 return NT_STATUS_NO_MEMORY;
396 e = &r->out.privs->privs[r->out.privs->count];
397 e->luid.low = priv;
398 e->luid.high = 0;
399 e->name.string = privname;
400 r->out.privs->count++;
401 i++;
404 *r->out.resume_handle = i;
406 return NT_STATUS_OK;
411 lsa_QuerySecObj
413 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
414 struct lsa_QuerySecurity *r)
416 struct auth_session_info *session_info =
417 dcesrv_call_session_info(dce_call);
418 struct dcesrv_handle *h;
419 const struct security_descriptor *sd = NULL;
420 uint32_t access_granted = 0;
421 struct sec_desc_buf *sdbuf = NULL;
422 NTSTATUS status;
423 struct dom_sid *sid;
425 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
427 sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
429 if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
430 struct lsa_policy_state *pstate = h->data;
432 sd = pstate->sd;
433 access_granted = pstate->access_mask;
435 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
436 struct lsa_account_state *astate = h->data;
437 struct security_descriptor *_sd = NULL;
439 status = dcesrv_build_lsa_sd(mem_ctx, &_sd, sid,
440 LSA_ACCOUNT_ALL_ACCESS);
441 if (!NT_STATUS_IS_OK(status)) {
442 return status;
444 sd = _sd;
445 access_granted = astate->access_mask;
446 } else {
447 return NT_STATUS_INVALID_HANDLE;
450 sdbuf = talloc_zero(mem_ctx, struct sec_desc_buf);
451 if (sdbuf == NULL) {
452 return NT_STATUS_NO_MEMORY;
455 status = security_descriptor_for_client(sdbuf, sd, r->in.sec_info,
456 access_granted, &sdbuf->sd);
457 if (!NT_STATUS_IS_OK(status)) {
458 return status;
461 *r->out.sdbuf = sdbuf;
463 return NT_STATUS_OK;
468 lsa_SetSecObj
470 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
471 struct lsa_SetSecObj *r)
473 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
478 lsa_ChangePassword
480 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
481 struct lsa_ChangePassword *r)
483 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
487 dssetup_DsRoleGetPrimaryDomainInformation
489 This is not an LSA call, but is the only call left on the DSSETUP
490 pipe (after the pipe was truncated), and needs lsa_get_policy_state
492 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
493 TALLOC_CTX *mem_ctx,
494 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
496 union dssetup_DsRoleInfo *info;
498 info = talloc_zero(mem_ctx, union dssetup_DsRoleInfo);
499 W_ERROR_HAVE_NO_MEMORY(info);
501 switch (r->in.level) {
502 case DS_ROLE_BASIC_INFORMATION:
504 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
505 uint32_t flags = 0;
506 const char *domain = NULL;
507 const char *dns_domain = NULL;
508 const char *forest = NULL;
509 struct GUID domain_guid;
510 struct lsa_policy_state *state;
512 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx,
513 0, /* we skip access checks */
514 &state);
515 if (!NT_STATUS_IS_OK(status)) {
516 return ntstatus_to_werror(status);
519 ZERO_STRUCT(domain_guid);
521 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
522 case ROLE_STANDALONE:
523 role = DS_ROLE_STANDALONE_SERVER;
524 break;
525 case ROLE_DOMAIN_MEMBER:
526 role = DS_ROLE_MEMBER_SERVER;
527 break;
528 case ROLE_ACTIVE_DIRECTORY_DC:
529 if (samdb_is_pdc(state->sam_ldb)) {
530 role = DS_ROLE_PRIMARY_DC;
531 } else {
532 role = DS_ROLE_BACKUP_DC;
534 break;
537 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
538 case ROLE_STANDALONE:
539 domain = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
540 W_ERROR_HAVE_NO_MEMORY(domain);
541 break;
542 case ROLE_DOMAIN_MEMBER:
543 domain = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
544 W_ERROR_HAVE_NO_MEMORY(domain);
545 /* TODO: what is with dns_domain and forest and guid? */
546 break;
547 case ROLE_ACTIVE_DIRECTORY_DC:
548 flags = DS_ROLE_PRIMARY_DS_RUNNING;
550 if (state->mixed_domain == 1) {
551 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
554 domain = state->domain_name;
555 dns_domain = state->domain_dns;
556 forest = state->forest_dns;
558 domain_guid = state->domain_guid;
559 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
560 break;
563 info->basic.role = role;
564 info->basic.flags = flags;
565 info->basic.domain = domain;
566 info->basic.dns_domain = dns_domain;
567 info->basic.forest = forest;
568 info->basic.domain_guid = domain_guid;
570 r->out.info = info;
571 return WERR_OK;
573 case DS_ROLE_UPGRADE_STATUS:
575 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
576 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
578 r->out.info = info;
579 return WERR_OK;
581 case DS_ROLE_OP_STATUS:
583 info->opstatus.status = DS_ROLE_OP_IDLE;
585 r->out.info = info;
586 return WERR_OK;
588 default:
589 return WERR_INVALID_PARAMETER;
594 fill in the AccountDomain info
596 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
597 struct lsa_DomainInfo *info)
599 info->name.string = state->domain_name;
600 info->sid = state->domain_sid;
602 return NT_STATUS_OK;
606 fill in the DNS domain info
608 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
609 struct lsa_DnsDomainInfo *info)
611 info->name.string = state->domain_name;
612 info->sid = state->domain_sid;
613 info->dns_domain.string = state->domain_dns;
614 info->dns_forest.string = state->forest_dns;
615 info->domain_guid = state->domain_guid;
617 return NT_STATUS_OK;
621 lsa_QueryInfoPolicy2
623 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
624 struct lsa_QueryInfoPolicy2 *r)
626 struct lsa_policy_state *state;
627 struct dcesrv_handle *h;
628 union lsa_PolicyInformation *info;
630 *r->out.info = NULL;
632 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
634 state = h->data;
636 info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
637 if (!info) {
638 return NT_STATUS_NO_MEMORY;
640 *r->out.info = info;
642 switch (r->in.level) {
643 case LSA_POLICY_INFO_AUDIT_LOG:
644 /* we don't need to fill in any of this */
645 ZERO_STRUCT(info->audit_log);
646 return NT_STATUS_OK;
647 case LSA_POLICY_INFO_AUDIT_EVENTS:
648 /* we don't need to fill in any of this */
649 ZERO_STRUCT(info->audit_events);
650 return NT_STATUS_OK;
651 case LSA_POLICY_INFO_PD:
652 /* we don't need to fill in any of this */
653 ZERO_STRUCT(info->pd);
654 return NT_STATUS_OK;
656 case LSA_POLICY_INFO_DOMAIN:
657 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
658 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
659 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
660 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
661 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
663 case LSA_POLICY_INFO_ROLE:
664 info->role.role = LSA_ROLE_PRIMARY;
665 return NT_STATUS_OK;
667 case LSA_POLICY_INFO_DNS:
668 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
669 case LSA_POLICY_INFO_DNS_INT:
670 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns_int);
672 case LSA_POLICY_INFO_REPLICA:
673 ZERO_STRUCT(info->replica);
674 return NT_STATUS_OK;
676 case LSA_POLICY_INFO_QUOTA:
677 ZERO_STRUCT(info->quota);
678 return NT_STATUS_OK;
680 case LSA_POLICY_INFO_MOD:
681 case LSA_POLICY_INFO_AUDIT_FULL_SET:
682 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
683 /* windows gives INVALID_PARAMETER */
684 *r->out.info = NULL;
685 return NT_STATUS_INVALID_PARAMETER;
688 *r->out.info = NULL;
689 return NT_STATUS_INVALID_INFO_CLASS;
693 lsa_QueryInfoPolicy
695 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
696 struct lsa_QueryInfoPolicy *r)
698 struct lsa_QueryInfoPolicy2 r2;
699 NTSTATUS status;
701 ZERO_STRUCT(r2);
703 r2.in.handle = r->in.handle;
704 r2.in.level = r->in.level;
705 r2.out.info = r->out.info;
707 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
709 return status;
713 lsa_SetInfoPolicy
715 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
716 struct lsa_SetInfoPolicy *r)
718 /* need to support this */
719 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
724 lsa_ClearAuditLog
726 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
727 struct lsa_ClearAuditLog *r)
729 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
733 static const struct generic_mapping dcesrv_lsa_account_mapping = {
734 LSA_ACCOUNT_READ,
735 LSA_ACCOUNT_WRITE,
736 LSA_ACCOUNT_EXECUTE,
737 LSA_ACCOUNT_ALL_ACCESS
741 lsa_CreateAccount
743 This call does not seem to have any long-term effects, hence no database operations
745 we need to talk to the MS product group to find out what this account database means!
747 answer is that the lsa database is totally separate from the SAM and
748 ldap databases. We are going to need a separate ldb to store these
749 accounts. The SIDs on this account bear no relation to the SIDs in
752 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
753 struct lsa_CreateAccount *r)
755 struct lsa_account_state *astate;
757 struct lsa_policy_state *state;
758 struct dcesrv_handle *h, *ah;
760 ZERO_STRUCTP(r->out.acct_handle);
762 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
764 state = h->data;
766 astate = talloc(dce_call->conn, struct lsa_account_state);
767 if (astate == NULL) {
768 return NT_STATUS_NO_MEMORY;
771 astate->account_sid = dom_sid_dup(astate, r->in.sid);
772 if (astate->account_sid == NULL) {
773 talloc_free(astate);
774 return NT_STATUS_NO_MEMORY;
777 astate->policy = talloc_reference(astate, state);
778 astate->access_mask = r->in.access_mask;
781 * For now we grant all requested access.
783 * We will fail at the ldb layer later.
785 if (astate->access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
786 astate->access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
787 astate->access_mask |= LSA_ACCOUNT_ALL_ACCESS;
789 se_map_generic(&astate->access_mask, &dcesrv_lsa_account_mapping);
791 DEBUG(10,("%s: %s access desired[0x%08X] granted[0x%08X].\n",
792 __func__, dom_sid_string(mem_ctx, astate->account_sid),
793 (unsigned)r->in.access_mask,
794 (unsigned)astate->access_mask));
796 ah = dcesrv_handle_create(dce_call, LSA_HANDLE_ACCOUNT);
797 if (!ah) {
798 talloc_free(astate);
799 return NT_STATUS_NO_MEMORY;
802 ah->data = talloc_steal(ah, astate);
804 *r->out.acct_handle = ah->wire_handle;
806 return NT_STATUS_OK;
811 lsa_EnumAccounts
813 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
814 struct lsa_EnumAccounts *r)
816 struct dcesrv_handle *h;
817 struct lsa_policy_state *state;
818 int ret;
819 struct ldb_message **res;
820 const char * const attrs[] = { "objectSid", NULL};
821 uint32_t count, i;
823 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
825 state = h->data;
827 /* NOTE: This call must only return accounts that have at least
828 one privilege set
830 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
831 "(&(objectSid=*)(privilege=*))");
832 if (ret < 0) {
833 return NT_STATUS_INTERNAL_DB_CORRUPTION;
836 if (*r->in.resume_handle >= ret) {
837 return NT_STATUS_NO_MORE_ENTRIES;
840 count = ret - *r->in.resume_handle;
841 if (count > r->in.num_entries) {
842 count = r->in.num_entries;
845 if (count == 0) {
846 return NT_STATUS_NO_MORE_ENTRIES;
849 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
850 if (r->out.sids->sids == NULL) {
851 return NT_STATUS_NO_MEMORY;
854 for (i=0;i<count;i++) {
855 r->out.sids->sids[i].sid =
856 samdb_result_dom_sid(r->out.sids->sids,
857 res[i + *r->in.resume_handle],
858 "objectSid");
859 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
862 r->out.sids->num_sids = count;
863 *r->out.resume_handle = count + *r->in.resume_handle;
865 return NT_STATUS_OK;
868 static NTSTATUS get_trustdom_auth_blob_aes(
869 struct dcesrv_call_state *dce_call,
870 TALLOC_CTX *mem_ctx,
871 struct lsa_TrustDomainInfoAuthInfoInternalAES *auth_info,
872 struct trustDomainPasswords *auth_struct)
874 DATA_BLOB session_key = data_blob_null;
875 DATA_BLOB salt = data_blob(auth_info->salt, sizeof(auth_info->salt));
876 DATA_BLOB auth_blob = data_blob(auth_info->cipher.data,
877 auth_info->cipher.size);
878 DATA_BLOB ciphertext = data_blob_null;
879 enum ndr_err_code ndr_err;
880 NTSTATUS status;
883 * The data blob starts with 512 bytes of random data and has two 32bit
884 * size parameters.
886 if (auth_blob.length < 520) {
887 return NT_STATUS_INVALID_PARAMETER;
890 status = dcesrv_transport_session_key(dce_call, &session_key);
891 if (!NT_STATUS_IS_OK(status)) {
892 return status;
895 status = samba_gnutls_aead_aes_256_cbc_hmac_sha512_decrypt(
896 mem_ctx,
897 &auth_blob,
898 &session_key,
899 &lsa_aes256_enc_key_salt,
900 &lsa_aes256_mac_key_salt,
901 &salt,
902 auth_info->auth_data,
903 &ciphertext);
904 if (!NT_STATUS_IS_OK(status)) {
905 return status;
908 ndr_err = ndr_pull_struct_blob(
909 &ciphertext,
910 mem_ctx,
911 auth_struct,
912 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
913 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
914 return NT_STATUS_INVALID_PARAMETER;
917 return NT_STATUS_OK;
920 /* This decrypts and returns Trusted Domain Auth Information Internal data */
921 static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
922 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
923 struct trustDomainPasswords *auth_struct)
925 DATA_BLOB session_key = data_blob(NULL, 0);
926 enum ndr_err_code ndr_err;
927 NTSTATUS nt_status;
928 gnutls_cipher_hd_t cipher_hnd = NULL;
929 gnutls_datum_t _session_key;
930 int rc;
931 struct auth_session_info *session_info =
932 dcesrv_call_session_info(dce_call);
933 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
934 bool encrypted;
936 encrypted =
937 dcerpc_is_transport_encrypted(session_info);
938 if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED &&
939 !encrypted) {
940 DBG_ERR("Transport isn't encrypted and weak crypto disallowed!\n");
941 return NT_STATUS_ACCESS_DENIED;
945 nt_status = dcesrv_transport_session_key(dce_call, &session_key);
946 if (!NT_STATUS_IS_OK(nt_status)) {
947 return nt_status;
950 _session_key = (gnutls_datum_t) {
951 .data = session_key.data,
952 .size = session_key.length,
955 GNUTLS_FIPS140_SET_LAX_MODE();
956 rc = gnutls_cipher_init(&cipher_hnd,
957 GNUTLS_CIPHER_ARCFOUR_128,
958 &_session_key,
959 NULL);
960 if (rc < 0) {
961 GNUTLS_FIPS140_SET_STRICT_MODE();
962 nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
963 goto out;
966 rc = gnutls_cipher_decrypt(cipher_hnd,
967 auth_blob->data,
968 auth_blob->length);
969 gnutls_cipher_deinit(cipher_hnd);
970 GNUTLS_FIPS140_SET_STRICT_MODE();
971 if (rc < 0) {
972 nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
973 goto out;
976 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
977 auth_struct,
978 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
979 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
980 return NT_STATUS_INVALID_PARAMETER;
983 nt_status = NT_STATUS_OK;
984 out:
985 return nt_status;
988 static NTSTATUS get_trustauth_inout_blob(struct dcesrv_call_state *dce_call,
989 TALLOC_CTX *mem_ctx,
990 struct trustAuthInOutBlob *iopw,
991 DATA_BLOB *trustauth_blob)
993 enum ndr_err_code ndr_err;
995 if (iopw->current.count != iopw->count) {
996 return NT_STATUS_INVALID_PARAMETER;
999 if (iopw->previous.count > iopw->current.count) {
1000 return NT_STATUS_INVALID_PARAMETER;
1003 if (iopw->previous.count == 0) {
1005 * If the previous credentials are not present
1006 * we need to make a copy.
1008 iopw->previous = iopw->current;
1011 if (iopw->previous.count < iopw->current.count) {
1012 struct AuthenticationInformationArray *c = &iopw->current;
1013 struct AuthenticationInformationArray *p = &iopw->previous;
1016 * The previous array needs to have the same size
1017 * as the current one.
1019 * We may have to fill with TRUST_AUTH_TYPE_NONE
1020 * elements.
1022 p->array = talloc_realloc(mem_ctx, p->array,
1023 struct AuthenticationInformation,
1024 c->count);
1025 if (p->array == NULL) {
1026 return NT_STATUS_NO_MEMORY;
1029 while (p->count < c->count) {
1030 struct AuthenticationInformation *a =
1031 &p->array[p->count++];
1033 *a = (struct AuthenticationInformation) {
1034 .LastUpdateTime = p->array[0].LastUpdateTime,
1035 .AuthType = TRUST_AUTH_TYPE_NONE,
1040 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
1041 iopw,
1042 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
1043 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1044 return NT_STATUS_INVALID_PARAMETER;
1047 return NT_STATUS_OK;
1050 static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx,
1051 struct ldb_context *sam_ldb,
1052 struct ldb_dn *base_dn,
1053 const char *netbios_name,
1054 struct trustAuthInOutBlob *in,
1055 struct ldb_dn **user_dn)
1057 struct ldb_request *req;
1058 struct ldb_message *msg;
1059 struct ldb_dn *dn;
1060 uint32_t i;
1061 int ret;
1063 dn = ldb_dn_copy(mem_ctx, base_dn);
1064 if (!dn) {
1065 return NT_STATUS_NO_MEMORY;
1067 if (!ldb_dn_add_child_fmt(dn, "cn=%s$,cn=users", netbios_name)) {
1068 return NT_STATUS_NO_MEMORY;
1071 msg = ldb_msg_new(mem_ctx);
1072 if (!msg) {
1073 return NT_STATUS_NO_MEMORY;
1075 msg->dn = dn;
1077 ret = ldb_msg_add_string(msg, "objectClass", "user");
1078 if (ret != LDB_SUCCESS) {
1079 return NT_STATUS_NO_MEMORY;
1082 ret = ldb_msg_add_fmt(msg, "samAccountName", "%s$", netbios_name);
1083 if (ret != LDB_SUCCESS) {
1084 return NT_STATUS_NO_MEMORY;
1087 ret = samdb_msg_add_uint(sam_ldb, msg, msg, "userAccountControl",
1088 UF_INTERDOMAIN_TRUST_ACCOUNT);
1089 if (ret != LDB_SUCCESS) {
1090 return NT_STATUS_NO_MEMORY;
1093 for (i = 0; i < in->count; i++) {
1094 const char *attribute;
1095 struct ldb_val v;
1096 switch (in->current.array[i].AuthType) {
1097 case TRUST_AUTH_TYPE_NT4OWF:
1098 attribute = "unicodePwd";
1099 v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
1100 v.length = 16;
1101 break;
1102 case TRUST_AUTH_TYPE_CLEAR:
1103 attribute = "clearTextPassword";
1104 v.data = in->current.array[i].AuthInfo.clear.password;
1105 v.length = in->current.array[i].AuthInfo.clear.size;
1106 break;
1107 default:
1108 continue;
1111 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
1112 if (ret != LDB_SUCCESS) {
1113 return NT_STATUS_NO_MEMORY;
1117 /* create the trusted_domain user account */
1118 ret = ldb_build_add_req(&req, sam_ldb, mem_ctx, msg, NULL, NULL,
1119 ldb_op_default_callback, NULL);
1120 if (ret != LDB_SUCCESS) {
1121 return NT_STATUS_NO_MEMORY;
1124 ret = ldb_request_add_control(req, DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID,
1125 false, NULL);
1126 if (ret != LDB_SUCCESS) {
1127 return NT_STATUS_NO_MEMORY;
1130 ret = dsdb_autotransaction_request(sam_ldb, req);
1131 if (ret != LDB_SUCCESS) {
1132 DEBUG(0,("Failed to create user record %s: %s\n",
1133 ldb_dn_get_linearized(msg->dn),
1134 ldb_errstring(sam_ldb)));
1136 switch (ret) {
1137 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1138 return NT_STATUS_DOMAIN_EXISTS;
1139 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1140 return NT_STATUS_ACCESS_DENIED;
1141 default:
1142 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1146 if (user_dn) {
1147 *user_dn = dn;
1149 return NT_STATUS_OK;
1152 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_precheck(
1153 TALLOC_CTX *mem_ctx,
1154 struct dcesrv_handle *policy_handle,
1155 struct lsa_TrustDomainInfoInfoEx *info)
1157 struct lsa_policy_state *policy_state = policy_handle->data;
1158 const char *netbios_name = NULL;
1159 const char *dns_name = NULL;
1160 bool ok;
1162 netbios_name = info->netbios_name.string;
1163 if (netbios_name == NULL) {
1164 return NT_STATUS_INVALID_PARAMETER;
1167 dns_name = info->domain_name.string;
1168 if (dns_name == NULL) {
1169 return NT_STATUS_INVALID_PARAMETER;
1172 if (info->sid == NULL) {
1173 return NT_STATUS_INVALID_SID;
1177 * We expect S-1-5-21-A-B-C, but we don't
1178 * allow S-1-5-21-0-0-0 as this is used
1179 * for claims and compound identities.
1181 ok = dom_sid_is_valid_account_domain(info->sid);
1182 if (!ok) {
1183 return NT_STATUS_INVALID_PARAMETER;
1186 if (strcasecmp(netbios_name, "BUILTIN") == 0 ||
1187 strcasecmp(dns_name, "BUILTIN") == 0 ||
1188 dom_sid_in_domain(policy_state->builtin_sid, info->sid))
1190 return NT_STATUS_INVALID_PARAMETER;
1193 if (strcasecmp(netbios_name, policy_state->domain_name) == 0 ||
1194 strcasecmp(netbios_name, policy_state->domain_dns) == 0 ||
1195 strcasecmp(dns_name, policy_state->domain_dns) == 0 ||
1196 strcasecmp(dns_name, policy_state->domain_name) == 0 ||
1197 dom_sid_equal(policy_state->domain_sid, info->sid))
1199 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
1202 return NT_STATUS_OK;
1205 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_common(struct dcesrv_call_state *dce_call,
1206 TALLOC_CTX *mem_ctx,
1207 struct dcesrv_handle *policy_handle,
1208 uint32_t access_mask,
1209 struct lsa_TrustDomainInfoInfoEx *info,
1210 struct trustDomainPasswords *auth_struct,
1211 struct policy_handle **ptrustdom_handle)
1213 struct lsa_policy_state *policy_state = policy_handle->data;
1214 struct ldb_context *sam_ldb = policy_state->sam_ldb;
1215 struct lsa_trusted_domain_state *trusted_domain_state = NULL;
1216 struct ldb_message **msgs, *msg;
1217 const char *attrs[] = {
1218 NULL
1220 const char *netbios_name = info->netbios_name.string;
1221 const char *dns_name = info->domain_name.string;
1222 DATA_BLOB trustAuthIncoming = data_blob_null;
1223 DATA_BLOB trustAuthOutgoing = data_blob_null;
1224 struct dcesrv_handle *handle = NULL;
1225 struct server_id *server_ids = NULL;
1226 uint32_t num_server_ids = 0;
1227 char *dns_encoded = NULL;
1228 char *netbios_encoded = NULL;
1229 char *sid_encoded = NULL;
1230 struct imessaging_context *imsg_ctx =
1231 dcesrv_imessaging_context(dce_call->conn);
1232 NTSTATUS status;
1233 bool ok;
1234 int ret;
1236 if (auth_struct->incoming.count) {
1237 status = get_trustauth_inout_blob(dce_call,
1238 mem_ctx,
1239 &auth_struct->incoming,
1240 &trustAuthIncoming);
1241 if (!NT_STATUS_IS_OK(status)) {
1242 return status;
1246 if (auth_struct->outgoing.count) {
1247 status = get_trustauth_inout_blob(dce_call,
1248 mem_ctx,
1249 &auth_struct->outgoing,
1250 &trustAuthOutgoing);
1251 if (!NT_STATUS_IS_OK(status)) {
1252 return status;
1256 dns_encoded = ldb_binary_encode_string(mem_ctx, dns_name);
1257 if (dns_encoded == NULL) {
1258 return NT_STATUS_NO_MEMORY;
1260 netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
1261 if (netbios_encoded == NULL) {
1262 return NT_STATUS_NO_MEMORY;
1264 sid_encoded = ldap_encode_ndr_dom_sid(mem_ctx, info->sid);
1265 if (sid_encoded == NULL) {
1266 return NT_STATUS_NO_MEMORY;
1269 trusted_domain_state = talloc_zero(mem_ctx,
1270 struct lsa_trusted_domain_state);
1271 if (trusted_domain_state == NULL) {
1272 return NT_STATUS_NO_MEMORY;
1274 trusted_domain_state->policy = policy_state;
1276 ret = ldb_transaction_start(sam_ldb);
1277 if (ret != LDB_SUCCESS) {
1278 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1281 /* search for the trusted_domain record */
1282 ret = gendb_search(sam_ldb,
1283 mem_ctx,
1284 policy_state->system_dn,
1285 &msgs,
1286 attrs,
1287 "(&(objectClass=trustedDomain)(|"
1288 "(flatname=%s)(trustPartner=%s)"
1289 "(flatname=%s)(trustPartner=%s)"
1290 "(securityIdentifier=%s)))",
1291 dns_encoded,
1292 dns_encoded,
1293 netbios_encoded,
1294 netbios_encoded,
1295 sid_encoded);
1296 if (ret > 0) {
1297 ldb_transaction_cancel(sam_ldb);
1298 return NT_STATUS_OBJECT_NAME_COLLISION;
1300 if (ret < 0) {
1301 ldb_transaction_cancel(sam_ldb);
1302 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1305 msg = ldb_msg_new(mem_ctx);
1306 if (msg == NULL) {
1307 return NT_STATUS_NO_MEMORY;
1310 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1311 if (msg->dn == NULL) {
1312 ldb_transaction_cancel(sam_ldb);
1313 return NT_STATUS_NO_MEMORY;
1316 ok = ldb_dn_add_child_fmt(msg->dn, "cn=%s", dns_name);
1317 if (!ok) {
1318 ldb_transaction_cancel(sam_ldb);
1319 return NT_STATUS_NO_MEMORY;
1322 ret = ldb_msg_add_string(msg, "objectClass", "trustedDomain");
1323 if (ret != LDB_SUCCESS) {
1324 ldb_transaction_cancel(sam_ldb);
1325 return NT_STATUS_NO_MEMORY;;
1328 ret = ldb_msg_add_string(msg, "flatname", netbios_name);
1329 if (ret != LDB_SUCCESS) {
1330 ldb_transaction_cancel(sam_ldb);
1331 return NT_STATUS_NO_MEMORY;
1334 ret = ldb_msg_add_string(msg, "trustPartner", dns_name);
1335 if (ret != LDB_SUCCESS) {
1336 ldb_transaction_cancel(sam_ldb);
1337 return NT_STATUS_NO_MEMORY;;
1340 ret = samdb_msg_add_dom_sid(
1341 sam_ldb, mem_ctx, msg, "securityIdentifier", info->sid);
1342 if (ret != LDB_SUCCESS) {
1343 ldb_transaction_cancel(sam_ldb);
1344 return NT_STATUS_NO_MEMORY;;
1347 ret = samdb_msg_add_int(
1348 sam_ldb, mem_ctx, msg, "trustType", info->trust_type);
1349 if (ret != LDB_SUCCESS) {
1350 ldb_transaction_cancel(sam_ldb);
1351 return NT_STATUS_NO_MEMORY;;
1354 ret = samdb_msg_add_int(sam_ldb,
1355 mem_ctx,
1356 msg,
1357 "trustAttributes",
1358 info->trust_attributes);
1359 if (ret != LDB_SUCCESS) {
1360 ldb_transaction_cancel(sam_ldb);
1361 return NT_STATUS_NO_MEMORY;;
1364 ret = samdb_msg_add_int(sam_ldb,
1365 mem_ctx,
1366 msg,
1367 "trustDirection",
1368 info->trust_direction);
1369 if (ret != LDB_SUCCESS) {
1370 ldb_transaction_cancel(sam_ldb);
1371 return NT_STATUS_NO_MEMORY;;
1374 if (trustAuthIncoming.length > 0) {
1375 ret = ldb_msg_add_value(msg,
1376 "trustAuthIncoming",
1377 &trustAuthIncoming,
1378 NULL);
1379 if (ret != LDB_SUCCESS) {
1380 ldb_transaction_cancel(sam_ldb);
1381 return NT_STATUS_NO_MEMORY;
1384 if (trustAuthOutgoing.length > 0) {
1385 ret = ldb_msg_add_value(msg,
1386 "trustAuthOutgoing",
1387 &trustAuthOutgoing,
1388 NULL);
1389 if (ret != LDB_SUCCESS) {
1390 ldb_transaction_cancel(sam_ldb);
1391 return NT_STATUS_NO_MEMORY;
1395 trusted_domain_state->trusted_domain_dn = ldb_dn_copy(
1396 trusted_domain_state, msg->dn);
1398 /* create the trusted_domain */
1399 ret = ldb_add(sam_ldb, msg);
1400 switch (ret) {
1401 case LDB_SUCCESS:
1402 break;
1403 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1404 ldb_transaction_cancel(sam_ldb);
1405 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1406 ldb_dn_get_linearized(msg->dn),
1407 ldb_errstring(sam_ldb)));
1408 return NT_STATUS_DOMAIN_EXISTS;
1409 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1410 ldb_transaction_cancel(sam_ldb);
1411 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1412 ldb_dn_get_linearized(msg->dn),
1413 ldb_errstring(sam_ldb)));
1414 return NT_STATUS_ACCESS_DENIED;
1415 default:
1416 ldb_transaction_cancel(sam_ldb);
1417 DEBUG(0,("Failed to create user record %s: %s\n",
1418 ldb_dn_get_linearized(msg->dn),
1419 ldb_errstring(sam_ldb)));
1420 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1423 if (info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1424 struct ldb_dn *user_dn;
1425 /* Inbound trusts must also create a cn=users object to match */
1426 status = add_trust_user(mem_ctx, sam_ldb,
1427 policy_state->domain_dn,
1428 netbios_name,
1429 &auth_struct->incoming,
1430 &user_dn);
1431 if (!NT_STATUS_IS_OK(status)) {
1432 ldb_transaction_cancel(sam_ldb);
1433 return status;
1436 /* save the trust user dn */
1437 trusted_domain_state->trusted_domain_user_dn
1438 = talloc_steal(trusted_domain_state, user_dn);
1441 ret = ldb_transaction_commit(sam_ldb);
1442 if (ret != LDB_SUCCESS) {
1443 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1447 * Notify winbindd that we have a new trust
1449 status = irpc_servers_byname(imsg_ctx,
1450 mem_ctx,
1451 "winbind_server",
1452 &num_server_ids,
1453 &server_ids);
1454 if (NT_STATUS_IS_OK(status) && num_server_ids >= 1) {
1455 imessaging_send(imsg_ctx,
1456 server_ids[0],
1457 MSG_WINBIND_RELOAD_TRUSTED_DOMAINS,
1458 NULL);
1460 TALLOC_FREE(server_ids);
1462 handle = dcesrv_handle_create(dce_call, LSA_HANDLE_TRUSTED_DOMAIN);
1463 if (handle == NULL) {
1464 return NT_STATUS_NO_MEMORY;
1467 handle->data = talloc_steal(handle, trusted_domain_state);
1469 trusted_domain_state->access_mask = access_mask;
1471 /* FIXME don't use talloc_reference */
1472 trusted_domain_state->policy = talloc_reference(trusted_domain_state,
1473 policy_state);
1474 NT_STATUS_HAVE_NO_MEMORY(trusted_domain_state->policy);
1476 *ptrustdom_handle = talloc_zero(mem_ctx, struct policy_handle);
1477 NT_STATUS_HAVE_NO_MEMORY(*ptrustdom_handle);
1479 **ptrustdom_handle = handle->wire_handle;
1481 return NT_STATUS_OK;
1485 lsa_CreateTrustedDomainEx2
1487 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1488 TALLOC_CTX *mem_ctx,
1489 struct lsa_CreateTrustedDomainEx2 *r)
1491 struct dcesrv_handle *policy_handle = NULL;
1492 struct trustDomainPasswords auth_struct = {
1493 .incoming_size = 0,
1495 DATA_BLOB auth_blob = data_blob_null;
1496 NTSTATUS status;
1498 ZERO_STRUCTP(r->out.trustdom_handle);
1499 DCESRV_PULL_HANDLE(policy_handle,
1500 r->in.policy_handle,
1501 LSA_HANDLE_POLICY);
1503 status = dcesrv_lsa_CreateTrustedDomain_precheck(mem_ctx,
1504 policy_handle,
1505 r->in.info);
1506 if (!NT_STATUS_IS_OK(status)) {
1507 return status;
1510 auth_blob = data_blob_const(r->in.auth_info_internal->auth_blob.data,
1511 r->in.auth_info_internal->auth_blob.size);
1513 status = get_trustdom_auth_blob(dce_call,
1514 mem_ctx,
1515 &auth_blob,
1516 &auth_struct);
1517 if (!NT_STATUS_IS_OK(status)) {
1518 return status;
1521 return dcesrv_lsa_CreateTrustedDomain_common(dce_call,
1522 mem_ctx,
1523 policy_handle,
1524 r->in.access_mask,
1525 r->in.info,
1526 &auth_struct,
1527 &r->out.trustdom_handle);
1530 lsa_CreateTrustedDomainEx
1532 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1533 TALLOC_CTX *mem_ctx,
1534 struct lsa_CreateTrustedDomainEx *r)
1537 * More investigation required here, do not create secrets for now.
1539 struct trustDomainPasswords auth_struct = {
1540 .incoming_size = 0,
1542 struct dcesrv_handle *policy_handle = NULL;
1543 NTSTATUS status;
1545 ZERO_STRUCTP(r->out.trustdom_handle);
1546 DCESRV_PULL_HANDLE(policy_handle,
1547 r->in.policy_handle,
1548 LSA_HANDLE_POLICY);
1550 status = dcesrv_lsa_CreateTrustedDomain_precheck(mem_ctx,
1551 policy_handle,
1552 r->in.info);
1553 if (!NT_STATUS_IS_OK(status)) {
1554 return status;
1557 if (r->in.auth_info->incoming_count > 1) {
1558 return NT_STATUS_INVALID_PARAMETER;
1561 return dcesrv_lsa_CreateTrustedDomain_common(
1562 dce_call,
1563 mem_ctx,
1564 policy_handle,
1565 r->in.access_mask,
1566 r->in.info,
1567 &auth_struct,
1568 &r->out.trustdom_handle);
1572 lsa_CreateTrustedDomain
1574 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1575 struct lsa_CreateTrustedDomain *r)
1577 struct trustDomainPasswords auth_struct = {
1578 .incoming_size = 0,
1580 struct dcesrv_handle *policy_handle = NULL;
1581 struct lsa_TrustDomainInfoInfoEx info = {
1582 .domain_name = r->in.info->name,
1583 .netbios_name = r->in.info->name,
1584 .sid = r->in.info->sid,
1585 .trust_direction = LSA_TRUST_DIRECTION_OUTBOUND,
1586 .trust_type = LSA_TRUST_TYPE_DOWNLEVEL,
1587 .trust_attributes = 0,
1589 NTSTATUS status;
1591 ZERO_STRUCTP(r->out.trustdom_handle);
1592 DCESRV_PULL_HANDLE(policy_handle,
1593 r->in.policy_handle,
1594 LSA_HANDLE_POLICY);
1596 status = dcesrv_lsa_CreateTrustedDomain_precheck(mem_ctx,
1597 policy_handle,
1598 &info);
1599 if (!NT_STATUS_IS_OK(status)) {
1600 return status;
1603 return dcesrv_lsa_CreateTrustedDomain_common(
1604 dce_call,
1605 mem_ctx,
1606 policy_handle,
1607 r->in.access_mask,
1608 &info,
1609 &auth_struct,
1610 &r->out.trustdom_handle);
1613 static NTSTATUS dcesrv_lsa_OpenTrustedDomain_common(
1614 struct dcesrv_call_state *dce_call,
1615 TALLOC_CTX *tmp_mem,
1616 struct lsa_policy_state *policy_state,
1617 const char *filter,
1618 uint32_t access_mask,
1619 struct dcesrv_handle **_handle)
1621 struct lsa_trusted_domain_state *trusted_domain_state;
1622 struct dcesrv_handle *handle;
1623 struct ldb_message **msgs;
1624 const char *attrs[] = {
1625 "trustDirection",
1626 "flatname",
1627 NULL
1629 uint32_t direction;
1630 int ret;
1632 /* TODO: perform access checks */
1634 /* search for the trusted_domain record */
1635 ret = gendb_search(policy_state->sam_ldb, tmp_mem,
1636 policy_state->system_dn,
1637 &msgs, attrs, "%s", filter);
1638 if (ret == 0) {
1639 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1642 if (ret != 1) {
1643 DEBUG(0,("Found %d records matching %s under %s\n", ret,
1644 filter,
1645 ldb_dn_get_linearized(policy_state->system_dn)));
1646 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1649 trusted_domain_state = talloc_zero(tmp_mem,
1650 struct lsa_trusted_domain_state);
1651 if (!trusted_domain_state) {
1652 return NT_STATUS_NO_MEMORY;
1654 trusted_domain_state->policy = policy_state;
1656 trusted_domain_state->trusted_domain_dn =
1657 talloc_steal(trusted_domain_state, msgs[0]->dn);
1659 direction = ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0);
1660 if (direction & LSA_TRUST_DIRECTION_INBOUND) {
1661 const char *flatname = ldb_msg_find_attr_as_string(msgs[0],
1662 "flatname", NULL);
1664 /* search for the trusted_domain account */
1665 ret = gendb_search(policy_state->sam_ldb, tmp_mem,
1666 policy_state->domain_dn,
1667 &msgs, attrs,
1668 "(&(samaccountname=%s$)(objectclass=user)"
1669 "(userAccountControl:%s:=%u))",
1670 flatname,
1671 LDB_OID_COMPARATOR_AND,
1672 UF_INTERDOMAIN_TRUST_ACCOUNT);
1673 if (ret == 1) {
1674 trusted_domain_state->trusted_domain_user_dn =
1675 talloc_steal(trusted_domain_state, msgs[0]->dn);
1679 handle = dcesrv_handle_create(dce_call, LSA_HANDLE_TRUSTED_DOMAIN);
1680 if (!handle) {
1681 return NT_STATUS_NO_MEMORY;
1684 handle->data = talloc_steal(handle, trusted_domain_state);
1686 trusted_domain_state->access_mask = access_mask;
1687 trusted_domain_state->policy = talloc_reference(trusted_domain_state,
1688 policy_state);
1690 *_handle = handle;
1692 return NT_STATUS_OK;
1696 lsa_OpenTrustedDomain
1698 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1699 struct lsa_OpenTrustedDomain *r)
1701 struct dcesrv_handle *policy_handle;
1702 struct lsa_policy_state *policy_state;
1703 struct dcesrv_handle *handle;
1704 const char *sid_string;
1705 char *filter;
1706 NTSTATUS status;
1708 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1709 ZERO_STRUCTP(r->out.trustdom_handle);
1710 policy_state = policy_handle->data;
1712 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1713 if (!sid_string) {
1714 return NT_STATUS_NO_MEMORY;
1717 filter = talloc_asprintf(mem_ctx,
1718 "(&(securityIdentifier=%s)"
1719 "(objectclass=trustedDomain))",
1720 sid_string);
1721 if (filter == NULL) {
1722 return NT_STATUS_NO_MEMORY;
1725 status = dcesrv_lsa_OpenTrustedDomain_common(dce_call, mem_ctx,
1726 policy_state,
1727 filter,
1728 r->in.access_mask,
1729 &handle);
1730 if (!NT_STATUS_IS_OK(status)) {
1731 return status;
1734 *r->out.trustdom_handle = handle->wire_handle;
1736 return NT_STATUS_OK;
1741 lsa_OpenTrustedDomainByName
1743 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1744 TALLOC_CTX *mem_ctx,
1745 struct lsa_OpenTrustedDomainByName *r)
1747 struct dcesrv_handle *policy_handle;
1748 struct lsa_policy_state *policy_state;
1749 struct dcesrv_handle *handle;
1750 char *td_name;
1751 char *filter;
1752 NTSTATUS status;
1754 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1755 ZERO_STRUCTP(r->out.trustdom_handle);
1756 policy_state = policy_handle->data;
1758 if (!r->in.name.string) {
1759 return NT_STATUS_INVALID_PARAMETER;
1762 /* search for the trusted_domain record */
1763 td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string);
1764 if (td_name == NULL) {
1765 return NT_STATUS_NO_MEMORY;
1768 filter = talloc_asprintf(mem_ctx,
1769 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))"
1770 "(objectclass=trustedDomain))",
1771 td_name, td_name, td_name);
1772 if (filter == NULL) {
1773 return NT_STATUS_NO_MEMORY;
1776 status = dcesrv_lsa_OpenTrustedDomain_common(dce_call, mem_ctx,
1777 policy_state,
1778 filter,
1779 r->in.access_mask,
1780 &handle);
1781 if (!NT_STATUS_IS_OK(status)) {
1782 return status;
1785 *r->out.trustdom_handle = handle->wire_handle;
1787 return NT_STATUS_OK;
1793 lsa_SetTrustedDomainInfo
1795 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1796 struct lsa_SetTrustedDomainInfo *r)
1798 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1803 /* parameters 4 to 6 are optional if the dn is a dn of a TDO object,
1804 * otherwise at least one must be provided */
1805 static NTSTATUS get_tdo(struct ldb_context *sam, TALLOC_CTX *mem_ctx,
1806 struct ldb_dn *basedn, const char *dns_domain,
1807 const char *netbios, struct dom_sid2 *sid,
1808 struct ldb_message ***msgs)
1810 const char *attrs[] = { "flatname", "trustPartner",
1811 "securityIdentifier", "trustDirection",
1812 "trustType", "trustAttributes",
1813 "trustPosixOffset",
1814 "msDs-supportedEncryptionTypes",
1815 "msDS-TrustForestTrustInfo",
1816 NULL
1818 char *dns = NULL;
1819 char *nbn = NULL;
1820 char *filter;
1821 int ret;
1824 if (dns_domain || netbios || sid) {
1825 filter = talloc_strdup(mem_ctx,
1826 "(&(objectclass=trustedDomain)(|");
1827 } else {
1828 filter = talloc_strdup(mem_ctx,
1829 "(objectclass=trustedDomain)");
1832 if (dns_domain) {
1833 dns = ldb_binary_encode_string(mem_ctx, dns_domain);
1834 if (!dns) {
1835 return NT_STATUS_NO_MEMORY;
1837 talloc_asprintf_addbuf(&filter, "(trustPartner=%s)", dns);
1839 if (netbios) {
1840 nbn = ldb_binary_encode_string(mem_ctx, netbios);
1841 if (!nbn) {
1842 return NT_STATUS_NO_MEMORY;
1844 talloc_asprintf_addbuf(&filter, "(flatname=%s)", nbn);
1846 if (sid) {
1847 struct dom_sid_buf buf;
1848 char *sidstr = dom_sid_str_buf(sid, &buf);
1849 talloc_asprintf_addbuf(
1850 &filter, "(securityIdentifier=%s)", sidstr);
1852 if (dns_domain || netbios || sid) {
1853 talloc_asprintf_addbuf(&filter, "))");
1855 if (filter == NULL) {
1856 return NT_STATUS_NO_MEMORY;
1859 ret = gendb_search(sam, mem_ctx, basedn, msgs, attrs, "%s", filter);
1860 if (ret == 0) {
1861 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1864 if (ret != 1) {
1865 return NT_STATUS_OBJECT_NAME_COLLISION;
1868 return NT_STATUS_OK;
1871 static NTSTATUS update_uint32_t_value(TALLOC_CTX *mem_ctx,
1872 struct ldb_context *sam_ldb,
1873 struct ldb_message *orig,
1874 struct ldb_message *dest,
1875 const char *attribute,
1876 uint32_t value,
1877 uint32_t *orig_value)
1879 const struct ldb_val *orig_val;
1880 uint32_t orig_uint = 0;
1881 unsigned int flags = 0;
1882 int ret;
1883 int error = 0;
1885 orig_val = ldb_msg_find_ldb_val(orig, attribute);
1886 if (!orig_val || !orig_val->data) {
1887 /* add new attribute */
1888 flags = LDB_FLAG_MOD_ADD;
1890 } else {
1891 orig_uint = smb_strtoul((const char *)orig_val->data,
1892 NULL,
1894 &error,
1895 SMB_STR_STANDARD);
1896 if (error != 0 || orig_uint != value) {
1897 /* replace also if can't get value */
1898 flags = LDB_FLAG_MOD_REPLACE;
1902 if (flags == 0) {
1903 /* stored value is identical, nothing to change */
1904 goto done;
1907 ret = samdb_msg_append_uint(sam_ldb, dest, dest, attribute, value, flags);
1908 if (ret != LDB_SUCCESS) {
1909 return NT_STATUS_NO_MEMORY;
1912 done:
1913 if (orig_value) {
1914 *orig_value = orig_uint;
1916 return NT_STATUS_OK;
1919 static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx,
1920 struct ldb_context *sam_ldb,
1921 struct ldb_dn *base_dn,
1922 bool delete_user,
1923 const char *netbios_name,
1924 struct trustAuthInOutBlob *in)
1926 const char *attrs[] = { "userAccountControl", NULL };
1927 struct ldb_message **msgs;
1928 struct ldb_message *msg;
1929 uint32_t uac;
1930 uint32_t i;
1931 int ret;
1933 ret = gendb_search(sam_ldb, mem_ctx,
1934 base_dn, &msgs, attrs,
1935 "samAccountName=%s$", netbios_name);
1936 if (ret > 1) {
1937 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1940 if (ret == 0) {
1941 if (delete_user) {
1942 return NT_STATUS_OK;
1945 /* ok no existing user, add it from scratch */
1946 return add_trust_user(mem_ctx, sam_ldb, base_dn,
1947 netbios_name, in, NULL);
1950 /* check user is what we are looking for */
1951 uac = ldb_msg_find_attr_as_uint(msgs[0],
1952 "userAccountControl", 0);
1953 if (!(uac & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
1954 return NT_STATUS_OBJECT_NAME_COLLISION;
1957 if (delete_user) {
1958 ret = ldb_delete(sam_ldb, msgs[0]->dn);
1959 switch (ret) {
1960 case LDB_SUCCESS:
1961 return NT_STATUS_OK;
1962 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1963 return NT_STATUS_ACCESS_DENIED;
1964 default:
1965 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1969 /* entry exists, just modify secret if any */
1970 if (in == NULL || in->count == 0) {
1971 return NT_STATUS_OK;
1974 msg = ldb_msg_new(mem_ctx);
1975 if (!msg) {
1976 return NT_STATUS_NO_MEMORY;
1978 msg->dn = msgs[0]->dn;
1980 for (i = 0; i < in->count; i++) {
1981 const char *attribute;
1982 struct ldb_val v;
1983 switch (in->current.array[i].AuthType) {
1984 case TRUST_AUTH_TYPE_NT4OWF:
1985 attribute = "unicodePwd";
1986 v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
1987 v.length = 16;
1988 break;
1989 case TRUST_AUTH_TYPE_CLEAR:
1990 attribute = "clearTextPassword";
1991 v.data = in->current.array[i].AuthInfo.clear.password;
1992 v.length = in->current.array[i].AuthInfo.clear.size;
1993 break;
1994 default:
1995 continue;
1998 ret = ldb_msg_append_value(msg, attribute, &v, LDB_FLAG_MOD_REPLACE);
1999 if (ret != LDB_SUCCESS) {
2000 return NT_STATUS_NO_MEMORY;
2004 /* create the trusted_domain user account */
2005 ret = ldb_modify(sam_ldb, msg);
2006 if (ret != LDB_SUCCESS) {
2007 DEBUG(0,("Failed to create user record %s: %s\n",
2008 ldb_dn_get_linearized(msg->dn),
2009 ldb_errstring(sam_ldb)));
2011 switch (ret) {
2012 case LDB_ERR_ENTRY_ALREADY_EXISTS:
2013 return NT_STATUS_DOMAIN_EXISTS;
2014 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
2015 return NT_STATUS_ACCESS_DENIED;
2016 default:
2017 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2021 return NT_STATUS_OK;
2025 static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call,
2026 struct lsa_policy_state *p_state,
2027 TALLOC_CTX *mem_ctx,
2028 struct ldb_message *dom_msg,
2029 enum lsa_TrustDomInfoEnum level,
2030 union lsa_TrustedDomainInfo *info)
2032 uint32_t *posix_offset = NULL;
2033 struct lsa_TrustDomainInfoInfoEx *info_ex = NULL;
2034 struct lsa_TrustDomainInfoAuthInfo *auth_info = NULL;
2035 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
2036 uint32_t *enc_types = NULL;
2037 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
2038 struct trustDomainPasswords auth_struct;
2039 struct trustAuthInOutBlob *current_passwords = NULL;
2040 NTSTATUS nt_status;
2041 struct ldb_message **msgs;
2042 struct ldb_message *msg;
2043 bool add_outgoing = false;
2044 bool add_incoming = false;
2045 bool del_outgoing = false;
2046 bool del_incoming = false;
2047 bool del_forest_info = false;
2048 bool in_transaction = false;
2049 int ret;
2050 bool am_rodc;
2052 switch (level) {
2053 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2054 posix_offset = &info->posix_offset.posix_offset;
2055 break;
2056 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2057 info_ex = &info->info_ex;
2058 break;
2059 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2060 auth_info = &info->auth_info;
2061 break;
2062 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2063 posix_offset = &info->full_info.posix_offset.posix_offset;
2064 info_ex = &info->full_info.info_ex;
2065 auth_info = &info->full_info.auth_info;
2066 break;
2067 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2068 auth_info_int = &info->auth_info_internal;
2069 break;
2070 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2071 posix_offset = &info->full_info_internal.posix_offset.posix_offset;
2072 info_ex = &info->full_info_internal.info_ex;
2073 auth_info_int = &info->full_info_internal.auth_info;
2074 break;
2075 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2076 enc_types = &info->enc_types.enc_types;
2077 break;
2078 default:
2079 return NT_STATUS_INVALID_PARAMETER;
2082 if (auth_info) {
2083 nt_status = auth_info_2_auth_blob(mem_ctx, auth_info,
2084 &trustAuthIncoming,
2085 &trustAuthOutgoing);
2086 if (!NT_STATUS_IS_OK(nt_status)) {
2087 return nt_status;
2089 if (trustAuthIncoming.data) {
2090 /* This does the decode of some of this twice, but it is easier that way */
2091 nt_status = auth_info_2_trustauth_inout(mem_ctx,
2092 auth_info->incoming_count,
2093 auth_info->incoming_current_auth_info,
2094 NULL,
2095 &current_passwords);
2096 if (!NT_STATUS_IS_OK(nt_status)) {
2097 return nt_status;
2102 /* decode auth_info_int if set */
2103 if (auth_info_int) {
2105 /* now decrypt blob */
2106 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
2107 auth_info_int->auth_blob.size);
2109 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
2110 &auth_blob, &auth_struct);
2111 if (!NT_STATUS_IS_OK(nt_status)) {
2112 return nt_status;
2116 if (info_ex) {
2117 /* verify data matches */
2118 if (info_ex->trust_attributes &
2119 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2120 /* TODO: check what behavior level we have */
2121 if (strcasecmp_m(p_state->domain_dns,
2122 p_state->forest_dns) != 0) {
2123 return NT_STATUS_INVALID_DOMAIN_STATE;
2127 ret = samdb_rodc(p_state->sam_ldb, &am_rodc);
2128 if (ret == LDB_SUCCESS && am_rodc) {
2129 return NT_STATUS_NO_SUCH_DOMAIN;
2132 /* verify only one object matches the dns/netbios/sid
2133 * triplet and that this is the one we already have */
2134 nt_status = get_tdo(p_state->sam_ldb, mem_ctx,
2135 p_state->system_dn,
2136 info_ex->domain_name.string,
2137 info_ex->netbios_name.string,
2138 info_ex->sid, &msgs);
2139 if (!NT_STATUS_IS_OK(nt_status)) {
2140 return nt_status;
2142 if (ldb_dn_compare(dom_msg->dn, msgs[0]->dn) != 0) {
2143 return NT_STATUS_OBJECT_NAME_COLLISION;
2145 talloc_free(msgs);
2148 /* TODO: should we fetch previous values from the existing entry
2149 * and append them ? */
2150 if (auth_info_int && auth_struct.incoming.count) {
2151 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
2152 &auth_struct.incoming,
2153 &trustAuthIncoming);
2154 if (!NT_STATUS_IS_OK(nt_status)) {
2155 return nt_status;
2158 current_passwords = &auth_struct.incoming;
2160 } else {
2161 trustAuthIncoming = data_blob(NULL, 0);
2164 if (auth_info_int && auth_struct.outgoing.count) {
2165 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
2166 &auth_struct.outgoing,
2167 &trustAuthOutgoing);
2168 if (!NT_STATUS_IS_OK(nt_status)) {
2169 return nt_status;
2171 } else {
2172 trustAuthOutgoing = data_blob(NULL, 0);
2175 msg = ldb_msg_new(mem_ctx);
2176 if (msg == NULL) {
2177 return NT_STATUS_NO_MEMORY;
2179 msg->dn = dom_msg->dn;
2181 if (posix_offset) {
2182 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2183 dom_msg, msg,
2184 "trustPosixOffset",
2185 *posix_offset, NULL);
2186 if (!NT_STATUS_IS_OK(nt_status)) {
2187 return nt_status;
2191 if (info_ex) {
2192 uint32_t origattrs;
2193 uint32_t changed_attrs;
2194 uint32_t origdir;
2195 int origtype;
2197 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2198 dom_msg, msg,
2199 "trustDirection",
2200 info_ex->trust_direction,
2201 &origdir);
2202 if (!NT_STATUS_IS_OK(nt_status)) {
2203 return nt_status;
2206 if (info_ex->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
2207 if (auth_info != NULL && trustAuthIncoming.length > 0) {
2208 add_incoming = true;
2211 if (info_ex->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) {
2212 if (auth_info != NULL && trustAuthOutgoing.length > 0) {
2213 add_outgoing = true;
2217 if ((origdir & LSA_TRUST_DIRECTION_INBOUND) &&
2218 !(info_ex->trust_direction & LSA_TRUST_DIRECTION_INBOUND)) {
2219 del_incoming = true;
2221 if ((origdir & LSA_TRUST_DIRECTION_OUTBOUND) &&
2222 !(info_ex->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND)) {
2223 del_outgoing = true;
2226 origtype = ldb_msg_find_attr_as_int(dom_msg, "trustType", -1);
2227 if (origtype == -1 || origtype != info_ex->trust_type) {
2228 DEBUG(1, ("Attempted to change trust type! "
2229 "Operation not handled\n"));
2230 return NT_STATUS_INVALID_PARAMETER;
2233 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2234 dom_msg, msg,
2235 "trustAttributes",
2236 info_ex->trust_attributes,
2237 &origattrs);
2238 if (!NT_STATUS_IS_OK(nt_status)) {
2239 return nt_status;
2241 /* TODO: check forestFunctionality from ldb opaque */
2242 /* TODO: check what is set makes sense */
2244 changed_attrs = origattrs ^ info_ex->trust_attributes;
2245 if (changed_attrs & ~LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2247 * For now we only allow
2248 * LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE to be changed.
2250 * TODO: we may need to support more attribute changes
2252 DEBUG(1, ("Attempted to change trust attributes "
2253 "(0x%08x != 0x%08x)! "
2254 "Operation not handled yet...\n",
2255 (unsigned)origattrs,
2256 (unsigned)info_ex->trust_attributes));
2257 return NT_STATUS_INVALID_PARAMETER;
2260 if (!(info_ex->trust_attributes &
2261 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE))
2263 struct ldb_message_element *orig_forest_el = NULL;
2265 orig_forest_el = ldb_msg_find_element(dom_msg,
2266 "msDS-TrustForestTrustInfo");
2267 if (orig_forest_el != NULL) {
2268 del_forest_info = true;
2273 if (enc_types) {
2274 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2275 dom_msg, msg,
2276 "msDS-SupportedEncryptionTypes",
2277 *enc_types, NULL);
2278 if (!NT_STATUS_IS_OK(nt_status)) {
2279 return nt_status;
2283 if (add_incoming || del_incoming) {
2284 if (add_incoming) {
2285 ret = ldb_msg_append_value(msg, "trustAuthIncoming",
2286 &trustAuthIncoming, LDB_FLAG_MOD_REPLACE);
2287 if (ret != LDB_SUCCESS) {
2288 return NT_STATUS_NO_MEMORY;
2290 } else {
2291 ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
2292 LDB_FLAG_MOD_REPLACE, NULL);
2293 if (ret != LDB_SUCCESS) {
2294 return NT_STATUS_NO_MEMORY;
2298 if (add_outgoing || del_outgoing) {
2299 if (add_outgoing) {
2300 ret = ldb_msg_append_value(msg, "trustAuthOutgoing",
2301 &trustAuthOutgoing, LDB_FLAG_MOD_REPLACE);
2302 if (ret != LDB_SUCCESS) {
2303 return NT_STATUS_NO_MEMORY;
2305 } else {
2306 ret = ldb_msg_add_empty(msg, "trustAuthOutgoing",
2307 LDB_FLAG_MOD_REPLACE, NULL);
2308 if (ret != LDB_SUCCESS) {
2309 return NT_STATUS_NO_MEMORY;
2313 if (del_forest_info) {
2314 ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo",
2315 LDB_FLAG_MOD_REPLACE, NULL);
2316 if (ret != LDB_SUCCESS) {
2317 return NT_STATUS_NO_MEMORY;
2321 /* start transaction */
2322 ret = ldb_transaction_start(p_state->sam_ldb);
2323 if (ret != LDB_SUCCESS) {
2324 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2326 in_transaction = true;
2328 if (msg->num_elements) {
2329 ret = ldb_modify(p_state->sam_ldb, msg);
2330 if (ret != LDB_SUCCESS) {
2331 DEBUG(1,("Failed to modify trusted domain record %s: %s\n",
2332 ldb_dn_get_linearized(msg->dn),
2333 ldb_errstring(p_state->sam_ldb)));
2334 nt_status = dsdb_ldb_err_to_ntstatus(ret);
2335 goto done;
2339 if (add_incoming || del_incoming) {
2340 const char *netbios_name;
2342 netbios_name = ldb_msg_find_attr_as_string(dom_msg,
2343 "flatname", NULL);
2344 if (!netbios_name) {
2345 nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
2346 goto done;
2349 /* We use trustAuthIncoming.data to indicate that auth_struct.incoming is valid */
2350 nt_status = update_trust_user(mem_ctx,
2351 p_state->sam_ldb,
2352 p_state->domain_dn,
2353 del_incoming,
2354 netbios_name,
2355 current_passwords);
2356 if (!NT_STATUS_IS_OK(nt_status)) {
2357 goto done;
2361 /* ok, all fine, commit transaction and return */
2362 ret = ldb_transaction_commit(p_state->sam_ldb);
2363 if (ret != LDB_SUCCESS) {
2364 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2366 in_transaction = false;
2368 nt_status = NT_STATUS_OK;
2370 done:
2371 if (in_transaction) {
2372 ldb_transaction_cancel(p_state->sam_ldb);
2374 return nt_status;
2378 lsa_SetInformationTrustedDomain
2380 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(
2381 struct dcesrv_call_state *dce_call,
2382 TALLOC_CTX *mem_ctx,
2383 struct lsa_SetInformationTrustedDomain *r)
2385 struct dcesrv_handle *h;
2386 struct lsa_trusted_domain_state *td_state;
2387 struct ldb_message **msgs;
2388 NTSTATUS nt_status;
2390 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle,
2391 LSA_HANDLE_TRUSTED_DOMAIN);
2393 td_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
2395 /* get the trusted domain object */
2396 nt_status = get_tdo(td_state->policy->sam_ldb, mem_ctx,
2397 td_state->trusted_domain_dn,
2398 NULL, NULL, NULL, &msgs);
2399 if (!NT_STATUS_IS_OK(nt_status)) {
2400 if (NT_STATUS_EQUAL(nt_status,
2401 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2402 return nt_status;
2404 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2407 return setInfoTrustedDomain_base(dce_call, td_state->policy, mem_ctx,
2408 msgs[0], r->in.level, r->in.info);
2413 lsa_DeleteTrustedDomain
2415 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2416 struct lsa_DeleteTrustedDomain *r)
2418 NTSTATUS status;
2419 struct lsa_OpenTrustedDomain opn = {{0},{0}};
2420 struct lsa_DeleteObject del;
2421 struct dcesrv_handle *h;
2423 opn.in.handle = r->in.handle;
2424 opn.in.sid = r->in.dom_sid;
2425 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2426 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2427 if (!opn.out.trustdom_handle) {
2428 return NT_STATUS_NO_MEMORY;
2430 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
2431 if (!NT_STATUS_IS_OK(status)) {
2432 return status;
2435 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2436 talloc_steal(mem_ctx, h);
2438 del.in.handle = opn.out.trustdom_handle;
2439 del.out.handle = opn.out.trustdom_handle;
2440 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
2441 if (!NT_STATUS_IS_OK(status)) {
2442 return status;
2444 return NT_STATUS_OK;
2447 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
2448 struct ldb_message *msg,
2449 struct lsa_TrustDomainInfoInfoEx *info_ex)
2451 info_ex->domain_name.string
2452 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
2453 info_ex->netbios_name.string
2454 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2455 info_ex->sid
2456 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
2457 info_ex->trust_direction
2458 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
2459 info_ex->trust_type
2460 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
2461 info_ex->trust_attributes
2462 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
2463 return NT_STATUS_OK;
2467 lsa_QueryTrustedDomainInfo
2469 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2470 struct lsa_QueryTrustedDomainInfo *r)
2472 union lsa_TrustedDomainInfo *info = NULL;
2473 struct dcesrv_handle *h;
2474 struct lsa_trusted_domain_state *trusted_domain_state;
2475 struct ldb_message *msg;
2476 int ret;
2477 struct ldb_message **res;
2478 const char *attrs[] = {
2479 "flatname",
2480 "trustPartner",
2481 "securityIdentifier",
2482 "trustDirection",
2483 "trustType",
2484 "trustAttributes",
2485 "msDs-supportedEncryptionTypes",
2486 NULL
2489 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
2491 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
2493 /* pull all the user attributes */
2494 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
2495 trusted_domain_state->trusted_domain_dn, &res, attrs);
2496 if (ret != 1) {
2497 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2499 msg = res[0];
2501 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
2502 if (!info) {
2503 return NT_STATUS_NO_MEMORY;
2505 *r->out.info = info;
2507 switch (r->in.level) {
2508 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2509 info->name.netbios_name.string
2510 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2511 break;
2512 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2513 info->posix_offset.posix_offset
2514 = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
2515 break;
2516 #if 0 /* Win2k3 doesn't implement this */
2517 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2518 r->out.info->info_basic.netbios_name.string
2519 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2520 r->out.info->info_basic.sid
2521 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
2522 break;
2523 #endif
2524 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2525 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
2527 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2528 ZERO_STRUCT(info->full_info);
2529 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
2530 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2531 ZERO_STRUCT(info->full_info2_internal);
2532 info->full_info2_internal.posix_offset.posix_offset
2533 = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
2534 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
2536 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2537 info->enc_types.enc_types
2538 = ldb_msg_find_attr_as_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
2539 break;
2541 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2542 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2543 /* oops, we don't want to return the info after all */
2544 talloc_free(info);
2545 *r->out.info = NULL;
2546 return NT_STATUS_INVALID_PARAMETER;
2547 default:
2548 /* oops, we don't want to return the info after all */
2549 talloc_free(info);
2550 *r->out.info = NULL;
2551 return NT_STATUS_INVALID_INFO_CLASS;
2554 return NT_STATUS_OK;
2559 lsa_QueryTrustedDomainInfoBySid
2561 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2562 struct lsa_QueryTrustedDomainInfoBySid *r)
2564 NTSTATUS status;
2565 struct lsa_OpenTrustedDomain opn = {{0},{0}};
2566 struct lsa_QueryTrustedDomainInfo query;
2567 struct dcesrv_handle *h;
2569 opn.in.handle = r->in.handle;
2570 opn.in.sid = r->in.dom_sid;
2571 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2572 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2573 if (!opn.out.trustdom_handle) {
2574 return NT_STATUS_NO_MEMORY;
2576 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
2577 if (!NT_STATUS_IS_OK(status)) {
2578 return status;
2581 /* Ensure this handle goes away at the end of this call */
2582 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2583 talloc_steal(mem_ctx, h);
2585 query.in.trustdom_handle = opn.out.trustdom_handle;
2586 query.in.level = r->in.level;
2587 query.out.info = r->out.info;
2588 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2589 if (!NT_STATUS_IS_OK(status)) {
2590 return status;
2593 return NT_STATUS_OK;
2597 lsa_SetTrustedDomainInfoByName
2599 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2600 TALLOC_CTX *mem_ctx,
2601 struct lsa_SetTrustedDomainInfoByName *r)
2603 struct dcesrv_handle *policy_handle;
2604 struct lsa_policy_state *policy_state;
2605 struct ldb_message **msgs;
2606 NTSTATUS nt_status;
2608 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2609 policy_state = policy_handle->data;
2611 /* get the trusted domain object */
2612 nt_status = get_tdo(policy_state->sam_ldb, mem_ctx,
2613 policy_state->domain_dn,
2614 r->in.trusted_domain->string,
2615 r->in.trusted_domain->string,
2616 NULL, &msgs);
2617 if (!NT_STATUS_IS_OK(nt_status)) {
2618 if (NT_STATUS_EQUAL(nt_status,
2619 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2620 return nt_status;
2622 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2625 return setInfoTrustedDomain_base(dce_call, policy_state, mem_ctx,
2626 msgs[0], r->in.level, r->in.info);
2630 lsa_QueryTrustedDomainInfoByName
2632 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2633 TALLOC_CTX *mem_ctx,
2634 struct lsa_QueryTrustedDomainInfoByName *r)
2636 NTSTATUS status;
2637 struct lsa_OpenTrustedDomainByName opn = {{0},{0}};
2638 struct lsa_QueryTrustedDomainInfo query;
2639 struct dcesrv_handle *h;
2641 opn.in.handle = r->in.handle;
2642 opn.in.name = *r->in.trusted_domain;
2643 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2644 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2645 if (!opn.out.trustdom_handle) {
2646 return NT_STATUS_NO_MEMORY;
2648 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
2649 if (!NT_STATUS_IS_OK(status)) {
2650 return status;
2653 /* Ensure this handle goes away at the end of this call */
2654 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2655 talloc_steal(mem_ctx, h);
2657 query.in.trustdom_handle = opn.out.trustdom_handle;
2658 query.in.level = r->in.level;
2659 query.out.info = r->out.info;
2660 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2661 if (!NT_STATUS_IS_OK(status)) {
2662 return status;
2665 return NT_STATUS_OK;
2669 lsa_CloseTrustedDomainEx
2671 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
2672 TALLOC_CTX *mem_ctx,
2673 struct lsa_CloseTrustedDomainEx *r)
2675 /* The result of a bad hair day from an IDL programmer? Not
2676 * implemented in Win2k3. You should always just lsa_Close
2677 * anyway. */
2678 return NT_STATUS_NOT_IMPLEMENTED;
2683 comparison function for sorting lsa_DomainInformation array
2685 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
2687 return strcasecmp_m(e1->name.string, e2->name.string);
2691 lsa_EnumTrustDom
2693 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2694 struct lsa_EnumTrustDom *r)
2696 struct dcesrv_handle *policy_handle;
2697 struct lsa_DomainInfo *entries;
2698 struct lsa_policy_state *policy_state;
2699 struct ldb_message **domains;
2700 const char *attrs[] = {
2701 "flatname",
2702 "securityIdentifier",
2703 NULL
2707 int count, i;
2709 *r->out.resume_handle = 0;
2711 r->out.domains->domains = NULL;
2712 r->out.domains->count = 0;
2714 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2716 policy_state = policy_handle->data;
2718 /* search for all users in this domain. This could possibly be cached and
2719 resumed based on resume_key */
2720 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2721 "objectclass=trustedDomain");
2722 if (count < 0) {
2723 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2726 /* convert to lsa_TrustInformation format */
2727 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
2728 if (!entries) {
2729 return NT_STATUS_NO_MEMORY;
2731 for (i=0;i<count;i++) {
2732 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
2733 entries[i].name.string = ldb_msg_find_attr_as_string(domains[i], "flatname", NULL);
2736 /* sort the results by name */
2737 TYPESAFE_QSORT(entries, count, compare_DomainInfo);
2739 if (*r->in.resume_handle >= count) {
2740 *r->out.resume_handle = -1;
2742 return NT_STATUS_NO_MORE_ENTRIES;
2745 /* return the rest, limit by max_size. Note that we
2746 use the w2k3 element size value of 60 */
2747 r->out.domains->count = count - *r->in.resume_handle;
2748 r->out.domains->count = MIN(r->out.domains->count,
2749 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
2751 r->out.domains->domains = entries + *r->in.resume_handle;
2753 if (r->out.domains->count < count - *r->in.resume_handle) {
2754 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2755 return STATUS_MORE_ENTRIES;
2758 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2759 * always be larger than the previous input resume handle, in
2760 * particular when hitting the last query it is vital to set the
2761 * resume handle correctly to avoid infinite client loops, as
2762 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2763 * status is NT_STATUS_OK - gd */
2765 *r->out.resume_handle = (uint32_t)-1;
2767 return NT_STATUS_OK;
2771 comparison function for sorting lsa_DomainInformation array
2773 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
2775 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
2779 lsa_EnumTrustedDomainsEx
2781 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2782 struct lsa_EnumTrustedDomainsEx *r)
2784 struct dcesrv_handle *policy_handle;
2785 struct lsa_TrustDomainInfoInfoEx *entries;
2786 struct lsa_policy_state *policy_state;
2787 struct ldb_message **domains;
2788 const char *attrs[] = {
2789 "flatname",
2790 "trustPartner",
2791 "securityIdentifier",
2792 "trustDirection",
2793 "trustType",
2794 "trustAttributes",
2795 NULL
2797 NTSTATUS nt_status;
2799 int count, i;
2801 *r->out.resume_handle = 0;
2803 r->out.domains->domains = NULL;
2804 r->out.domains->count = 0;
2806 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2808 policy_state = policy_handle->data;
2810 /* search for all users in this domain. This could possibly be cached and
2811 resumed based on resume_key */
2812 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2813 "objectclass=trustedDomain");
2814 if (count < 0) {
2815 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2818 /* convert to lsa_DomainInformation format */
2819 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
2820 if (!entries) {
2821 return NT_STATUS_NO_MEMORY;
2823 for (i=0;i<count;i++) {
2824 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
2825 if (!NT_STATUS_IS_OK(nt_status)) {
2826 return nt_status;
2830 /* sort the results by name */
2831 TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
2833 if (*r->in.resume_handle >= count) {
2834 *r->out.resume_handle = -1;
2836 return NT_STATUS_NO_MORE_ENTRIES;
2839 /* return the rest, limit by max_size. Note that we
2840 use the w2k3 element size value of 60 */
2841 r->out.domains->count = count - *r->in.resume_handle;
2842 r->out.domains->count = MIN(r->out.domains->count,
2843 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
2845 r->out.domains->domains = entries + *r->in.resume_handle;
2847 if (r->out.domains->count < count - *r->in.resume_handle) {
2848 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2849 return STATUS_MORE_ENTRIES;
2852 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2854 return NT_STATUS_OK;
2859 lsa_OpenAccount
2861 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2862 struct lsa_OpenAccount *r)
2864 struct dcesrv_handle *h, *ah;
2865 struct lsa_policy_state *state;
2866 struct lsa_account_state *astate;
2868 ZERO_STRUCTP(r->out.acct_handle);
2870 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2872 state = h->data;
2874 astate = talloc(dce_call->conn, struct lsa_account_state);
2875 if (astate == NULL) {
2876 return NT_STATUS_NO_MEMORY;
2879 astate->account_sid = dom_sid_dup(astate, r->in.sid);
2880 if (astate->account_sid == NULL) {
2881 talloc_free(astate);
2882 return NT_STATUS_NO_MEMORY;
2885 astate->policy = talloc_reference(astate, state);
2886 astate->access_mask = r->in.access_mask;
2889 * For now we grant all requested access.
2891 * We will fail at the ldb layer later.
2893 if (astate->access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
2894 astate->access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
2895 astate->access_mask |= LSA_ACCOUNT_ALL_ACCESS;
2897 se_map_generic(&astate->access_mask, &dcesrv_lsa_account_mapping);
2899 DEBUG(10,("%s: %s access desired[0x%08X] granted[0x%08X] - success.\n",
2900 __func__, dom_sid_string(mem_ctx, astate->account_sid),
2901 (unsigned)r->in.access_mask,
2902 (unsigned)astate->access_mask));
2904 ah = dcesrv_handle_create(dce_call, LSA_HANDLE_ACCOUNT);
2905 if (!ah) {
2906 talloc_free(astate);
2907 return NT_STATUS_NO_MEMORY;
2910 ah->data = talloc_steal(ah, astate);
2912 *r->out.acct_handle = ah->wire_handle;
2914 return NT_STATUS_OK;
2919 lsa_EnumPrivsAccount
2921 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
2922 TALLOC_CTX *mem_ctx,
2923 struct lsa_EnumPrivsAccount *r)
2925 struct dcesrv_handle *h;
2926 struct lsa_account_state *astate;
2927 int ret;
2928 unsigned int i, j;
2929 struct ldb_message **res;
2930 const char * const attrs[] = { "privilege", NULL};
2931 struct ldb_message_element *el;
2932 const char *sidstr;
2933 struct lsa_PrivilegeSet *privs;
2935 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2937 astate = h->data;
2939 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2940 if (privs == NULL) {
2941 return NT_STATUS_NO_MEMORY;
2943 privs->count = 0;
2944 privs->unknown = 0;
2945 privs->set = NULL;
2947 *r->out.privs = privs;
2949 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
2950 if (sidstr == NULL) {
2951 return NT_STATUS_NO_MEMORY;
2954 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
2955 "objectSid=%s", sidstr);
2956 if (ret < 0) {
2957 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2959 if (ret != 1) {
2960 return NT_STATUS_OK;
2963 el = ldb_msg_find_element(res[0], "privilege");
2964 if (el == NULL || el->num_values == 0) {
2965 return NT_STATUS_OK;
2968 privs->set = talloc_array(privs,
2969 struct lsa_LUIDAttribute, el->num_values);
2970 if (privs->set == NULL) {
2971 return NT_STATUS_NO_MEMORY;
2974 j = 0;
2975 for (i=0;i<el->num_values;i++) {
2976 int id = sec_privilege_id((const char *)el->values[i].data);
2977 if (id == SEC_PRIV_INVALID) {
2978 /* Perhaps an account right, not a privilege */
2979 continue;
2981 privs->set[j].attribute = 0;
2982 privs->set[j].luid.low = id;
2983 privs->set[j].luid.high = 0;
2984 j++;
2987 privs->count = j;
2989 return NT_STATUS_OK;
2993 lsa_EnumAccountRights
2995 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
2996 TALLOC_CTX *mem_ctx,
2997 struct lsa_EnumAccountRights *r)
2999 struct dcesrv_handle *h;
3000 struct lsa_policy_state *state;
3001 int ret;
3002 unsigned int i;
3003 struct ldb_message **res;
3004 const char * const attrs[] = { "privilege", NULL};
3005 const char *sidstr;
3006 struct ldb_message_element *el;
3008 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3010 state = h->data;
3012 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
3013 if (sidstr == NULL) {
3014 return NT_STATUS_NO_MEMORY;
3017 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
3018 "(&(objectSid=%s)(privilege=*))", sidstr);
3019 if (ret == 0) {
3020 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3022 if (ret != 1) {
3023 DEBUG(3, ("searching for account rights for SID: %s failed: %s\n",
3024 dom_sid_string(mem_ctx, r->in.sid),
3025 ldb_errstring(state->pdb)));
3026 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3029 el = ldb_msg_find_element(res[0], "privilege");
3030 if (el == NULL || el->num_values == 0) {
3031 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3034 r->out.rights->count = el->num_values;
3035 r->out.rights->names = talloc_array(r->out.rights,
3036 struct lsa_StringLarge, r->out.rights->count);
3037 if (r->out.rights->names == NULL) {
3038 return NT_STATUS_NO_MEMORY;
3041 for (i=0;i<el->num_values;i++) {
3042 r->out.rights->names[i].string = (const char *)el->values[i].data;
3045 return NT_STATUS_OK;
3051 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
3053 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
3054 TALLOC_CTX *mem_ctx,
3055 struct lsa_policy_state *state,
3056 int ldb_flag,
3057 struct dom_sid *sid,
3058 const struct lsa_RightSet *rights)
3060 struct auth_session_info *session_info =
3061 dcesrv_call_session_info(dce_call);
3062 const char *sidstr, *sidndrstr;
3063 struct ldb_message *msg;
3064 struct ldb_message_element *el;
3065 int ret;
3066 uint32_t i;
3067 struct lsa_EnumAccountRights r2;
3068 char *dnstr;
3070 if (security_session_user_level(session_info, NULL) <
3071 SECURITY_ADMINISTRATOR) {
3072 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
3073 return NT_STATUS_ACCESS_DENIED;
3076 msg = ldb_msg_new(mem_ctx);
3077 if (msg == NULL) {
3078 return NT_STATUS_NO_MEMORY;
3081 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
3082 if (sidndrstr == NULL) {
3083 TALLOC_FREE(msg);
3084 return NT_STATUS_NO_MEMORY;
3087 sidstr = dom_sid_string(msg, sid);
3088 if (sidstr == NULL) {
3089 TALLOC_FREE(msg);
3090 return NT_STATUS_NO_MEMORY;
3093 dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
3094 if (dnstr == NULL) {
3095 TALLOC_FREE(msg);
3096 return NT_STATUS_NO_MEMORY;
3099 msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
3100 if (msg->dn == NULL) {
3101 TALLOC_FREE(msg);
3102 return NT_STATUS_NO_MEMORY;
3105 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
3106 NTSTATUS status;
3108 r2.in.handle = &state->handle->wire_handle;
3109 r2.in.sid = sid;
3110 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
3112 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
3113 if (!NT_STATUS_IS_OK(status)) {
3114 ZERO_STRUCTP(r2.out.rights);
3118 for (i=0;i<rights->count;i++) {
3119 bool ok;
3121 ok = dcesrc_lsa_valid_AccountRight(rights->names[i].string);
3122 if (!ok) {
3123 talloc_free(msg);
3124 return NT_STATUS_NO_SUCH_PRIVILEGE;
3127 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
3128 uint32_t j;
3129 for (j=0;j<r2.out.rights->count;j++) {
3130 if (strcasecmp_m(r2.out.rights->names[j].string,
3131 rights->names[i].string) == 0) {
3132 break;
3135 if (j != r2.out.rights->count) continue;
3138 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
3139 if (ret != LDB_SUCCESS) {
3140 talloc_free(msg);
3141 return NT_STATUS_NO_MEMORY;
3145 el = ldb_msg_find_element(msg, "privilege");
3146 if (!el) {
3147 talloc_free(msg);
3148 return NT_STATUS_OK;
3151 el->flags = ldb_flag;
3153 ret = ldb_modify(state->pdb, msg);
3154 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
3155 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
3156 talloc_free(msg);
3157 return NT_STATUS_NO_MEMORY;
3159 ldb_msg_add_string(msg, "comment", "added via LSA");
3160 ret = ldb_add(state->pdb, msg);
3162 if (ret != LDB_SUCCESS) {
3163 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
3164 talloc_free(msg);
3165 return NT_STATUS_OK;
3167 DEBUG(3, ("Could not %s attributes from %s: %s\n",
3168 LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE ? "delete" : "add",
3169 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
3170 talloc_free(msg);
3171 return NT_STATUS_UNEXPECTED_IO_ERROR;
3174 talloc_free(msg);
3175 return NT_STATUS_OK;
3179 lsa_AddPrivilegesToAccount
3181 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3182 struct lsa_AddPrivilegesToAccount *r)
3184 struct lsa_RightSet rights;
3185 struct dcesrv_handle *h;
3186 struct lsa_account_state *astate;
3187 uint32_t i;
3189 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
3191 astate = h->data;
3193 rights.count = r->in.privs->count;
3194 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
3195 if (rights.names == NULL) {
3196 return NT_STATUS_NO_MEMORY;
3198 for (i=0;i<rights.count;i++) {
3199 int id = r->in.privs->set[i].luid.low;
3200 if (r->in.privs->set[i].luid.high) {
3201 return NT_STATUS_NO_SUCH_PRIVILEGE;
3203 rights.names[i].string = sec_privilege_name(id);
3204 if (rights.names[i].string == NULL) {
3205 return NT_STATUS_NO_SUCH_PRIVILEGE;
3209 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
3210 LDB_FLAG_MOD_ADD, astate->account_sid,
3211 &rights);
3216 lsa_RemovePrivilegesFromAccount
3218 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3219 struct lsa_RemovePrivilegesFromAccount *r)
3221 struct lsa_RightSet *rights;
3222 struct dcesrv_handle *h;
3223 struct lsa_account_state *astate;
3224 uint32_t i;
3226 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
3228 astate = h->data;
3230 rights = talloc(mem_ctx, struct lsa_RightSet);
3232 if (r->in.remove_all == 1 &&
3233 r->in.privs == NULL) {
3234 struct lsa_EnumAccountRights r2;
3235 NTSTATUS status;
3237 r2.in.handle = &astate->policy->handle->wire_handle;
3238 r2.in.sid = astate->account_sid;
3239 r2.out.rights = rights;
3241 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
3242 if (!NT_STATUS_IS_OK(status)) {
3243 return status;
3246 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
3247 LDB_FLAG_MOD_DELETE, astate->account_sid,
3248 r2.out.rights);
3251 if (r->in.remove_all != 0) {
3252 return NT_STATUS_INVALID_PARAMETER;
3255 rights->count = r->in.privs->count;
3256 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
3257 if (rights->names == NULL) {
3258 return NT_STATUS_NO_MEMORY;
3260 for (i=0;i<rights->count;i++) {
3261 int id = r->in.privs->set[i].luid.low;
3262 if (r->in.privs->set[i].luid.high) {
3263 return NT_STATUS_NO_SUCH_PRIVILEGE;
3265 rights->names[i].string = sec_privilege_name(id);
3266 if (rights->names[i].string == NULL) {
3267 return NT_STATUS_NO_SUCH_PRIVILEGE;
3271 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
3272 LDB_FLAG_MOD_DELETE, astate->account_sid,
3273 rights);
3278 lsa_GetQuotasForAccount
3280 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3281 struct lsa_GetQuotasForAccount *r)
3283 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3288 lsa_SetQuotasForAccount
3290 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3291 struct lsa_SetQuotasForAccount *r)
3293 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3298 lsa_GetSystemAccessAccount
3300 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3301 struct lsa_GetSystemAccessAccount *r)
3303 struct dcesrv_handle *h;
3304 struct lsa_account_state *astate;
3305 int ret;
3306 unsigned int i;
3307 struct ldb_message **res;
3308 const char * const attrs[] = { "privilege", NULL};
3309 struct ldb_message_element *el;
3310 const char *sidstr;
3312 *(r->out.access_mask) = 0x00000000;
3314 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
3316 astate = h->data;
3318 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
3319 if (sidstr == NULL) {
3320 return NT_STATUS_NO_MEMORY;
3323 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
3324 "objectSid=%s", sidstr);
3325 if (ret < 0) {
3326 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3328 if (ret != 1) {
3329 return NT_STATUS_OK;
3332 el = ldb_msg_find_element(res[0], "privilege");
3333 if (el == NULL || el->num_values == 0) {
3334 return NT_STATUS_OK;
3337 for (i=0;i<el->num_values;i++) {
3338 uint32_t right_bit = sec_right_bit((const char *)el->values[i].data);
3339 if (right_bit == 0) {
3340 /* Perhaps an privilege, not a right */
3341 continue;
3343 *(r->out.access_mask) |= right_bit;
3346 return NT_STATUS_OK;
3351 lsa_SetSystemAccessAccount
3353 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3354 struct lsa_SetSystemAccessAccount *r)
3356 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3359 lsa_CreateSecret
3361 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3362 struct lsa_CreateSecret *r)
3364 struct auth_session_info *session_info =
3365 dcesrv_call_session_info(dce_call);
3366 struct dcesrv_handle *policy_handle;
3367 struct lsa_policy_state *policy_state;
3368 struct lsa_secret_state *secret_state;
3369 struct dcesrv_handle *handle;
3370 struct ldb_message **msgs, *msg;
3371 const char *attrs[] = {
3372 NULL
3375 const char *name;
3377 int ret;
3379 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3380 ZERO_STRUCTP(r->out.sec_handle);
3382 switch (security_session_user_level(session_info, NULL))
3384 case SECURITY_SYSTEM:
3385 case SECURITY_ADMINISTRATOR:
3386 break;
3387 default:
3388 /* Users and anonymous are not allowed create secrets */
3389 return NT_STATUS_ACCESS_DENIED;
3392 policy_state = policy_handle->data;
3394 if (!r->in.name.string) {
3395 return NT_STATUS_INVALID_PARAMETER;
3398 secret_state = talloc(mem_ctx, struct lsa_secret_state);
3399 NT_STATUS_HAVE_NO_MEMORY(secret_state);
3400 secret_state->policy = policy_state;
3402 msg = ldb_msg_new(mem_ctx);
3403 if (msg == NULL) {
3404 return NT_STATUS_NO_MEMORY;
3407 if (strncmp("G$", r->in.name.string, 2) == 0) {
3408 const char *name2;
3410 secret_state->global = true;
3412 name = &r->in.name.string[2];
3413 if (strlen(name) == 0) {
3414 return NT_STATUS_INVALID_PARAMETER;
3417 name2 = talloc_asprintf(mem_ctx, "%s Secret",
3418 ldb_binary_encode_string(mem_ctx, name));
3419 NT_STATUS_HAVE_NO_MEMORY(name2);
3422 * We need to connect to the database as system, as this is
3423 * one of the rare RPC calls that must read the secrets
3424 * (and this is denied otherwise)
3426 * We also save the current remote session details so they can
3427 * used by the audit logging module. This allows the audit
3428 * logging to report the remote users details, rather than the
3429 * system users details.
3431 secret_state->sam_ldb =
3432 dcesrv_samdb_connect_as_system(secret_state, dce_call);
3433 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
3435 /* search for the secret record */
3436 ret = gendb_search(secret_state->sam_ldb,
3437 mem_ctx, policy_state->system_dn, &msgs, attrs,
3438 "(&(cn=%s)(objectclass=secret))",
3439 name2);
3440 if (ret > 0) {
3441 return NT_STATUS_OBJECT_NAME_COLLISION;
3444 if (ret < 0) {
3445 DEBUG(0,("Failure searching for CN=%s: %s\n",
3446 name2, ldb_errstring(secret_state->sam_ldb)));
3447 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3450 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
3451 NT_STATUS_HAVE_NO_MEMORY(msg->dn);
3452 if (!ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
3453 return NT_STATUS_NO_MEMORY;
3456 ret = ldb_msg_add_string(msg, "cn", name2);
3457 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
3458 } else {
3459 secret_state->global = false;
3461 name = r->in.name.string;
3462 if (strlen(name) == 0) {
3463 return NT_STATUS_INVALID_PARAMETER;
3466 secret_state->sam_ldb = secrets_db_connect(secret_state,
3467 dce_call->conn->dce_ctx->lp_ctx);
3468 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
3470 /* search for the secret record */
3471 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
3472 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
3473 &msgs, attrs,
3474 "(&(cn=%s)(objectclass=secret))",
3475 ldb_binary_encode_string(mem_ctx, name));
3476 if (ret > 0) {
3477 return NT_STATUS_OBJECT_NAME_COLLISION;
3480 if (ret < 0) {
3481 DEBUG(0,("Failure searching for CN=%s: %s\n",
3482 name, ldb_errstring(secret_state->sam_ldb)));
3483 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3486 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb,
3487 "cn=%s,cn=LSA Secrets", name);
3488 NT_STATUS_HAVE_NO_MEMORY(msg->dn);
3489 ret = ldb_msg_add_string(msg, "cn", name);
3490 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
3493 ret = ldb_msg_add_string(msg, "objectClass", "secret");
3494 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
3496 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
3497 NT_STATUS_HAVE_NO_MEMORY(secret_state->secret_dn);
3499 /* create the secret */
3500 ret = ldb_add(secret_state->sam_ldb, msg);
3501 if (ret != LDB_SUCCESS) {
3502 DEBUG(0,("Failed to create secret record %s: %s\n",
3503 ldb_dn_get_linearized(msg->dn),
3504 ldb_errstring(secret_state->sam_ldb)));
3505 return NT_STATUS_ACCESS_DENIED;
3508 handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET);
3509 NT_STATUS_HAVE_NO_MEMORY(handle);
3511 handle->data = talloc_steal(handle, secret_state);
3513 secret_state->access_mask = r->in.access_mask;
3514 secret_state->policy = talloc_reference(secret_state, policy_state);
3515 NT_STATUS_HAVE_NO_MEMORY(secret_state->policy);
3517 *r->out.sec_handle = handle->wire_handle;
3519 return NT_STATUS_OK;
3524 lsa_OpenSecret
3526 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3527 struct lsa_OpenSecret *r)
3529 struct auth_session_info *session_info =
3530 dcesrv_call_session_info(dce_call);
3531 struct dcesrv_handle *policy_handle;
3532 struct lsa_policy_state *policy_state;
3533 struct lsa_secret_state *secret_state;
3534 struct dcesrv_handle *handle;
3535 struct ldb_message **msgs;
3536 const char *attrs[] = {
3537 NULL
3539 const char *name;
3540 int ret;
3542 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3543 ZERO_STRUCTP(r->out.sec_handle);
3544 policy_state = policy_handle->data;
3546 if (!r->in.name.string) {
3547 return NT_STATUS_INVALID_PARAMETER;
3550 switch (security_session_user_level(session_info, NULL))
3552 case SECURITY_SYSTEM:
3553 case SECURITY_ADMINISTRATOR:
3554 break;
3555 default:
3556 /* Users and anonymous are not allowed to access secrets */
3557 return NT_STATUS_ACCESS_DENIED;
3560 secret_state = talloc(mem_ctx, struct lsa_secret_state);
3561 if (!secret_state) {
3562 return NT_STATUS_NO_MEMORY;
3564 secret_state->policy = policy_state;
3566 if (strncmp("G$", r->in.name.string, 2) == 0) {
3567 name = &r->in.name.string[2];
3569 * We need to connect to the database as system, as this is
3570 * one of the rare RPC calls that must read the secrets
3571 * (and this is denied otherwise)
3573 * We also save the current remote session details so they can
3574 * used by the audit logging module. This allows the audit
3575 * logging to report the remote users details, rather than the
3576 * system users details.
3578 secret_state->sam_ldb =
3579 dcesrv_samdb_connect_as_system(secret_state, dce_call);
3580 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
3581 secret_state->global = true;
3583 if (strlen(name) < 1) {
3584 return NT_STATUS_INVALID_PARAMETER;
3587 /* search for the secret record */
3588 ret = gendb_search(secret_state->sam_ldb,
3589 mem_ctx, policy_state->system_dn, &msgs, attrs,
3590 "(&(cn=%s Secret)(objectclass=secret))",
3591 ldb_binary_encode_string(mem_ctx, name));
3592 if (ret == 0) {
3593 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3596 if (ret != 1) {
3597 DEBUG(0,("Found %d records matching DN %s\n", ret,
3598 ldb_dn_get_linearized(policy_state->system_dn)));
3599 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3601 } else {
3602 secret_state->global = false;
3603 secret_state->sam_ldb = secrets_db_connect(secret_state,
3604 dce_call->conn->dce_ctx->lp_ctx);
3605 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
3607 name = r->in.name.string;
3608 if (strlen(name) < 1) {
3609 return NT_STATUS_INVALID_PARAMETER;
3612 /* search for the secret record */
3613 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
3614 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
3615 &msgs, attrs,
3616 "(&(cn=%s)(objectclass=secret))",
3617 ldb_binary_encode_string(mem_ctx, name));
3618 if (ret == 0) {
3619 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3622 if (ret != 1) {
3623 DEBUG(0,("Found %d records matching CN=%s\n",
3624 ret, ldb_binary_encode_string(mem_ctx, name)));
3625 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3629 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
3631 handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET);
3632 if (!handle) {
3633 return NT_STATUS_NO_MEMORY;
3636 handle->data = talloc_steal(handle, secret_state);
3638 secret_state->access_mask = r->in.access_mask;
3639 secret_state->policy = talloc_reference(secret_state, policy_state);
3641 *r->out.sec_handle = handle->wire_handle;
3643 return NT_STATUS_OK;
3648 lsa_SetSecret
3650 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3651 struct lsa_SetSecret *r)
3654 struct dcesrv_handle *h;
3655 struct lsa_secret_state *secret_state;
3656 struct ldb_message *msg;
3657 DATA_BLOB session_key;
3658 DATA_BLOB crypt_secret, secret;
3659 struct ldb_val val;
3660 int ret;
3661 NTSTATUS status = NT_STATUS_OK;
3663 struct timeval now = timeval_current();
3664 NTTIME nt_now = timeval_to_nttime(&now);
3666 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3668 secret_state = h->data;
3670 msg = ldb_msg_new(mem_ctx);
3671 if (msg == NULL) {
3672 return NT_STATUS_NO_MEMORY;
3675 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
3676 if (!msg->dn) {
3677 return NT_STATUS_NO_MEMORY;
3679 status = dcesrv_transport_session_key(dce_call, &session_key);
3680 if (!NT_STATUS_IS_OK(status)) {
3681 return status;
3684 if (r->in.old_val) {
3685 /* Decrypt */
3686 crypt_secret.data = r->in.old_val->data;
3687 crypt_secret.length = r->in.old_val->size;
3689 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3690 if (!NT_STATUS_IS_OK(status)) {
3691 return status;
3694 val.data = secret.data;
3695 val.length = secret.length;
3697 /* set value */
3698 if (ldb_msg_add_value(msg, "priorValue", &val, NULL) != LDB_SUCCESS) {
3699 return NT_STATUS_NO_MEMORY;
3702 /* set old value mtime */
3703 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3704 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3705 return NT_STATUS_NO_MEMORY;
3708 } else {
3709 /* If the old value is not set, then migrate the
3710 * current value to the old value */
3711 const struct ldb_val *old_val;
3712 NTTIME last_set_time;
3713 struct ldb_message **res;
3714 const char *attrs[] = {
3715 "currentValue",
3716 "lastSetTime",
3717 NULL
3720 /* search for the secret record */
3721 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
3722 secret_state->secret_dn, &res, attrs);
3723 if (ret == 0) {
3724 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3727 if (ret != 1) {
3728 DEBUG(0,("Found %d records matching dn=%s\n", ret,
3729 ldb_dn_get_linearized(secret_state->secret_dn)));
3730 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3733 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3734 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3736 if (old_val) {
3737 /* set old value */
3738 if (ldb_msg_add_value(msg, "priorValue",
3739 old_val, NULL) != LDB_SUCCESS) {
3740 return NT_STATUS_NO_MEMORY;
3742 } else {
3743 if (samdb_msg_add_delete(secret_state->sam_ldb,
3744 mem_ctx, msg, "priorValue") != LDB_SUCCESS) {
3745 return NT_STATUS_NO_MEMORY;
3749 /* set old value mtime */
3750 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
3751 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3752 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
3753 return NT_STATUS_NO_MEMORY;
3755 } else {
3756 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3757 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3758 return NT_STATUS_NO_MEMORY;
3763 if (r->in.new_val) {
3764 /* Decrypt */
3765 crypt_secret.data = r->in.new_val->data;
3766 crypt_secret.length = r->in.new_val->size;
3768 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3769 if (!NT_STATUS_IS_OK(status)) {
3770 return status;
3773 val.data = secret.data;
3774 val.length = secret.length;
3776 /* set value */
3777 if (ldb_msg_add_value(msg, "currentValue", &val, NULL) != LDB_SUCCESS) {
3778 return NT_STATUS_NO_MEMORY;
3781 /* set new value mtime */
3782 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3783 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3784 return NT_STATUS_NO_MEMORY;
3786 } else {
3787 /* NULL out the NEW value */
3788 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3789 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3790 return NT_STATUS_NO_MEMORY;
3792 if (samdb_msg_add_delete(secret_state->sam_ldb,
3793 mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
3794 return NT_STATUS_NO_MEMORY;
3798 /* modify the samdb record */
3799 ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
3800 if (ret != LDB_SUCCESS) {
3801 return dsdb_ldb_err_to_ntstatus(ret);
3804 return NT_STATUS_OK;
3809 lsa_QuerySecret
3811 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3812 struct lsa_QuerySecret *r)
3814 struct auth_session_info *session_info =
3815 dcesrv_call_session_info(dce_call);
3816 struct dcesrv_handle *h;
3817 struct lsa_secret_state *secret_state;
3818 struct ldb_message *msg;
3819 DATA_BLOB session_key;
3820 DATA_BLOB crypt_secret, secret;
3821 int ret;
3822 struct ldb_message **res;
3823 const char *attrs[] = {
3824 "currentValue",
3825 "priorValue",
3826 "lastSetTime",
3827 "priorSetTime",
3828 NULL
3831 NTSTATUS nt_status;
3833 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3835 /* Ensure user is permitted to read this... */
3836 switch (security_session_user_level(session_info, NULL))
3838 case SECURITY_SYSTEM:
3839 case SECURITY_ADMINISTRATOR:
3840 break;
3841 default:
3842 /* Users and anonymous are not allowed to read secrets */
3843 return NT_STATUS_ACCESS_DENIED;
3846 secret_state = h->data;
3848 /* pull all the user attributes */
3849 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
3850 secret_state->secret_dn, &res, attrs);
3851 if (ret != 1) {
3852 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3854 msg = res[0];
3856 nt_status = dcesrv_transport_session_key(dce_call, &session_key);
3857 if (!NT_STATUS_IS_OK(nt_status)) {
3858 return nt_status;
3861 if (r->in.old_val) {
3862 const struct ldb_val *prior_val;
3863 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3864 if (!r->out.old_val) {
3865 return NT_STATUS_NO_MEMORY;
3867 prior_val = ldb_msg_find_ldb_val(msg, "priorValue");
3869 if (prior_val && prior_val->length) {
3870 secret.data = prior_val->data;
3871 secret.length = prior_val->length;
3873 /* Encrypt */
3874 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3875 if (!crypt_secret.length) {
3876 return NT_STATUS_NO_MEMORY;
3878 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3879 if (!r->out.old_val->buf) {
3880 return NT_STATUS_NO_MEMORY;
3882 r->out.old_val->buf->size = crypt_secret.length;
3883 r->out.old_val->buf->length = crypt_secret.length;
3884 r->out.old_val->buf->data = crypt_secret.data;
3888 if (r->in.old_mtime) {
3889 r->out.old_mtime = talloc(mem_ctx, NTTIME);
3890 if (!r->out.old_mtime) {
3891 return NT_STATUS_NO_MEMORY;
3893 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(msg, "priorSetTime", 0);
3896 if (r->in.new_val) {
3897 const struct ldb_val *new_val;
3898 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3899 if (!r->out.new_val) {
3900 return NT_STATUS_NO_MEMORY;
3903 new_val = ldb_msg_find_ldb_val(msg, "currentValue");
3905 if (new_val && new_val->length) {
3906 secret.data = new_val->data;
3907 secret.length = new_val->length;
3909 /* Encrypt */
3910 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3911 if (!crypt_secret.length) {
3912 return NT_STATUS_NO_MEMORY;
3914 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3915 if (!r->out.new_val->buf) {
3916 return NT_STATUS_NO_MEMORY;
3918 r->out.new_val->buf->length = crypt_secret.length;
3919 r->out.new_val->buf->size = crypt_secret.length;
3920 r->out.new_val->buf->data = crypt_secret.data;
3924 if (r->in.new_mtime) {
3925 r->out.new_mtime = talloc(mem_ctx, NTTIME);
3926 if (!r->out.new_mtime) {
3927 return NT_STATUS_NO_MEMORY;
3929 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(msg, "lastSetTime", 0);
3932 return NT_STATUS_OK;
3937 lsa_LookupPrivValue
3939 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
3940 TALLOC_CTX *mem_ctx,
3941 struct lsa_LookupPrivValue *r)
3943 struct dcesrv_handle *h;
3944 int id;
3946 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3948 id = sec_privilege_id(r->in.name->string);
3949 if (id == SEC_PRIV_INVALID) {
3950 return NT_STATUS_NO_SUCH_PRIVILEGE;
3953 r->out.luid->low = id;
3954 r->out.luid->high = 0;
3956 return NT_STATUS_OK;
3961 lsa_LookupPrivName
3963 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
3964 TALLOC_CTX *mem_ctx,
3965 struct lsa_LookupPrivName *r)
3967 struct dcesrv_handle *h;
3968 struct lsa_StringLarge *name;
3969 const char *privname;
3971 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3973 if (r->in.luid->high != 0) {
3974 return NT_STATUS_NO_SUCH_PRIVILEGE;
3977 privname = sec_privilege_name(r->in.luid->low);
3978 if (privname == NULL) {
3979 return NT_STATUS_NO_SUCH_PRIVILEGE;
3982 name = talloc(mem_ctx, struct lsa_StringLarge);
3983 if (name == NULL) {
3984 return NT_STATUS_NO_MEMORY;
3987 name->string = privname;
3989 *r->out.name = name;
3991 return NT_STATUS_OK;
3996 lsa_LookupPrivDisplayName
3998 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
3999 TALLOC_CTX *mem_ctx,
4000 struct lsa_LookupPrivDisplayName *r)
4002 struct dcesrv_handle *h;
4003 struct lsa_StringLarge *disp_name = NULL;
4004 enum sec_privilege id;
4006 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4008 id = sec_privilege_id(r->in.name->string);
4009 if (id == SEC_PRIV_INVALID) {
4010 return NT_STATUS_NO_SUCH_PRIVILEGE;
4013 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
4014 if (disp_name == NULL) {
4015 return NT_STATUS_NO_MEMORY;
4018 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
4019 if (disp_name->string == NULL) {
4020 return NT_STATUS_INTERNAL_ERROR;
4023 *r->out.disp_name = disp_name;
4024 *r->out.returned_language_id = 0;
4026 return NT_STATUS_OK;
4031 lsa_EnumAccountsWithUserRight
4033 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
4034 TALLOC_CTX *mem_ctx,
4035 struct lsa_EnumAccountsWithUserRight *r)
4037 struct dcesrv_handle *h;
4038 struct lsa_policy_state *state;
4039 int ret, i;
4040 struct ldb_message **res;
4041 const char * const attrs[] = { "objectSid", NULL};
4042 const char *privname;
4043 bool ok;
4045 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4047 state = h->data;
4049 if (r->in.name == NULL) {
4050 return NT_STATUS_NO_SUCH_PRIVILEGE;
4053 privname = r->in.name->string;
4055 ok = dcesrc_lsa_valid_AccountRight(privname);
4056 if (!ok) {
4057 return NT_STATUS_NO_SUCH_PRIVILEGE;
4060 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
4061 "privilege=%s", privname);
4062 if (ret < 0) {
4063 return NT_STATUS_INTERNAL_DB_CORRUPTION;
4065 if (ret == 0) {
4066 return NT_STATUS_NO_MORE_ENTRIES;
4069 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
4070 if (r->out.sids->sids == NULL) {
4071 return NT_STATUS_NO_MEMORY;
4073 for (i=0;i<ret;i++) {
4074 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
4075 res[i], "objectSid");
4076 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
4078 r->out.sids->num_sids = ret;
4080 return NT_STATUS_OK;
4085 lsa_AddAccountRights
4087 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
4088 TALLOC_CTX *mem_ctx,
4089 struct lsa_AddAccountRights *r)
4091 struct dcesrv_handle *h;
4092 struct lsa_policy_state *state;
4094 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4096 state = h->data;
4098 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
4099 LDB_FLAG_MOD_ADD,
4100 r->in.sid, r->in.rights);
4105 lsa_RemoveAccountRights
4107 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
4108 TALLOC_CTX *mem_ctx,
4109 struct lsa_RemoveAccountRights *r)
4111 struct dcesrv_handle *h;
4112 struct lsa_policy_state *state;
4114 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4116 state = h->data;
4118 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
4119 LDB_FLAG_MOD_DELETE,
4120 r->in.sid, r->in.rights);
4125 lsa_StorePrivateData
4127 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4128 struct lsa_StorePrivateData *r)
4130 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4135 lsa_RetrievePrivateData
4137 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4138 struct lsa_RetrievePrivateData *r)
4140 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4145 lsa_GetUserName
4147 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4148 struct lsa_GetUserName *r)
4150 enum dcerpc_transport_t transport =
4151 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
4152 struct auth_session_info *session_info =
4153 dcesrv_call_session_info(dce_call);
4154 NTSTATUS status = NT_STATUS_OK;
4155 const char *account_name;
4156 const char *authority_name;
4157 struct lsa_String *_account_name;
4158 struct lsa_String *_authority_name = NULL;
4160 if (transport != NCACN_NP && transport != NCALRPC) {
4161 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
4164 /* this is what w2k3 does */
4165 r->out.account_name = r->in.account_name;
4166 r->out.authority_name = r->in.authority_name;
4168 if (r->in.account_name
4169 && *r->in.account_name
4170 /* && *(*r->in.account_name)->string */
4172 return NT_STATUS_INVALID_PARAMETER;
4175 if (r->in.authority_name
4176 && *r->in.authority_name
4177 /* && *(*r->in.authority_name)->string */
4179 return NT_STATUS_INVALID_PARAMETER;
4182 account_name = talloc_reference(mem_ctx, session_info->info->account_name);
4183 authority_name = talloc_reference(mem_ctx, session_info->info->domain_name);
4185 _account_name = talloc(mem_ctx, struct lsa_String);
4186 NT_STATUS_HAVE_NO_MEMORY(_account_name);
4187 _account_name->string = account_name;
4189 if (r->in.authority_name) {
4190 _authority_name = talloc(mem_ctx, struct lsa_String);
4191 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
4192 _authority_name->string = authority_name;
4195 *r->out.account_name = _account_name;
4196 if (r->out.authority_name) {
4197 *r->out.authority_name = _authority_name;
4200 return status;
4204 lsa_SetInfoPolicy2
4206 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
4207 TALLOC_CTX *mem_ctx,
4208 struct lsa_SetInfoPolicy2 *r)
4210 /* need to support these */
4211 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4214 static void kdc_get_policy(TALLOC_CTX *mem_ctx,
4215 struct loadparm_context *lp_ctx,
4216 struct smb_krb5_context *smb_krb5_context,
4217 struct lsa_DomainInfoKerberos *k)
4219 time_t svc_tkt_lifetime;
4220 time_t usr_tkt_lifetime;
4221 time_t renewal_lifetime;
4223 /* Our KDC always re-validates the client */
4224 k->authentication_options = LSA_POLICY_KERBEROS_VALIDATE_CLIENT;
4226 lpcfg_default_kdc_policy(mem_ctx, lp_ctx, &svc_tkt_lifetime,
4227 &usr_tkt_lifetime, &renewal_lifetime);
4229 unix_to_nt_time(&k->service_tkt_lifetime, svc_tkt_lifetime);
4230 unix_to_nt_time(&k->user_tkt_lifetime, usr_tkt_lifetime);
4231 unix_to_nt_time(&k->user_tkt_renewaltime, renewal_lifetime);
4232 #ifdef SAMBA4_USES_HEIMDAL /* MIT lacks krb5_get_max_time_skew.
4233 However in the parent function we basically just did a full
4234 krb5_context init with the only purpose of getting a global
4235 config option (the max skew), it would probably make more sense
4236 to have a lp_ or ldb global option as the samba default */
4237 if (smb_krb5_context) {
4238 unix_to_nt_time(&k->clock_skew,
4239 krb5_get_max_time_skew(smb_krb5_context->krb5_context));
4241 #endif
4242 k->reserved = 0;
4245 lsa_QueryDomainInformationPolicy
4247 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
4248 TALLOC_CTX *mem_ctx,
4249 struct lsa_QueryDomainInformationPolicy *r)
4251 union lsa_DomainInformationPolicy *info;
4253 info = talloc_zero(r->out.info, union lsa_DomainInformationPolicy);
4254 if (!info) {
4255 return NT_STATUS_NO_MEMORY;
4258 switch (r->in.level) {
4259 case LSA_DOMAIN_INFO_POLICY_EFS:
4260 talloc_free(info);
4261 *r->out.info = NULL;
4262 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4263 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
4265 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
4266 struct smb_krb5_context *smb_krb5_context;
4267 int ret = smb_krb5_init_context(mem_ctx,
4268 dce_call->conn->dce_ctx->lp_ctx,
4269 &smb_krb5_context);
4270 if (ret != 0) {
4271 talloc_free(info);
4272 *r->out.info = NULL;
4273 return NT_STATUS_INTERNAL_ERROR;
4275 kdc_get_policy(mem_ctx, dce_call->conn->dce_ctx->lp_ctx,
4276 smb_krb5_context,
4278 talloc_free(smb_krb5_context);
4279 *r->out.info = info;
4280 return NT_STATUS_OK;
4282 default:
4283 talloc_free(info);
4284 *r->out.info = NULL;
4285 return NT_STATUS_INVALID_INFO_CLASS;
4290 lsa_SetDomInfoPolicy
4292 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
4293 TALLOC_CTX *mem_ctx,
4294 struct lsa_SetDomainInformationPolicy *r)
4296 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4300 lsa_TestCall
4302 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
4303 TALLOC_CTX *mem_ctx,
4304 struct lsa_TestCall *r)
4306 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4310 lsa_CREDRWRITE
4312 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4313 struct lsa_CREDRWRITE *r)
4315 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4320 lsa_CREDRREAD
4322 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4323 struct lsa_CREDRREAD *r)
4325 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4330 lsa_CREDRENUMERATE
4332 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4333 struct lsa_CREDRENUMERATE *r)
4335 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4340 lsa_CREDRWRITEDOMAINCREDENTIALS
4342 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4343 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
4345 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4350 lsa_CREDRREADDOMAINCREDENTIALS
4352 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4353 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
4355 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4360 lsa_CREDRDELETE
4362 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4363 struct lsa_CREDRDELETE *r)
4365 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4370 lsa_CREDRGETTARGETINFO
4372 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4373 struct lsa_CREDRGETTARGETINFO *r)
4375 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4380 lsa_CREDRPROFILELOADED
4382 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4383 struct lsa_CREDRPROFILELOADED *r)
4385 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4390 lsa_CREDRGETSESSIONTYPES
4392 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4393 struct lsa_CREDRGETSESSIONTYPES *r)
4395 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4400 lsa_LSARREGISTERAUDITEVENT
4402 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4403 struct lsa_LSARREGISTERAUDITEVENT *r)
4405 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4410 lsa_LSARGENAUDITEVENT
4412 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4413 struct lsa_LSARGENAUDITEVENT *r)
4415 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4420 lsa_LSARUNREGISTERAUDITEVENT
4422 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4423 struct lsa_LSARUNREGISTERAUDITEVENT *r)
4425 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4430 lsa_lsaRQueryForestTrustInformation
4432 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4433 struct lsa_lsaRQueryForestTrustInformation *r)
4435 struct dcesrv_handle *h = NULL;
4436 struct lsa_policy_state *p_state = NULL;
4437 int forest_level = DS_DOMAIN_FUNCTION_2000;
4438 const char * const trust_attrs[] = {
4439 "securityIdentifier",
4440 "flatName",
4441 "trustPartner",
4442 "trustAttributes",
4443 "trustDirection",
4444 "trustType",
4445 "msDS-TrustForestTrustInfo",
4446 NULL
4448 struct ldb_message *trust_tdo_msg = NULL;
4449 struct lsa_TrustDomainInfoInfoEx *trust_tdo = NULL;
4450 struct ForestTrustInfo *trust_fti = NULL;
4451 struct lsa_ForestTrustInformation *trust_lfti = NULL;
4452 NTSTATUS status;
4454 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4456 p_state = h->data;
4458 if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
4459 return NT_STATUS_INVALID_DOMAIN_STATE;
4462 forest_level = dsdb_forest_functional_level(p_state->sam_ldb);
4463 if (forest_level < DS_DOMAIN_FUNCTION_2003) {
4464 return NT_STATUS_INVALID_DOMAIN_STATE;
4467 if (r->in.trusted_domain_name->string == NULL) {
4468 return NT_STATUS_NO_SUCH_DOMAIN;
4471 status = dsdb_trust_search_tdo(p_state->sam_ldb,
4472 r->in.trusted_domain_name->string,
4473 r->in.trusted_domain_name->string,
4474 trust_attrs, mem_ctx, &trust_tdo_msg);
4475 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4476 return NT_STATUS_NO_SUCH_DOMAIN;
4478 if (!NT_STATUS_IS_OK(status)) {
4479 return status;
4482 status = dsdb_trust_parse_tdo_info(mem_ctx, trust_tdo_msg, &trust_tdo);
4483 if (!NT_STATUS_IS_OK(status)) {
4484 return status;
4487 if (!(trust_tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4488 return NT_STATUS_INVALID_PARAMETER;
4491 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4492 return NT_STATUS_INVALID_PARAMETER;
4495 status = dsdb_trust_parse_forest_info(mem_ctx,
4496 trust_tdo_msg,
4497 &trust_fti);
4498 if (!NT_STATUS_IS_OK(status)) {
4499 return status;
4502 status = dsdb_trust_forest_info_to_lsa(mem_ctx, trust_fti,
4503 &trust_lfti);
4504 if (!NT_STATUS_IS_OK(status)) {
4505 return status;
4508 *r->out.forest_trust_info = trust_lfti;
4509 return NT_STATUS_OK;
4513 lsa_lsaRSetForestTrustInformation
4515 static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_state *dce_call,
4516 TALLOC_CTX *mem_ctx,
4517 struct lsa_lsaRSetForestTrustInformation *r)
4519 struct dcesrv_handle *h;
4520 struct lsa_policy_state *p_state;
4521 const char * const trust_attrs[] = {
4522 "securityIdentifier",
4523 "flatName",
4524 "trustPartner",
4525 "trustAttributes",
4526 "trustDirection",
4527 "trustType",
4528 "msDS-TrustForestTrustInfo",
4529 NULL
4531 struct ldb_message *trust_tdo_msg = NULL;
4532 struct lsa_TrustDomainInfoInfoEx *trust_tdo = NULL;
4533 struct lsa_ForestTrustInformation *step1_lfti = NULL;
4534 struct lsa_ForestTrustInformation *step2_lfti = NULL;
4535 struct ForestTrustInfo *trust_fti = NULL;
4536 struct ldb_result *trusts_res = NULL;
4537 unsigned int i;
4538 struct lsa_TrustDomainInfoInfoEx *xref_tdo = NULL;
4539 struct lsa_ForestTrustInformation *xref_lfti = NULL;
4540 struct lsa_ForestTrustCollisionInfo *c_info = NULL;
4541 DATA_BLOB ft_blob = {};
4542 struct ldb_message *msg = NULL;
4543 struct server_id *server_ids = NULL;
4544 uint32_t num_server_ids = 0;
4545 NTSTATUS status;
4546 enum ndr_err_code ndr_err;
4547 int ret;
4548 bool in_transaction = false;
4549 struct imessaging_context *imsg_ctx =
4550 dcesrv_imessaging_context(dce_call->conn);
4552 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4554 p_state = h->data;
4556 if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
4557 return NT_STATUS_INVALID_DOMAIN_STATE;
4560 if (r->in.check_only == 0) {
4561 ret = ldb_transaction_start(p_state->sam_ldb);
4562 if (ret != LDB_SUCCESS) {
4563 return NT_STATUS_INTERNAL_DB_CORRUPTION;
4565 in_transaction = true;
4569 * abort if we are not a PDC
4571 * In future we should use a function like IsEffectiveRoleOwner()
4573 if (!samdb_is_pdc(p_state->sam_ldb)) {
4574 status = NT_STATUS_INVALID_DOMAIN_ROLE;
4575 goto done;
4578 if (r->in.trusted_domain_name->string == NULL) {
4579 status = NT_STATUS_NO_SUCH_DOMAIN;
4580 goto done;
4583 status = dsdb_trust_search_tdo(p_state->sam_ldb,
4584 r->in.trusted_domain_name->string,
4585 r->in.trusted_domain_name->string,
4586 trust_attrs, mem_ctx, &trust_tdo_msg);
4587 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4588 status = NT_STATUS_NO_SUCH_DOMAIN;
4589 goto done;
4591 if (!NT_STATUS_IS_OK(status)) {
4592 goto done;
4595 status = dsdb_trust_parse_tdo_info(mem_ctx, trust_tdo_msg, &trust_tdo);
4596 if (!NT_STATUS_IS_OK(status)) {
4597 goto done;
4600 if (!(trust_tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4601 status = NT_STATUS_INVALID_PARAMETER;
4602 goto done;
4605 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4606 status = NT_STATUS_INVALID_PARAMETER;
4607 goto done;
4611 * verify and normalize the given forest trust info.
4613 * Step1: doesn't reorder yet, so step1_lfti might contain
4614 * NULL entries. This means dsdb_trust_verify_forest_info()
4615 * can generate collision entries with the callers index.
4617 status = dsdb_trust_normalize_forest_info_step1(mem_ctx,
4618 r->in.forest_trust_info,
4619 &step1_lfti);
4620 if (!NT_STATUS_IS_OK(status)) {
4621 goto done;
4624 c_info = talloc_zero(r->out.collision_info,
4625 struct lsa_ForestTrustCollisionInfo);
4626 if (c_info == NULL) {
4627 status = NT_STATUS_NO_MEMORY;
4628 goto done;
4632 * First check our own forest, then other domains/forests
4635 status = dsdb_trust_xref_tdo_info(mem_ctx, p_state->sam_ldb,
4636 &xref_tdo);
4637 if (!NT_STATUS_IS_OK(status)) {
4638 goto done;
4640 status = dsdb_trust_xref_forest_info(mem_ctx, p_state->sam_ldb,
4641 &xref_lfti);
4642 if (!NT_STATUS_IS_OK(status)) {
4643 goto done;
4647 * The documentation proposed to generate
4648 * LSA_FOREST_TRUST_COLLISION_XREF collisions.
4649 * But Windows always uses LSA_FOREST_TRUST_COLLISION_TDO.
4651 status = dsdb_trust_verify_forest_info(xref_tdo, xref_lfti,
4652 LSA_FOREST_TRUST_COLLISION_TDO,
4653 c_info, step1_lfti);
4654 if (!NT_STATUS_IS_OK(status)) {
4655 goto done;
4658 /* fetch all other trusted domain objects */
4659 status = dsdb_trust_search_tdos(p_state->sam_ldb,
4660 trust_tdo->domain_name.string,
4661 trust_attrs,
4662 mem_ctx, &trusts_res);
4663 if (!NT_STATUS_IS_OK(status)) {
4664 goto done;
4668 * now check against the other domains.
4669 * and generate LSA_FOREST_TRUST_COLLISION_TDO collisions.
4671 for (i = 0; i < trusts_res->count; i++) {
4672 struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
4673 struct ForestTrustInfo *fti = NULL;
4674 struct lsa_ForestTrustInformation *lfti = NULL;
4676 status = dsdb_trust_parse_tdo_info(mem_ctx,
4677 trusts_res->msgs[i],
4678 &tdo);
4679 if (!NT_STATUS_IS_OK(status)) {
4680 goto done;
4683 status = dsdb_trust_parse_forest_info(tdo,
4684 trusts_res->msgs[i],
4685 &fti);
4686 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
4687 continue;
4689 if (!NT_STATUS_IS_OK(status)) {
4690 goto done;
4693 status = dsdb_trust_forest_info_to_lsa(tdo, fti, &lfti);
4694 if (!NT_STATUS_IS_OK(status)) {
4695 goto done;
4698 status = dsdb_trust_verify_forest_info(tdo, lfti,
4699 LSA_FOREST_TRUST_COLLISION_TDO,
4700 c_info, step1_lfti);
4701 if (!NT_STATUS_IS_OK(status)) {
4702 goto done;
4705 TALLOC_FREE(tdo);
4708 if (r->in.check_only != 0) {
4709 status = NT_STATUS_OK;
4710 goto done;
4714 * not just a check, write info back
4718 * normalize the given forest trust info.
4720 * Step2: adds TOP_LEVEL_NAME[_EX] in reverse order,
4721 * followed by DOMAIN_INFO in reverse order. It also removes
4722 * possible NULL entries from Step1.
4724 status = dsdb_trust_normalize_forest_info_step2(mem_ctx, step1_lfti,
4725 &step2_lfti);
4726 if (!NT_STATUS_IS_OK(status)) {
4727 goto done;
4730 status = dsdb_trust_forest_info_from_lsa(mem_ctx, step2_lfti,
4731 &trust_fti);
4732 if (!NT_STATUS_IS_OK(status)) {
4733 goto done;
4736 ndr_err = ndr_push_struct_blob(&ft_blob, mem_ctx, trust_fti,
4737 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4738 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4739 status = NT_STATUS_INVALID_PARAMETER;
4740 goto done;
4743 msg = ldb_msg_new(mem_ctx);
4744 if (msg == NULL) {
4745 status = NT_STATUS_NO_MEMORY;
4746 goto done;
4749 msg->dn = ldb_dn_copy(mem_ctx, trust_tdo_msg->dn);
4750 if (!msg->dn) {
4751 status = NT_STATUS_NO_MEMORY;
4752 goto done;
4755 ret = ldb_msg_append_value(msg, "msDS-TrustForestTrustInfo",
4756 &ft_blob, LDB_FLAG_MOD_REPLACE);
4757 if (ret != LDB_SUCCESS) {
4758 status = NT_STATUS_NO_MEMORY;
4759 goto done;
4762 ret = ldb_modify(p_state->sam_ldb, msg);
4763 if (ret != LDB_SUCCESS) {
4764 status = dsdb_ldb_err_to_ntstatus(ret);
4766 DEBUG(0, ("Failed to store Forest Trust Info: %s\n",
4767 ldb_errstring(p_state->sam_ldb)));
4769 goto done;
4772 /* ok, all fine, commit transaction and return */
4773 in_transaction = false;
4774 ret = ldb_transaction_commit(p_state->sam_ldb);
4775 if (ret != LDB_SUCCESS) {
4776 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
4777 goto done;
4781 * Notify winbindd that we have a acquired forest trust info
4783 status = irpc_servers_byname(imsg_ctx,
4784 mem_ctx,
4785 "winbind_server",
4786 &num_server_ids,
4787 &server_ids);
4788 if (!NT_STATUS_IS_OK(status)) {
4789 DBG_ERR("irpc_servers_byname failed\n");
4790 goto done;
4793 imessaging_send(imsg_ctx,
4794 server_ids[0],
4795 MSG_WINBIND_RELOAD_TRUSTED_DOMAINS,
4796 NULL);
4798 status = NT_STATUS_OK;
4800 done:
4801 if (NT_STATUS_IS_OK(status) && c_info->count != 0) {
4802 *r->out.collision_info = c_info;
4805 if (in_transaction) {
4806 ldb_transaction_cancel(p_state->sam_ldb);
4809 return status;
4813 lsa_CREDRRENAME
4815 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4816 struct lsa_CREDRRENAME *r)
4818 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4824 lsa_LSAROPENPOLICYSCE
4826 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4827 struct lsa_LSAROPENPOLICYSCE *r)
4829 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4834 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
4836 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4837 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4839 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4844 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
4846 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4847 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4849 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4854 lsa_LSARADTREPORTSECURITYEVENT
4856 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4857 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4859 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4863 lsa_Opnum82NotUsedOnWire
4865 static void dcesrv_lsa_Opnum82NotUsedOnWire(struct dcesrv_call_state *dce_call,
4866 TALLOC_CTX *mem_ctx,
4867 struct lsa_Opnum82NotUsedOnWire *r)
4869 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4873 lsa_Opnum83NotUsedOnWire
4875 static void dcesrv_lsa_Opnum83NotUsedOnWire(struct dcesrv_call_state *dce_call,
4876 TALLOC_CTX *mem_ctx,
4877 struct lsa_Opnum83NotUsedOnWire *r)
4879 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4883 lsa_Opnum84NotUsedOnWire
4885 static void dcesrv_lsa_Opnum84NotUsedOnWire(struct dcesrv_call_state *dce_call,
4886 TALLOC_CTX *mem_ctx,
4887 struct lsa_Opnum84NotUsedOnWire *r)
4889 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4893 lsa_Opnum85NotUsedOnWire
4895 static void dcesrv_lsa_Opnum85NotUsedOnWire(struct dcesrv_call_state *dce_call,
4896 TALLOC_CTX *mem_ctx,
4897 struct lsa_Opnum85NotUsedOnWire *r)
4899 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4903 lsa_Opnum86NotUsedOnWire
4905 static void dcesrv_lsa_Opnum86NotUsedOnWire(struct dcesrv_call_state *dce_call,
4906 TALLOC_CTX *mem_ctx,
4907 struct lsa_Opnum86NotUsedOnWire *r)
4909 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4913 lsa_Opnum87NotUsedOnWire
4915 static void dcesrv_lsa_Opnum87NotUsedOnWire(struct dcesrv_call_state *dce_call,
4916 TALLOC_CTX *mem_ctx,
4917 struct lsa_Opnum87NotUsedOnWire *r)
4919 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4923 lsa_Opnum88NotUsedOnWire
4925 static void dcesrv_lsa_Opnum88NotUsedOnWire(struct dcesrv_call_state *dce_call,
4926 TALLOC_CTX *mem_ctx,
4927 struct lsa_Opnum88NotUsedOnWire *r)
4929 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4933 lsa_Opnum89NotUsedOnWire
4935 static void dcesrv_lsa_Opnum89NotUsedOnWire(struct dcesrv_call_state *dce_call,
4936 TALLOC_CTX *mem_ctx,
4937 struct lsa_Opnum89NotUsedOnWire *r)
4939 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4943 lsa_Opnum90NotUsedOnWire
4945 static void dcesrv_lsa_Opnum90NotUsedOnWire(struct dcesrv_call_state *dce_call,
4946 TALLOC_CTX *mem_ctx,
4947 struct lsa_Opnum90NotUsedOnWire *r)
4949 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4953 lsa_Opnum91NotUsedOnWire
4955 static void dcesrv_lsa_Opnum91NotUsedOnWire(struct dcesrv_call_state *dce_call,
4956 TALLOC_CTX *mem_ctx,
4957 struct lsa_Opnum91NotUsedOnWire *r)
4959 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4963 lsa_Opnum92NotUsedOnWire
4965 static void dcesrv_lsa_Opnum92NotUsedOnWire(struct dcesrv_call_state *dce_call,
4966 TALLOC_CTX *mem_ctx,
4967 struct lsa_Opnum92NotUsedOnWire *r)
4969 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4973 lsa_Opnum93NotUsedOnWire
4975 static void dcesrv_lsa_Opnum93NotUsedOnWire(struct dcesrv_call_state *dce_call,
4976 TALLOC_CTX *mem_ctx,
4977 struct lsa_Opnum93NotUsedOnWire *r)
4979 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4983 lsa_Opnum94NotUsedOnWire
4985 static void dcesrv_lsa_Opnum94NotUsedOnWire(struct dcesrv_call_state *dce_call,
4986 TALLOC_CTX *mem_ctx,
4987 struct lsa_Opnum94NotUsedOnWire *r)
4989 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4993 lsa_Opnum95NotUsedOnWire
4995 static void dcesrv_lsa_Opnum95NotUsedOnWire(struct dcesrv_call_state *dce_call,
4996 TALLOC_CTX *mem_ctx,
4997 struct lsa_Opnum95NotUsedOnWire *r)
4999 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5003 lsa_Opnum96NotUsedOnWire
5005 static void dcesrv_lsa_Opnum96NotUsedOnWire(struct dcesrv_call_state *dce_call,
5006 TALLOC_CTX *mem_ctx,
5007 struct lsa_Opnum96NotUsedOnWire *r)
5009 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5013 lsa_Opnum97NotUsedOnWire
5015 static void dcesrv_lsa_Opnum97NotUsedOnWire(struct dcesrv_call_state *dce_call,
5016 TALLOC_CTX *mem_ctx,
5017 struct lsa_Opnum97NotUsedOnWire *r)
5019 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5023 lsa_Opnum98NotUsedOnWire
5025 static void dcesrv_lsa_Opnum98NotUsedOnWire(struct dcesrv_call_state *dce_call,
5026 TALLOC_CTX *mem_ctx,
5027 struct lsa_Opnum98NotUsedOnWire *r)
5029 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5033 lsa_Opnum99NotUsedOnWire
5035 static void dcesrv_lsa_Opnum99NotUsedOnWire(struct dcesrv_call_state *dce_call,
5036 TALLOC_CTX *mem_ctx,
5037 struct lsa_Opnum99NotUsedOnWire *r)
5039 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5043 lsa_Opnum100NotUsedOnWire
5045 static void dcesrv_lsa_Opnum100NotUsedOnWire(struct dcesrv_call_state *dce_call,
5046 TALLOC_CTX *mem_ctx,
5047 struct lsa_Opnum100NotUsedOnWire *r)
5049 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5053 lsa_Opnum101NotUsedOnWire
5055 static void dcesrv_lsa_Opnum101NotUsedOnWire(struct dcesrv_call_state *dce_call,
5056 TALLOC_CTX *mem_ctx,
5057 struct lsa_Opnum101NotUsedOnWire *r)
5059 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5063 lsa_Opnum102NotUsedOnWire
5065 static void dcesrv_lsa_Opnum102NotUsedOnWire(struct dcesrv_call_state *dce_call,
5066 TALLOC_CTX *mem_ctx,
5067 struct lsa_Opnum102NotUsedOnWire *r)
5069 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5073 lsa_Opnum103NotUsedOnWire
5075 static void dcesrv_lsa_Opnum103NotUsedOnWire(struct dcesrv_call_state *dce_call,
5076 TALLOC_CTX *mem_ctx,
5077 struct lsa_Opnum103NotUsedOnWire *r)
5079 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5083 lsa_Opnum104NotUsedOnWire
5085 static void dcesrv_lsa_Opnum104NotUsedOnWire(struct dcesrv_call_state *dce_call,
5086 TALLOC_CTX *mem_ctx,
5087 struct lsa_Opnum104NotUsedOnWire *r)
5089 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5093 lsa_Opnum105NotUsedOnWire
5095 static void dcesrv_lsa_Opnum105NotUsedOnWire(struct dcesrv_call_state *dce_call,
5096 TALLOC_CTX *mem_ctx,
5097 struct lsa_Opnum105NotUsedOnWire *r)
5099 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5103 lsa_Opnum106NotUsedOnWire
5105 static void dcesrv_lsa_Opnum106NotUsedOnWire(struct dcesrv_call_state *dce_call,
5106 TALLOC_CTX *mem_ctx,
5107 struct lsa_Opnum106NotUsedOnWire *r)
5109 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5113 lsa_Opnum107NotUsedOnWire
5115 static void dcesrv_lsa_Opnum107NotUsedOnWire(struct dcesrv_call_state *dce_call,
5116 TALLOC_CTX *mem_ctx,
5117 struct lsa_Opnum107NotUsedOnWire *r)
5119 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5123 lsa_Opnum108NotUsedOnWire
5125 static void dcesrv_lsa_Opnum108NotUsedOnWire(struct dcesrv_call_state *dce_call,
5126 TALLOC_CTX *mem_ctx,
5127 struct lsa_Opnum108NotUsedOnWire *r)
5129 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5133 lsa_Opnum109NotUsedOnWire
5135 static void dcesrv_lsa_Opnum109NotUsedOnWire(struct dcesrv_call_state *dce_call,
5136 TALLOC_CTX *mem_ctx,
5137 struct lsa_Opnum109NotUsedOnWire *r)
5139 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5143 lsa_Opnum110NotUsedOnWire
5145 static void dcesrv_lsa_Opnum110NotUsedOnWire(struct dcesrv_call_state *dce_call,
5146 TALLOC_CTX *mem_ctx,
5147 struct lsa_Opnum110NotUsedOnWire *r)
5149 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5153 lsa_Opnum111NotUsedOnWire
5155 static void dcesrv_lsa_Opnum111NotUsedOnWire(struct dcesrv_call_state *dce_call,
5156 TALLOC_CTX *mem_ctx,
5157 struct lsa_Opnum111NotUsedOnWire *r)
5159 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5163 lsa_Opnum112NotUsedOnWire
5165 static void dcesrv_lsa_Opnum112NotUsedOnWire(struct dcesrv_call_state *dce_call,
5166 TALLOC_CTX *mem_ctx,
5167 struct lsa_Opnum112NotUsedOnWire *r)
5169 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5173 lsa_Opnum113NotUsedOnWire
5175 static void dcesrv_lsa_Opnum113NotUsedOnWire(struct dcesrv_call_state *dce_call,
5176 TALLOC_CTX *mem_ctx,
5177 struct lsa_Opnum113NotUsedOnWire *r)
5179 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5183 lsa_Opnum114NotUsedOnWire
5185 static void dcesrv_lsa_Opnum114NotUsedOnWire(struct dcesrv_call_state *dce_call,
5186 TALLOC_CTX *mem_ctx,
5187 struct lsa_Opnum114NotUsedOnWire *r)
5189 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5193 lsa_Opnum115NotUsedOnWire
5195 static void dcesrv_lsa_Opnum115NotUsedOnWire(struct dcesrv_call_state *dce_call,
5196 TALLOC_CTX *mem_ctx,
5197 struct lsa_Opnum115NotUsedOnWire *r)
5199 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5203 lsa_Opnum116NotUsedOnWire
5205 static void dcesrv_lsa_Opnum116NotUsedOnWire(struct dcesrv_call_state *dce_call,
5206 TALLOC_CTX *mem_ctx,
5207 struct lsa_Opnum116NotUsedOnWire *r)
5209 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5213 lsa_Opnum117NotUsedOnWire
5215 static void dcesrv_lsa_Opnum117NotUsedOnWire(struct dcesrv_call_state *dce_call,
5216 TALLOC_CTX *mem_ctx,
5217 struct lsa_Opnum117NotUsedOnWire *r)
5219 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5223 lsa_Opnum118NotUsedOnWire
5225 static void dcesrv_lsa_Opnum118NotUsedOnWire(struct dcesrv_call_state *dce_call,
5226 TALLOC_CTX *mem_ctx,
5227 struct lsa_Opnum118NotUsedOnWire *r)
5229 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5233 lsa_Opnum119NotUsedOnWire
5235 static void dcesrv_lsa_Opnum119NotUsedOnWire(struct dcesrv_call_state *dce_call,
5236 TALLOC_CTX *mem_ctx,
5237 struct lsa_Opnum119NotUsedOnWire *r)
5239 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5243 lsa_Opnum120NotUsedOnWire
5245 static void dcesrv_lsa_Opnum120NotUsedOnWire(struct dcesrv_call_state *dce_call,
5246 TALLOC_CTX *mem_ctx,
5247 struct lsa_Opnum120NotUsedOnWire *r)
5249 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5253 lsa_Opnum121NotUsedOnWire
5255 static void dcesrv_lsa_Opnum121NotUsedOnWire(struct dcesrv_call_state *dce_call,
5256 TALLOC_CTX *mem_ctx,
5257 struct lsa_Opnum121NotUsedOnWire *r)
5259 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5263 lsa_Opnum122NotUsedOnWire
5265 static void dcesrv_lsa_Opnum122NotUsedOnWire(struct dcesrv_call_state *dce_call,
5266 TALLOC_CTX *mem_ctx,
5267 struct lsa_Opnum122NotUsedOnWire *r)
5269 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5273 lsa_Opnum123NotUsedOnWire
5275 static void dcesrv_lsa_Opnum123NotUsedOnWire(struct dcesrv_call_state *dce_call,
5276 TALLOC_CTX *mem_ctx,
5277 struct lsa_Opnum123NotUsedOnWire *r)
5279 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5283 lsa_Opnum124NotUsedOnWire
5285 static void dcesrv_lsa_Opnum124NotUsedOnWire(struct dcesrv_call_state *dce_call,
5286 TALLOC_CTX *mem_ctx,
5287 struct lsa_Opnum124NotUsedOnWire *r)
5289 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5293 lsa_Opnum125NotUsedOnWire
5295 static void dcesrv_lsa_Opnum125NotUsedOnWire(struct dcesrv_call_state *dce_call,
5296 TALLOC_CTX *mem_ctx,
5297 struct lsa_Opnum125NotUsedOnWire *r)
5299 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5303 lsa_Opnum126NotUsedOnWire
5305 static void dcesrv_lsa_Opnum126NotUsedOnWire(struct dcesrv_call_state *dce_call,
5306 TALLOC_CTX *mem_ctx,
5307 struct lsa_Opnum126NotUsedOnWire *r)
5309 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5313 lsa_Opnum127NotUsedOnWire
5315 static void dcesrv_lsa_Opnum127NotUsedOnWire(struct dcesrv_call_state *dce_call,
5316 TALLOC_CTX *mem_ctx,
5317 struct lsa_Opnum127NotUsedOnWire *r)
5319 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5323 lsa_Opnum128NotUsedOnWire
5325 static void dcesrv_lsa_Opnum128NotUsedOnWire(struct dcesrv_call_state *dce_call,
5326 TALLOC_CTX *mem_ctx,
5327 struct lsa_Opnum128NotUsedOnWire *r)
5329 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5333 lsa_CreateTrustedDomainEx3
5335 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx3(struct dcesrv_call_state *dce_call,
5336 TALLOC_CTX *mem_ctx,
5337 struct lsa_CreateTrustedDomainEx3 *r)
5339 struct dcesrv_handle *policy_handle = NULL;
5340 struct trustDomainPasswords auth_struct = {
5341 .incoming_size = 0,
5343 NTSTATUS status;
5345 ZERO_STRUCTP(r->out.trustdom_handle);
5347 DCESRV_PULL_HANDLE(policy_handle,
5348 r->in.policy_handle,
5349 LSA_HANDLE_POLICY);
5351 status = dcesrv_lsa_CreateTrustedDomain_precheck(mem_ctx,
5352 policy_handle,
5353 r->in.info);
5354 if (!NT_STATUS_IS_OK(status)) {
5355 return status;
5358 status = get_trustdom_auth_blob_aes(dce_call,
5359 mem_ctx,
5360 r->in.auth_info_internal,
5361 &auth_struct);
5362 if (!NT_STATUS_IS_OK(status)) {
5363 return status;
5366 status = dcesrv_lsa_CreateTrustedDomain_common(dce_call,
5367 mem_ctx,
5368 policy_handle,
5369 r->in.access_mask,
5370 r->in.info,
5371 &auth_struct,
5372 &r->out.trustdom_handle);
5373 if (!NT_STATUS_IS_OK(status)) {
5374 return status;
5377 return NT_STATUS_OK;
5381 lsa_Opnum131NotUsedOnWire
5383 static void dcesrv_lsa_Opnum131NotUsedOnWire(struct dcesrv_call_state *dce_call,
5384 TALLOC_CTX *mem_ctx,
5385 struct lsa_Opnum131NotUsedOnWire *r)
5387 DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5391 lsa_lsaRQueryForestTrustInformation2
5393 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation2(
5394 struct dcesrv_call_state *dce_call,
5395 TALLOC_CTX *mem_ctx,
5396 struct lsa_lsaRQueryForestTrustInformation2 *r)
5398 /* TODO */
5399 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5403 lsa_lsaRSetForestTrustInformation2
5405 static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation2(struct dcesrv_call_state *dce_call,
5406 TALLOC_CTX *mem_ctx,
5407 struct lsa_lsaRSetForestTrustInformation2 *r)
5409 /* TODO */
5410 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5413 /* include the generated boilerplate */
5414 #include "librpc/gen_ndr/ndr_lsa_s.c"
5418 /*****************************************
5419 NOTE! The remaining calls below were
5420 removed in w2k3, so the DCESRV_FAULT()
5421 replies are the correct implementation. Do
5422 not try and fill these in with anything else
5423 ******************************************/
5426 dssetup_DsRoleDnsNameToFlatName
5428 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5429 struct dssetup_DsRoleDnsNameToFlatName *r)
5431 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5436 dssetup_DsRoleDcAsDc
5438 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5439 struct dssetup_DsRoleDcAsDc *r)
5441 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5446 dssetup_DsRoleDcAsReplica
5448 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5449 struct dssetup_DsRoleDcAsReplica *r)
5451 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5456 dssetup_DsRoleDemoteDc
5458 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5459 struct dssetup_DsRoleDemoteDc *r)
5461 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5466 dssetup_DsRoleGetDcOperationProgress
5468 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5469 struct dssetup_DsRoleGetDcOperationProgress *r)
5471 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5476 dssetup_DsRoleGetDcOperationResults
5478 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5479 struct dssetup_DsRoleGetDcOperationResults *r)
5481 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5486 dssetup_DsRoleCancel
5488 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5489 struct dssetup_DsRoleCancel *r)
5491 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5496 dssetup_DsRoleServerSaveStateForUpgrade
5498 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5499 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
5501 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5506 dssetup_DsRoleUpgradeDownlevelServer
5508 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5509 struct dssetup_DsRoleUpgradeDownlevelServer *r)
5511 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5516 dssetup_DsRoleAbortDownlevelServerUpgrade
5518 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5519 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
5521 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5525 /* include the generated boilerplate */
5526 #include "librpc/gen_ndr/ndr_dssetup_s.c"
5528 NTSTATUS dcerpc_server_lsa_init(TALLOC_CTX *ctx)
5530 NTSTATUS ret;
5532 ret = dcerpc_server_dssetup_init(ctx);
5533 if (!NT_STATUS_IS_OK(ret)) {
5534 return ret;
5536 ret = dcerpc_server_lsarpc_init(ctx);
5537 if (!NT_STATUS_IS_OK(ret)) {
5538 return ret;
5540 return ret;