1 /* need access mask/acl implementation */
4 Unix SMB/CIFS implementation.
6 endpoint server for the lsarpc pipe
8 Copyright (C) Andrew Tridgell 2004
9 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "rpc_server/lsa/lsa.h"
26 #include "system/kerberos.h"
27 #include "auth/kerberos/kerberos.h"
28 #include "librpc/gen_ndr/ndr_drsblobs.h"
29 #include "librpc/gen_ndr/ndr_lsa.h"
30 #include "../lib/crypto/crypto.h"
31 #include "lib/util/tsort.h"
32 #include "dsdb/common/util.h"
35 this type allows us to distinguish handle types
39 state associated with a lsa_OpenAccount() operation
41 struct lsa_account_state {
42 struct lsa_policy_state *policy;
44 struct dom_sid *account_sid;
49 state associated with a lsa_OpenSecret() operation
51 struct lsa_secret_state {
52 struct lsa_policy_state *policy;
54 struct ldb_dn *secret_dn;
55 struct ldb_context *sam_ldb;
60 state associated with a lsa_OpenTrustedDomain() operation
62 struct lsa_trusted_domain_state {
63 struct lsa_policy_state *policy;
65 struct ldb_dn *trusted_domain_dn;
66 struct ldb_dn *trusted_domain_user_dn;
70 this is based on the samba3 function make_lsa_object_sd()
71 It uses the same logic, but with samba4 helper functions
73 static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
74 struct security_descriptor **sd,
80 struct dom_sid *domain_sid, *domain_admins_sid;
81 const char *domain_admins_sid_str, *sidstr;
82 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
84 status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
85 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
87 domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
88 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid, tmp_ctx);
90 domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
91 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid_str, tmp_ctx);
93 sidstr = dom_sid_string(tmp_ctx, sid);
94 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, tmp_ctx);
96 *sd = security_descriptor_dacl_create(mem_ctx,
100 SEC_ACE_TYPE_ACCESS_ALLOWED,
101 SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,
103 SID_BUILTIN_ADMINISTRATORS,
104 SEC_ACE_TYPE_ACCESS_ALLOWED,
107 SID_BUILTIN_ACCOUNT_OPERATORS,
108 SEC_ACE_TYPE_ACCESS_ALLOWED,
111 domain_admins_sid_str,
112 SEC_ACE_TYPE_ACCESS_ALLOWED,
116 SEC_ACE_TYPE_ACCESS_ALLOWED,
120 talloc_free(tmp_ctx);
122 NT_STATUS_HAVE_NO_MEMORY(*sd);
128 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
130 struct lsa_EnumAccountRights *r);
132 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
134 struct lsa_policy_state *state,
137 const struct lsa_RightSet *rights);
142 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
145 struct dcesrv_handle *h;
147 *r->out.handle = *r->in.handle;
149 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
153 ZERO_STRUCTP(r->out.handle);
162 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
163 struct lsa_Delete *r)
165 return NT_STATUS_NOT_SUPPORTED;
172 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
173 struct lsa_DeleteObject *r)
175 struct dcesrv_handle *h;
178 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
180 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
181 struct lsa_secret_state *secret_state = h->data;
183 /* Ensure user is permitted to delete this... */
184 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
186 case SECURITY_SYSTEM:
187 case SECURITY_ADMINISTRATOR:
190 /* Users and anonymous are not allowed to delete things */
191 return NT_STATUS_ACCESS_DENIED;
194 ret = ldb_delete(secret_state->sam_ldb,
195 secret_state->secret_dn);
196 if (ret != LDB_SUCCESS) {
197 return NT_STATUS_INVALID_HANDLE;
200 ZERO_STRUCTP(r->out.handle);
204 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
205 struct lsa_trusted_domain_state *trusted_domain_state =
206 talloc_get_type(h->data, struct lsa_trusted_domain_state);
207 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
208 if (ret != LDB_SUCCESS) {
209 return NT_STATUS_INTERNAL_DB_CORRUPTION;
212 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
213 trusted_domain_state->trusted_domain_dn);
214 if (ret != LDB_SUCCESS) {
215 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
216 return NT_STATUS_INVALID_HANDLE;
219 if (trusted_domain_state->trusted_domain_user_dn) {
220 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
221 trusted_domain_state->trusted_domain_user_dn);
222 if (ret != LDB_SUCCESS) {
223 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
224 return NT_STATUS_INVALID_HANDLE;
228 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
229 if (ret != LDB_SUCCESS) {
230 return NT_STATUS_INTERNAL_DB_CORRUPTION;
233 ZERO_STRUCTP(r->out.handle);
237 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
238 struct lsa_RightSet *rights;
239 struct lsa_account_state *astate;
240 struct lsa_EnumAccountRights r2;
243 rights = talloc(mem_ctx, struct lsa_RightSet);
245 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
249 r2.in.handle = &astate->policy->handle->wire_handle;
250 r2.in.sid = astate->account_sid;
251 r2.out.rights = rights;
253 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
254 but we have a LSA_HANDLE_ACCOUNT here, so this call
256 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
257 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
261 if (!NT_STATUS_IS_OK(status)) {
265 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
266 LDB_FLAG_MOD_DELETE, astate->account_sid,
268 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
272 if (!NT_STATUS_IS_OK(status)) {
276 ZERO_STRUCTP(r->out.handle);
281 return NT_STATUS_INVALID_HANDLE;
288 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
289 struct lsa_EnumPrivs *r)
291 struct dcesrv_handle *h;
292 struct lsa_policy_state *state;
294 const char *privname;
296 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
300 i = *r->in.resume_handle;
303 while ((privname = sec_privilege_name(i)) &&
304 r->out.privs->count < r->in.max_count) {
305 struct lsa_PrivEntry *e;
307 r->out.privs->privs = talloc_realloc(r->out.privs,
309 struct lsa_PrivEntry,
310 r->out.privs->count+1);
311 if (r->out.privs->privs == NULL) {
312 return NT_STATUS_NO_MEMORY;
314 e = &r->out.privs->privs[r->out.privs->count];
317 e->name.string = privname;
318 r->out.privs->count++;
322 *r->out.resume_handle = i;
331 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
332 struct lsa_QuerySecurity *r)
334 struct dcesrv_handle *h;
335 struct security_descriptor *sd;
339 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
341 sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
343 if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
344 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid, 0);
345 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
346 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid,
347 LSA_ACCOUNT_ALL_ACCESS);
349 return NT_STATUS_INVALID_HANDLE;
351 NT_STATUS_NOT_OK_RETURN(status);
353 (*r->out.sdbuf) = talloc(mem_ctx, struct sec_desc_buf);
354 NT_STATUS_HAVE_NO_MEMORY(*r->out.sdbuf);
356 (*r->out.sdbuf)->sd = sd;
365 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
366 struct lsa_SetSecObj *r)
368 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
375 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
376 struct lsa_ChangePassword *r)
378 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
382 dssetup_DsRoleGetPrimaryDomainInformation
384 This is not an LSA call, but is the only call left on the DSSETUP
385 pipe (after the pipe was truncated), and needs lsa_get_policy_state
387 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
389 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
391 union dssetup_DsRoleInfo *info;
393 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
394 W_ERROR_HAVE_NO_MEMORY(info);
396 switch (r->in.level) {
397 case DS_ROLE_BASIC_INFORMATION:
399 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
401 const char *domain = NULL;
402 const char *dns_domain = NULL;
403 const char *forest = NULL;
404 struct GUID domain_guid;
405 struct lsa_policy_state *state;
407 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
408 if (!NT_STATUS_IS_OK(status)) {
409 return ntstatus_to_werror(status);
412 ZERO_STRUCT(domain_guid);
414 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
415 case ROLE_STANDALONE:
416 role = DS_ROLE_STANDALONE_SERVER;
418 case ROLE_DOMAIN_MEMBER:
419 role = DS_ROLE_MEMBER_SERVER;
421 case ROLE_DOMAIN_CONTROLLER:
422 if (samdb_is_pdc(state->sam_ldb)) {
423 role = DS_ROLE_PRIMARY_DC;
425 role = DS_ROLE_BACKUP_DC;
430 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
431 case ROLE_STANDALONE:
432 domain = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
433 W_ERROR_HAVE_NO_MEMORY(domain);
435 case ROLE_DOMAIN_MEMBER:
436 domain = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
437 W_ERROR_HAVE_NO_MEMORY(domain);
438 /* TODO: what is with dns_domain and forest and guid? */
440 case ROLE_DOMAIN_CONTROLLER:
441 flags = DS_ROLE_PRIMARY_DS_RUNNING;
443 if (state->mixed_domain == 1) {
444 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
447 domain = state->domain_name;
448 dns_domain = state->domain_dns;
449 forest = state->forest_dns;
451 domain_guid = state->domain_guid;
452 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
456 info->basic.role = role;
457 info->basic.flags = flags;
458 info->basic.domain = domain;
459 info->basic.dns_domain = dns_domain;
460 info->basic.forest = forest;
461 info->basic.domain_guid = domain_guid;
466 case DS_ROLE_UPGRADE_STATUS:
468 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
469 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
474 case DS_ROLE_OP_STATUS:
476 info->opstatus.status = DS_ROLE_OP_IDLE;
482 return WERR_INVALID_PARAM;
487 fill in the AccountDomain info
489 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
490 struct lsa_DomainInfo *info)
492 info->name.string = state->domain_name;
493 info->sid = state->domain_sid;
499 fill in the DNS domain info
501 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
502 struct lsa_DnsDomainInfo *info)
504 info->name.string = state->domain_name;
505 info->sid = state->domain_sid;
506 info->dns_domain.string = state->domain_dns;
507 info->dns_forest.string = state->forest_dns;
508 info->domain_guid = state->domain_guid;
516 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
517 struct lsa_QueryInfoPolicy2 *r)
519 struct lsa_policy_state *state;
520 struct dcesrv_handle *h;
521 union lsa_PolicyInformation *info;
525 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
529 info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
531 return NT_STATUS_NO_MEMORY;
535 switch (r->in.level) {
536 case LSA_POLICY_INFO_AUDIT_LOG:
537 /* we don't need to fill in any of this */
538 ZERO_STRUCT(info->audit_log);
540 case LSA_POLICY_INFO_AUDIT_EVENTS:
541 /* we don't need to fill in any of this */
542 ZERO_STRUCT(info->audit_events);
544 case LSA_POLICY_INFO_PD:
545 /* we don't need to fill in any of this */
546 ZERO_STRUCT(info->pd);
549 case LSA_POLICY_INFO_DOMAIN:
550 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
551 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
552 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
553 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
554 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
556 case LSA_POLICY_INFO_ROLE:
557 info->role.role = LSA_ROLE_PRIMARY;
560 case LSA_POLICY_INFO_DNS:
561 case LSA_POLICY_INFO_DNS_INT:
562 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
564 case LSA_POLICY_INFO_REPLICA:
565 ZERO_STRUCT(info->replica);
568 case LSA_POLICY_INFO_QUOTA:
569 ZERO_STRUCT(info->quota);
572 case LSA_POLICY_INFO_MOD:
573 case LSA_POLICY_INFO_AUDIT_FULL_SET:
574 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
575 /* windows gives INVALID_PARAMETER */
577 return NT_STATUS_INVALID_PARAMETER;
581 return NT_STATUS_INVALID_INFO_CLASS;
587 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
588 struct lsa_QueryInfoPolicy *r)
590 struct lsa_QueryInfoPolicy2 r2;
595 r2.in.handle = r->in.handle;
596 r2.in.level = r->in.level;
597 r2.out.info = r->out.info;
599 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
607 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
608 struct lsa_SetInfoPolicy *r)
610 /* need to support this */
611 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
618 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
619 struct lsa_ClearAuditLog *r)
621 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
628 This call does not seem to have any long-term effects, hence no database operations
630 we need to talk to the MS product group to find out what this account database means!
632 answer is that the lsa database is totally separate from the SAM and
633 ldap databases. We are going to need a separate ldb to store these
634 accounts. The SIDs on this account bear no relation to the SIDs in
637 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
638 struct lsa_CreateAccount *r)
640 struct lsa_account_state *astate;
642 struct lsa_policy_state *state;
643 struct dcesrv_handle *h, *ah;
645 ZERO_STRUCTP(r->out.acct_handle);
647 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
651 astate = talloc(dce_call->conn, struct lsa_account_state);
652 if (astate == NULL) {
653 return NT_STATUS_NO_MEMORY;
656 astate->account_sid = dom_sid_dup(astate, r->in.sid);
657 if (astate->account_sid == NULL) {
659 return NT_STATUS_NO_MEMORY;
662 astate->policy = talloc_reference(astate, state);
663 astate->access_mask = r->in.access_mask;
665 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
668 return NT_STATUS_NO_MEMORY;
671 ah->data = talloc_steal(ah, astate);
673 *r->out.acct_handle = ah->wire_handle;
682 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
683 struct lsa_EnumAccounts *r)
685 struct dcesrv_handle *h;
686 struct lsa_policy_state *state;
688 struct ldb_message **res;
689 const char * const attrs[] = { "objectSid", NULL};
692 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
696 /* NOTE: This call must only return accounts that have at least
699 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
700 "(&(objectSid=*)(privilege=*))");
702 return NT_STATUS_INTERNAL_DB_CORRUPTION;
705 if (*r->in.resume_handle >= ret) {
706 return NT_STATUS_NO_MORE_ENTRIES;
709 count = ret - *r->in.resume_handle;
710 if (count > r->in.num_entries) {
711 count = r->in.num_entries;
715 return NT_STATUS_NO_MORE_ENTRIES;
718 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
719 if (r->out.sids->sids == NULL) {
720 return NT_STATUS_NO_MEMORY;
723 for (i=0;i<count;i++) {
724 r->out.sids->sids[i].sid =
725 samdb_result_dom_sid(r->out.sids->sids,
726 res[i + *r->in.resume_handle],
728 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
731 r->out.sids->num_sids = count;
732 *r->out.resume_handle = count + *r->in.resume_handle;
738 /* This decrypts and returns Trusted Domain Auth Information Internal data */
739 static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
740 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
741 struct trustDomainPasswords *auth_struct)
743 DATA_BLOB session_key = data_blob(NULL, 0);
744 enum ndr_err_code ndr_err;
747 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
748 if (!NT_STATUS_IS_OK(nt_status)) {
752 arcfour_crypt_blob(auth_blob->data, auth_blob->length, &session_key);
753 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
755 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
756 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
757 return NT_STATUS_INVALID_PARAMETER;
763 static NTSTATUS get_trustauth_inout_blob(struct dcesrv_call_state *dce_call,
765 struct trustAuthInOutBlob *iopw,
766 DATA_BLOB *trustauth_blob)
768 enum ndr_err_code ndr_err;
770 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
772 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
773 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
774 return NT_STATUS_INVALID_PARAMETER;
780 static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx,
781 struct ldb_context *sam_ldb,
782 struct ldb_dn *base_dn,
783 const char *netbios_name,
784 struct trustAuthInOutBlob *in,
785 struct ldb_dn **user_dn)
787 struct ldb_message *msg;
792 dn = ldb_dn_copy(mem_ctx, base_dn);
794 return NT_STATUS_NO_MEMORY;
796 if (!ldb_dn_add_child_fmt(dn, "cn=%s$,cn=users", netbios_name)) {
797 return NT_STATUS_NO_MEMORY;
800 msg = ldb_msg_new(mem_ctx);
802 return NT_STATUS_NO_MEMORY;
806 ret = ldb_msg_add_string(msg, "objectClass", "user");
807 if (ret != LDB_SUCCESS) {
808 return NT_STATUS_NO_MEMORY;
811 ret = ldb_msg_add_fmt(msg, "samAccountName", "%s$", netbios_name);
812 if (ret != LDB_SUCCESS) {
813 return NT_STATUS_NO_MEMORY;
816 ret = ldb_msg_add_fmt(msg, "userAccountControl", "%u",
817 UF_INTERDOMAIN_TRUST_ACCOUNT);
818 if (ret != LDB_SUCCESS) {
819 return NT_STATUS_NO_MEMORY;
822 for (i = 0; i < in->count; i++) {
823 const char *attribute;
825 switch (in->current.array[i].AuthType) {
826 case TRUST_AUTH_TYPE_NT4OWF:
827 attribute = "unicodePwd";
828 v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
831 case TRUST_AUTH_TYPE_CLEAR:
832 attribute = "clearTextPassword";
833 v.data = in->current.array[i].AuthInfo.clear.password;
834 v.length = in->current.array[i].AuthInfo.clear.size;
840 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
841 if (ret != LDB_SUCCESS) {
842 return NT_STATUS_NO_MEMORY;
846 /* create the trusted_domain user account */
847 ret = ldb_add(sam_ldb, msg);
848 if (ret != LDB_SUCCESS) {
849 DEBUG(0,("Failed to create user record %s: %s\n",
850 ldb_dn_get_linearized(msg->dn),
851 ldb_errstring(sam_ldb)));
854 case LDB_ERR_ENTRY_ALREADY_EXISTS:
855 return NT_STATUS_DOMAIN_EXISTS;
856 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
857 return NT_STATUS_ACCESS_DENIED;
859 return NT_STATUS_INTERNAL_DB_CORRUPTION;
870 lsa_CreateTrustedDomainEx2
872 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
874 struct lsa_CreateTrustedDomainEx2 *r,
877 struct dcesrv_handle *policy_handle;
878 struct lsa_policy_state *policy_state;
879 struct lsa_trusted_domain_state *trusted_domain_state;
880 struct dcesrv_handle *handle;
881 struct ldb_message **msgs, *msg;
882 const char *attrs[] = {
885 const char *netbios_name;
886 const char *dns_name;
888 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
889 struct trustDomainPasswords auth_struct;
892 struct ldb_context *sam_ldb;
894 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
895 ZERO_STRUCTP(r->out.trustdom_handle);
897 policy_state = policy_handle->data;
898 sam_ldb = policy_state->sam_ldb;
900 netbios_name = r->in.info->netbios_name.string;
902 return NT_STATUS_INVALID_PARAMETER;
905 dns_name = r->in.info->domain_name.string;
907 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
908 if (!trusted_domain_state) {
909 return NT_STATUS_NO_MEMORY;
911 trusted_domain_state->policy = policy_state;
913 if (strcasecmp(netbios_name, "BUILTIN") == 0
914 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
915 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
916 return NT_STATUS_INVALID_PARAMETER;
919 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
920 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
921 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
922 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
923 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
924 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
927 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
928 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
929 /* No secrets are created at this time, for this function */
930 auth_struct.outgoing.count = 0;
931 auth_struct.incoming.count = 0;
933 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data,
934 r->in.auth_info->auth_blob.size);
935 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
936 &auth_blob, &auth_struct);
937 if (!NT_STATUS_IS_OK(nt_status)) {
941 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
942 if (auth_struct.incoming.count > 1) {
943 return NT_STATUS_INVALID_PARAMETER;
948 if (auth_struct.incoming.count) {
949 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
950 &auth_struct.incoming,
952 if (!NT_STATUS_IS_OK(nt_status)) {
956 trustAuthIncoming = data_blob(NULL, 0);
959 if (auth_struct.outgoing.count) {
960 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
961 &auth_struct.outgoing,
963 if (!NT_STATUS_IS_OK(nt_status)) {
967 trustAuthOutgoing = data_blob(NULL, 0);
970 ret = ldb_transaction_start(sam_ldb);
971 if (ret != LDB_SUCCESS) {
972 return NT_STATUS_INTERNAL_DB_CORRUPTION;
976 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
977 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
978 /* search for the trusted_domain record */
979 ret = gendb_search(sam_ldb,
980 mem_ctx, policy_state->system_dn, &msgs, attrs,
981 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
982 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
984 ldb_transaction_cancel(sam_ldb);
985 return NT_STATUS_OBJECT_NAME_COLLISION;
988 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
989 /* search for the trusted_domain record */
990 ret = gendb_search(sam_ldb,
991 mem_ctx, policy_state->system_dn, &msgs, attrs,
992 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
993 netbios_encoded, netbios_encoded, netbios_encoded);
995 ldb_transaction_cancel(sam_ldb);
996 return NT_STATUS_OBJECT_NAME_COLLISION;
1001 ldb_transaction_cancel(sam_ldb);
1002 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1005 name = dns_name ? dns_name : netbios_name;
1007 msg = ldb_msg_new(mem_ctx);
1009 return NT_STATUS_NO_MEMORY;
1012 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1013 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
1014 ldb_transaction_cancel(sam_ldb);
1015 return NT_STATUS_NO_MEMORY;
1018 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "flatname", netbios_name);
1020 if (r->in.info->sid) {
1021 ret = samdb_msg_add_dom_sid(sam_ldb, mem_ctx, msg, "securityIdentifier", r->in.info->sid);
1022 if (ret != LDB_SUCCESS) {
1023 ldb_transaction_cancel(sam_ldb);
1024 return NT_STATUS_INVALID_PARAMETER;
1028 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
1030 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
1032 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
1034 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
1037 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
1040 if (trustAuthIncoming.data) {
1041 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
1042 if (ret != LDB_SUCCESS) {
1043 ldb_transaction_cancel(sam_ldb);
1044 return NT_STATUS_NO_MEMORY;
1047 if (trustAuthOutgoing.data) {
1048 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
1049 if (ret != LDB_SUCCESS) {
1050 ldb_transaction_cancel(sam_ldb);
1051 return NT_STATUS_NO_MEMORY;
1055 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
1057 /* create the trusted_domain */
1058 ret = dsdb_add(sam_ldb, msg, DSDB_MODIFY_RELAX);
1062 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1063 ldb_transaction_cancel(sam_ldb);
1064 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1065 ldb_dn_get_linearized(msg->dn),
1066 ldb_errstring(sam_ldb)));
1067 return NT_STATUS_DOMAIN_EXISTS;
1068 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1069 ldb_transaction_cancel(sam_ldb);
1070 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1071 ldb_dn_get_linearized(msg->dn),
1072 ldb_errstring(sam_ldb)));
1073 return NT_STATUS_ACCESS_DENIED;
1075 ldb_transaction_cancel(sam_ldb);
1076 DEBUG(0,("Failed to create user record %s: %s\n",
1077 ldb_dn_get_linearized(msg->dn),
1078 ldb_errstring(sam_ldb)));
1079 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1082 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1083 struct ldb_dn *user_dn;
1084 /* Inbound trusts must also create a cn=users object to match */
1085 nt_status = add_trust_user(mem_ctx, sam_ldb,
1086 policy_state->domain_dn,
1088 &auth_struct.incoming,
1090 if (!NT_STATUS_IS_OK(nt_status)) {
1091 ldb_transaction_cancel(sam_ldb);
1095 /* save the trust user dn */
1096 trusted_domain_state->trusted_domain_user_dn
1097 = talloc_steal(trusted_domain_state, user_dn);
1100 ret = ldb_transaction_commit(sam_ldb);
1101 if (ret != LDB_SUCCESS) {
1102 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1105 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1107 return NT_STATUS_NO_MEMORY;
1110 handle->data = talloc_steal(handle, trusted_domain_state);
1112 trusted_domain_state->access_mask = r->in.access_mask;
1113 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1115 *r->out.trustdom_handle = handle->wire_handle;
1117 return NT_STATUS_OK;
1121 lsa_CreateTrustedDomainEx2
1123 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1124 TALLOC_CTX *mem_ctx,
1125 struct lsa_CreateTrustedDomainEx2 *r)
1127 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
1130 lsa_CreateTrustedDomainEx
1132 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1133 TALLOC_CTX *mem_ctx,
1134 struct lsa_CreateTrustedDomainEx *r)
1136 struct lsa_CreateTrustedDomainEx2 r2;
1138 r2.in.policy_handle = r->in.policy_handle;
1139 r2.in.info = r->in.info;
1140 r2.in.auth_info = r->in.auth_info;
1141 r2.out.trustdom_handle = r->out.trustdom_handle;
1142 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
1146 lsa_CreateTrustedDomain
1148 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1149 struct lsa_CreateTrustedDomain *r)
1151 struct lsa_CreateTrustedDomainEx2 r2;
1153 r2.in.policy_handle = r->in.policy_handle;
1154 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1156 return NT_STATUS_NO_MEMORY;
1159 r2.in.info->domain_name.string = NULL;
1160 r2.in.info->netbios_name = r->in.info->name;
1161 r2.in.info->sid = r->in.info->sid;
1162 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1163 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1164 r2.in.info->trust_attributes = 0;
1166 r2.in.access_mask = r->in.access_mask;
1167 r2.out.trustdom_handle = r->out.trustdom_handle;
1169 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1174 lsa_OpenTrustedDomain
1176 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1177 struct lsa_OpenTrustedDomain *r)
1179 struct dcesrv_handle *policy_handle;
1181 struct lsa_policy_state *policy_state;
1182 struct lsa_trusted_domain_state *trusted_domain_state;
1183 struct dcesrv_handle *handle;
1184 struct ldb_message **msgs;
1185 const char *attrs[] = {
1191 const char *sid_string;
1194 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1195 ZERO_STRUCTP(r->out.trustdom_handle);
1196 policy_state = policy_handle->data;
1198 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1199 if (!trusted_domain_state) {
1200 return NT_STATUS_NO_MEMORY;
1202 trusted_domain_state->policy = policy_state;
1204 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1206 return NT_STATUS_NO_MEMORY;
1209 /* search for the trusted_domain record */
1210 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1211 mem_ctx, policy_state->system_dn, &msgs, attrs,
1212 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
1215 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1219 DEBUG(0,("Found %d records matching DN %s\n", ret,
1220 ldb_dn_get_linearized(policy_state->system_dn)));
1221 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1224 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1226 trusted_domain_state->trusted_domain_user_dn = NULL;
1228 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1229 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1230 /* search for the trusted_domain record */
1231 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1232 mem_ctx, policy_state->domain_dn, &msgs, attrs,
1233 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%d))",
1234 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1236 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1239 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1241 return NT_STATUS_NO_MEMORY;
1244 handle->data = talloc_steal(handle, trusted_domain_state);
1246 trusted_domain_state->access_mask = r->in.access_mask;
1247 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1249 *r->out.trustdom_handle = handle->wire_handle;
1251 return NT_STATUS_OK;
1256 lsa_OpenTrustedDomainByName
1258 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1259 TALLOC_CTX *mem_ctx,
1260 struct lsa_OpenTrustedDomainByName *r)
1262 struct dcesrv_handle *policy_handle;
1264 struct lsa_policy_state *policy_state;
1265 struct lsa_trusted_domain_state *trusted_domain_state;
1266 struct dcesrv_handle *handle;
1267 struct ldb_message **msgs;
1268 const char *attrs[] = {
1274 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1275 ZERO_STRUCTP(r->out.trustdom_handle);
1276 policy_state = policy_handle->data;
1278 if (!r->in.name.string) {
1279 return NT_STATUS_INVALID_PARAMETER;
1282 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1283 if (!trusted_domain_state) {
1284 return NT_STATUS_NO_MEMORY;
1286 trusted_domain_state->policy = policy_state;
1288 /* search for the trusted_domain record */
1289 td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string);
1290 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1291 mem_ctx, policy_state->system_dn, &msgs, attrs,
1292 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))"
1293 "(objectclass=trustedDomain))",
1294 td_name, td_name, td_name);
1296 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1300 DEBUG(0,("Found %d records matching DN %s\n", ret,
1301 ldb_dn_get_linearized(policy_state->system_dn)));
1302 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1305 /* TODO: perform access checks */
1307 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1309 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1311 return NT_STATUS_NO_MEMORY;
1314 handle->data = talloc_steal(handle, trusted_domain_state);
1316 trusted_domain_state->access_mask = r->in.access_mask;
1317 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1319 *r->out.trustdom_handle = handle->wire_handle;
1321 return NT_STATUS_OK;
1327 lsa_SetTrustedDomainInfo
1329 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1330 struct lsa_SetTrustedDomainInfo *r)
1332 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1337 /* parameters 4 to 6 are optional if the dn is a dn of a TDO object,
1338 * otherwise at least one must be provided */
1339 static NTSTATUS get_tdo(struct ldb_context *sam, TALLOC_CTX *mem_ctx,
1340 struct ldb_dn *basedn, const char *dns_domain,
1341 const char *netbios, struct dom_sid2 *sid,
1342 struct ldb_message ***msgs)
1344 const char *attrs[] = { "flatname", "trustPartner",
1345 "securityIdentifier", "trustDirection",
1346 "trustType", "trustAttributes",
1348 "msDs-supportedEncryptionTypes", NULL };
1351 char *sidstr = NULL;
1356 if (dns_domain || netbios || sid) {
1357 filter = talloc_strdup(mem_ctx,
1358 "(&(objectclass=trustedDomain)(|");
1360 filter = talloc_strdup(mem_ctx,
1361 "(objectclass=trustedDomain)");
1364 return NT_STATUS_NO_MEMORY;
1368 dns = ldb_binary_encode_string(mem_ctx, dns_domain);
1370 return NT_STATUS_NO_MEMORY;
1372 filter = talloc_asprintf_append(filter,
1373 "(trustPartner=%s)", dns);
1375 return NT_STATUS_NO_MEMORY;
1379 nbn = ldb_binary_encode_string(mem_ctx, netbios);
1381 return NT_STATUS_NO_MEMORY;
1383 filter = talloc_asprintf_append(filter,
1384 "(flatname=%s)", nbn);
1386 return NT_STATUS_NO_MEMORY;
1390 sidstr = dom_sid_string(mem_ctx, sid);
1392 return NT_STATUS_INVALID_PARAMETER;
1394 filter = talloc_asprintf_append(filter,
1395 "(securityIdentifier=%s)",
1398 return NT_STATUS_NO_MEMORY;
1401 if (dns_domain || netbios || sid) {
1402 filter = talloc_asprintf_append(filter, "))");
1404 return NT_STATUS_NO_MEMORY;
1408 ret = gendb_search(sam, mem_ctx, basedn, msgs, attrs, "%s", filter);
1410 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1414 return NT_STATUS_OBJECT_NAME_COLLISION;
1417 return NT_STATUS_OK;
1420 static NTSTATUS update_uint32_t_value(TALLOC_CTX *mem_ctx,
1421 struct ldb_message *orig,
1422 struct ldb_message *dest,
1423 const char *attribute,
1425 uint32_t *orig_value)
1427 const struct ldb_val *orig_val;
1428 uint32_t orig_uint = 0;
1433 orig_val = ldb_msg_find_ldb_val(orig, attribute);
1434 if (!orig_val || !orig_val->data) {
1435 /* add new attribute */
1436 flags = LDB_FLAG_MOD_ADD;
1440 orig_uint = strtoul((const char *)orig_val->data, NULL, 0);
1441 if (errno != 0 || orig_uint != value) {
1442 /* replace also if can't get value */
1443 flags = LDB_FLAG_MOD_REPLACE;
1448 /* stored value is identical, nothing to change */
1452 ret = ldb_msg_add_empty(dest, attribute, flags, NULL);
1453 if (ret != LDB_SUCCESS) {
1454 return NT_STATUS_NO_MEMORY;
1457 str_val = talloc_asprintf(mem_ctx, "%u", value);
1459 return NT_STATUS_NO_MEMORY;
1461 ret = ldb_msg_add_steal_string(dest, attribute, str_val);
1462 if (ret != LDB_SUCCESS) {
1463 return NT_STATUS_NO_MEMORY;
1468 *orig_value = orig_uint;
1470 return NT_STATUS_OK;
1473 static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx,
1474 struct ldb_context *sam_ldb,
1475 struct ldb_dn *base_dn,
1477 const char *netbios_name,
1478 struct trustAuthInOutBlob *in)
1480 const char *attrs[] = { "userAccountControl", NULL };
1481 struct ldb_message **msgs;
1482 struct ldb_message *msg;
1487 ret = gendb_search(sam_ldb, mem_ctx,
1488 base_dn, &msgs, attrs,
1489 "samAccountName=%s$", netbios_name);
1491 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1496 return NT_STATUS_OK;
1499 /* ok no existing user, add it from scratch */
1500 return add_trust_user(mem_ctx, sam_ldb, base_dn,
1501 netbios_name, in, NULL);
1504 /* check user is what we are looking for */
1505 uac = ldb_msg_find_attr_as_uint(msgs[0],
1506 "userAccountControl", 0);
1507 if (!(uac & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
1508 return NT_STATUS_OBJECT_NAME_COLLISION;
1512 ret = ldb_delete(sam_ldb, msgs[0]->dn);
1515 return NT_STATUS_OK;
1516 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1517 return NT_STATUS_ACCESS_DENIED;
1519 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1523 /* entry exists, just modify secret if any */
1524 if (in->count == 0) {
1525 return NT_STATUS_OK;
1528 msg = ldb_msg_new(mem_ctx);
1530 return NT_STATUS_NO_MEMORY;
1532 msg->dn = msgs[0]->dn;
1534 for (i = 0; i < in->count; i++) {
1535 const char *attribute;
1537 switch (in->current.array[i].AuthType) {
1538 case TRUST_AUTH_TYPE_NT4OWF:
1539 attribute = "unicodePwd";
1540 v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
1543 case TRUST_AUTH_TYPE_CLEAR:
1544 attribute = "clearTextPassword";
1545 v.data = in->current.array[i].AuthInfo.clear.password;
1546 v.length = in->current.array[i].AuthInfo.clear.size;
1552 ret = ldb_msg_add_empty(msg, attribute,
1553 LDB_FLAG_MOD_REPLACE, NULL);
1554 if (ret != LDB_SUCCESS) {
1555 return NT_STATUS_NO_MEMORY;
1558 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
1559 if (ret != LDB_SUCCESS) {
1560 return NT_STATUS_NO_MEMORY;
1564 /* create the trusted_domain user account */
1565 ret = ldb_modify(sam_ldb, msg);
1566 if (ret != LDB_SUCCESS) {
1567 DEBUG(0,("Failed to create user record %s: %s\n",
1568 ldb_dn_get_linearized(msg->dn),
1569 ldb_errstring(sam_ldb)));
1572 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1573 return NT_STATUS_DOMAIN_EXISTS;
1574 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1575 return NT_STATUS_ACCESS_DENIED;
1577 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1581 return NT_STATUS_OK;
1585 static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call,
1586 struct dcesrv_handle *p_handle,
1587 TALLOC_CTX *mem_ctx,
1588 struct ldb_message *dom_msg,
1589 enum lsa_TrustDomInfoEnum level,
1590 union lsa_TrustedDomainInfo *info)
1592 struct lsa_policy_state *p_state = p_handle->data;
1593 uint32_t *posix_offset = NULL;
1594 struct lsa_TrustDomainInfoInfoEx *info_ex = NULL;
1595 struct lsa_TrustDomainInfoAuthInfo *auth_info = NULL;
1596 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
1597 uint32_t *enc_types = NULL;
1598 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
1599 struct trustDomainPasswords auth_struct;
1601 struct ldb_message **msgs;
1602 struct ldb_message *msg;
1603 bool add_outgoing = false;
1604 bool add_incoming = false;
1605 bool del_outgoing = false;
1606 bool del_incoming = false;
1607 bool in_transaction = false;
1612 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1613 posix_offset = &info->posix_offset.posix_offset;
1615 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1616 info_ex = &info->info_ex;
1618 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1619 auth_info = &info->auth_info;
1621 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1622 posix_offset = &info->full_info.posix_offset.posix_offset;
1623 info_ex = &info->full_info.info_ex;
1624 auth_info = &info->full_info.auth_info;
1626 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1627 auth_info_int = &info->auth_info_internal;
1629 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1630 posix_offset = &info->full_info_internal.posix_offset.posix_offset;
1631 info_ex = &info->full_info_internal.info_ex;
1632 auth_info_int = &info->full_info_internal.auth_info;
1634 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1635 enc_types = &info->enc_types.enc_types;
1638 return NT_STATUS_INVALID_PARAMETER;
1642 /* FIXME: not handled yet */
1643 return NT_STATUS_INVALID_PARAMETER;
1646 /* decode auth_info_int if set */
1647 if (auth_info_int) {
1649 /* now decrypt blob */
1650 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
1651 auth_info_int->auth_blob.size);
1653 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
1654 &auth_blob, &auth_struct);
1655 if (!NT_STATUS_IS_OK(nt_status)) {
1661 /* verify data matches */
1662 if (info_ex->trust_attributes &
1663 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1664 /* TODO: check what behavior level we have */
1665 if (strcasecmp_m(p_state->domain_dns,
1666 p_state->forest_dns) != 0) {
1667 return NT_STATUS_INVALID_DOMAIN_STATE;
1671 ret = samdb_rodc(p_state->sam_ldb, &am_rodc);
1672 if (ret == LDB_SUCCESS && am_rodc) {
1673 return NT_STATUS_NO_SUCH_DOMAIN;
1676 /* verify only one object matches the dns/netbios/sid
1677 * triplet and that this is the one we already have */
1678 nt_status = get_tdo(p_state->sam_ldb, mem_ctx,
1680 info_ex->domain_name.string,
1681 info_ex->netbios_name.string,
1682 info_ex->sid, &msgs);
1683 if (!NT_STATUS_IS_OK(nt_status)) {
1686 if (ldb_dn_compare(dom_msg->dn, msgs[0]->dn) != 0) {
1687 return NT_STATUS_OBJECT_NAME_COLLISION;
1692 /* TODO: should we fetch previous values from the existing entry
1693 * and append them ? */
1694 if (auth_struct.incoming.count) {
1695 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1696 &auth_struct.incoming,
1697 &trustAuthIncoming);
1698 if (!NT_STATUS_IS_OK(nt_status)) {
1702 trustAuthIncoming = data_blob(NULL, 0);
1705 if (auth_struct.outgoing.count) {
1706 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1707 &auth_struct.outgoing,
1708 &trustAuthOutgoing);
1709 if (!NT_STATUS_IS_OK(nt_status)) {
1713 trustAuthOutgoing = data_blob(NULL, 0);
1716 msg = ldb_msg_new(mem_ctx);
1718 return NT_STATUS_NO_MEMORY;
1720 msg->dn = dom_msg->dn;
1723 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1725 *posix_offset, NULL);
1726 if (!NT_STATUS_IS_OK(nt_status)) {
1737 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1739 info_ex->trust_direction,
1741 if (!NT_STATUS_IS_OK(nt_status)) {
1745 tmp = info_ex->trust_direction ^ origdir;
1746 if (tmp & LSA_TRUST_DIRECTION_INBOUND) {
1747 if (origdir & LSA_TRUST_DIRECTION_INBOUND) {
1748 del_incoming = true;
1750 add_incoming = true;
1753 if (tmp & LSA_TRUST_DIRECTION_OUTBOUND) {
1754 if (origdir & LSA_TRUST_DIRECTION_OUTBOUND) {
1755 del_outgoing = true;
1757 add_outgoing = true;
1761 origtype = ldb_msg_find_attr_as_int(dom_msg, "trustType", -1);
1762 if (origtype == -1 || origtype != info_ex->trust_type) {
1763 DEBUG(1, ("Attempted to change trust type! "
1764 "Operation not handled\n"));
1765 return NT_STATUS_INVALID_PARAMETER;
1768 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1770 info_ex->trust_attributes,
1772 if (!NT_STATUS_IS_OK(nt_status)) {
1775 /* TODO: check forestFunctionality from ldb opaque */
1776 /* TODO: check what is set makes sense */
1777 /* for now refuse changes */
1778 if (origattrs == -1 ||
1779 origattrs != info_ex->trust_attributes) {
1780 DEBUG(1, ("Attempted to change trust attributes! "
1781 "Operation not handled\n"));
1782 return NT_STATUS_INVALID_PARAMETER;
1787 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1788 "msDS-SupportedEncryptionTypes",
1790 if (!NT_STATUS_IS_OK(nt_status)) {
1795 if (add_incoming && trustAuthIncoming.data) {
1796 ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
1797 LDB_FLAG_MOD_REPLACE, NULL);
1798 if (ret != LDB_SUCCESS) {
1799 return NT_STATUS_NO_MEMORY;
1801 ret = ldb_msg_add_value(msg, "trustAuthIncoming",
1802 &trustAuthIncoming, NULL);
1803 if (ret != LDB_SUCCESS) {
1804 return NT_STATUS_NO_MEMORY;
1807 if (add_outgoing && trustAuthOutgoing.data) {
1808 ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
1809 LDB_FLAG_MOD_REPLACE, NULL);
1810 if (ret != LDB_SUCCESS) {
1811 return NT_STATUS_NO_MEMORY;
1813 ret = ldb_msg_add_value(msg, "trustAuthOutgoing",
1814 &trustAuthOutgoing, NULL);
1815 if (ret != LDB_SUCCESS) {
1816 return NT_STATUS_NO_MEMORY;
1820 /* start transaction */
1821 ret = ldb_transaction_start(p_state->sam_ldb);
1822 if (ret != LDB_SUCCESS) {
1823 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1825 in_transaction = true;
1827 ret = ldb_modify(p_state->sam_ldb, msg);
1828 if (ret != LDB_SUCCESS) {
1829 DEBUG(1,("Failed to modify trusted domain record %s: %s\n",
1830 ldb_dn_get_linearized(msg->dn),
1831 ldb_errstring(p_state->sam_ldb)));
1832 if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
1833 nt_status = NT_STATUS_ACCESS_DENIED;
1835 nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1840 if (add_incoming || del_incoming) {
1841 const char *netbios_name;
1843 netbios_name = ldb_msg_find_attr_as_string(dom_msg,
1845 if (!netbios_name) {
1846 nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
1850 nt_status = update_trust_user(mem_ctx,
1855 &auth_struct.incoming);
1856 if (!NT_STATUS_IS_OK(nt_status)) {
1861 /* ok, all fine, commit transaction and return */
1862 ret = ldb_transaction_commit(p_state->sam_ldb);
1863 if (ret != LDB_SUCCESS) {
1864 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1866 in_transaction = false;
1868 nt_status = NT_STATUS_OK;
1871 if (in_transaction) {
1872 ldb_transaction_cancel(p_state->sam_ldb);
1878 lsa_SetInfomrationTrustedDomain
1880 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(
1881 struct dcesrv_call_state *dce_call,
1882 TALLOC_CTX *mem_ctx,
1883 struct lsa_SetInformationTrustedDomain *r)
1885 struct dcesrv_handle *h;
1886 struct lsa_trusted_domain_state *td_state;
1887 struct ldb_message **msgs;
1890 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle,
1891 LSA_HANDLE_TRUSTED_DOMAIN);
1893 td_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1895 /* get the trusted domain object */
1896 nt_status = get_tdo(td_state->policy->sam_ldb, mem_ctx,
1897 td_state->trusted_domain_dn,
1898 NULL, NULL, NULL, &msgs);
1899 if (!NT_STATUS_IS_OK(nt_status)) {
1900 if (NT_STATUS_EQUAL(nt_status,
1901 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1904 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1907 return setInfoTrustedDomain_base(dce_call, h, mem_ctx,
1908 msgs[0], r->in.level, r->in.info);
1913 lsa_DeleteTrustedDomain
1915 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1916 struct lsa_DeleteTrustedDomain *r)
1919 struct lsa_OpenTrustedDomain opn;
1920 struct lsa_DeleteObject del;
1921 struct dcesrv_handle *h;
1923 opn.in.handle = r->in.handle;
1924 opn.in.sid = r->in.dom_sid;
1925 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1926 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1927 if (!opn.out.trustdom_handle) {
1928 return NT_STATUS_NO_MEMORY;
1930 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1931 if (!NT_STATUS_IS_OK(status)) {
1935 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1936 talloc_steal(mem_ctx, h);
1938 del.in.handle = opn.out.trustdom_handle;
1939 del.out.handle = opn.out.trustdom_handle;
1940 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
1941 if (!NT_STATUS_IS_OK(status)) {
1944 return NT_STATUS_OK;
1947 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1948 struct ldb_message *msg,
1949 struct lsa_TrustDomainInfoInfoEx *info_ex)
1951 info_ex->domain_name.string
1952 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1953 info_ex->netbios_name.string
1954 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1956 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1957 info_ex->trust_direction
1958 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1960 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1961 info_ex->trust_attributes
1962 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1963 return NT_STATUS_OK;
1967 lsa_QueryTrustedDomainInfo
1969 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1970 struct lsa_QueryTrustedDomainInfo *r)
1972 union lsa_TrustedDomainInfo *info = NULL;
1973 struct dcesrv_handle *h;
1974 struct lsa_trusted_domain_state *trusted_domain_state;
1975 struct ldb_message *msg;
1977 struct ldb_message **res;
1978 const char *attrs[] = {
1981 "securityIdentifier",
1985 "msDs-supportedEncryptionTypes",
1989 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1991 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1993 /* pull all the user attributes */
1994 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1995 trusted_domain_state->trusted_domain_dn, &res, attrs);
1997 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2001 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
2003 return NT_STATUS_NO_MEMORY;
2005 *r->out.info = info;
2007 switch (r->in.level) {
2008 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2009 info->name.netbios_name.string
2010 = samdb_result_string(msg, "flatname", NULL);
2012 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2013 info->posix_offset.posix_offset
2014 = samdb_result_uint(msg, "posixOffset", 0);
2016 #if 0 /* Win2k3 doesn't implement this */
2017 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2018 r->out.info->info_basic.netbios_name.string
2019 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2020 r->out.info->info_basic.sid
2021 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
2024 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2025 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
2027 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2028 ZERO_STRUCT(info->full_info);
2029 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
2031 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2032 ZERO_STRUCT(info->full_info2_internal);
2033 info->full_info2_internal.posix_offset.posix_offset
2034 = samdb_result_uint(msg, "posixOffset", 0);
2035 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
2037 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2038 info->enc_types.enc_types
2039 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
2042 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2043 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2044 /* oops, we don't want to return the info after all */
2046 *r->out.info = NULL;
2047 return NT_STATUS_INVALID_PARAMETER;
2049 /* oops, we don't want to return the info after all */
2051 *r->out.info = NULL;
2052 return NT_STATUS_INVALID_INFO_CLASS;
2055 return NT_STATUS_OK;
2060 lsa_QueryTrustedDomainInfoBySid
2062 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2063 struct lsa_QueryTrustedDomainInfoBySid *r)
2066 struct lsa_OpenTrustedDomain opn;
2067 struct lsa_QueryTrustedDomainInfo query;
2068 struct dcesrv_handle *h;
2070 opn.in.handle = r->in.handle;
2071 opn.in.sid = r->in.dom_sid;
2072 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2073 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2074 if (!opn.out.trustdom_handle) {
2075 return NT_STATUS_NO_MEMORY;
2077 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
2078 if (!NT_STATUS_IS_OK(status)) {
2082 /* Ensure this handle goes away at the end of this call */
2083 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2084 talloc_steal(mem_ctx, h);
2086 query.in.trustdom_handle = opn.out.trustdom_handle;
2087 query.in.level = r->in.level;
2088 query.out.info = r->out.info;
2089 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2090 if (!NT_STATUS_IS_OK(status)) {
2094 return NT_STATUS_OK;
2098 lsa_SetTrustedDomainInfoByName
2100 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2101 TALLOC_CTX *mem_ctx,
2102 struct lsa_SetTrustedDomainInfoByName *r)
2104 struct dcesrv_handle *policy_handle;
2105 struct lsa_policy_state *policy_state;
2106 struct ldb_message **msgs;
2109 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2110 policy_state = policy_handle->data;
2112 /* get the trusted domain object */
2113 nt_status = get_tdo(policy_state->sam_ldb, mem_ctx,
2114 policy_state->domain_dn,
2115 r->in.trusted_domain->string,
2116 r->in.trusted_domain->string,
2118 if (!NT_STATUS_IS_OK(nt_status)) {
2119 if (NT_STATUS_EQUAL(nt_status,
2120 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2123 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2126 return setInfoTrustedDomain_base(dce_call, policy_handle, mem_ctx,
2127 msgs[0], r->in.level, r->in.info);
2131 lsa_QueryTrustedDomainInfoByName
2133 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2134 TALLOC_CTX *mem_ctx,
2135 struct lsa_QueryTrustedDomainInfoByName *r)
2138 struct lsa_OpenTrustedDomainByName opn;
2139 struct lsa_QueryTrustedDomainInfo query;
2140 struct dcesrv_handle *h;
2142 opn.in.handle = r->in.handle;
2143 opn.in.name = *r->in.trusted_domain;
2144 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2145 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2146 if (!opn.out.trustdom_handle) {
2147 return NT_STATUS_NO_MEMORY;
2149 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
2150 if (!NT_STATUS_IS_OK(status)) {
2154 /* Ensure this handle goes away at the end of this call */
2155 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2156 talloc_steal(mem_ctx, h);
2158 query.in.trustdom_handle = opn.out.trustdom_handle;
2159 query.in.level = r->in.level;
2160 query.out.info = r->out.info;
2161 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2162 if (!NT_STATUS_IS_OK(status)) {
2166 return NT_STATUS_OK;
2170 lsa_CloseTrustedDomainEx
2172 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
2173 TALLOC_CTX *mem_ctx,
2174 struct lsa_CloseTrustedDomainEx *r)
2176 /* The result of a bad hair day from an IDL programmer? Not
2177 * implmented in Win2k3. You should always just lsa_Close
2179 return NT_STATUS_NOT_IMPLEMENTED;
2184 comparison function for sorting lsa_DomainInformation array
2186 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
2188 return strcasecmp_m(e1->name.string, e2->name.string);
2194 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2195 struct lsa_EnumTrustDom *r)
2197 struct dcesrv_handle *policy_handle;
2198 struct lsa_DomainInfo *entries;
2199 struct lsa_policy_state *policy_state;
2200 struct ldb_message **domains;
2201 const char *attrs[] = {
2203 "securityIdentifier",
2210 *r->out.resume_handle = 0;
2212 r->out.domains->domains = NULL;
2213 r->out.domains->count = 0;
2215 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2217 policy_state = policy_handle->data;
2219 /* search for all users in this domain. This could possibly be cached and
2220 resumed based on resume_key */
2221 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2222 "objectclass=trustedDomain");
2224 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2227 /* convert to lsa_TrustInformation format */
2228 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
2230 return NT_STATUS_NO_MEMORY;
2232 for (i=0;i<count;i++) {
2233 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
2234 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
2237 /* sort the results by name */
2238 TYPESAFE_QSORT(entries, count, compare_DomainInfo);
2240 if (*r->in.resume_handle >= count) {
2241 *r->out.resume_handle = -1;
2243 return NT_STATUS_NO_MORE_ENTRIES;
2246 /* return the rest, limit by max_size. Note that we
2247 use the w2k3 element size value of 60 */
2248 r->out.domains->count = count - *r->in.resume_handle;
2249 r->out.domains->count = MIN(r->out.domains->count,
2250 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
2252 r->out.domains->domains = entries + *r->in.resume_handle;
2253 r->out.domains->count = r->out.domains->count;
2255 if (r->out.domains->count < count - *r->in.resume_handle) {
2256 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2257 return STATUS_MORE_ENTRIES;
2260 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2261 * always be larger than the previous input resume handle, in
2262 * particular when hitting the last query it is vital to set the
2263 * resume handle correctly to avoid infinite client loops, as
2264 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2265 * status is NT_STATUS_OK - gd */
2267 *r->out.resume_handle = (uint32_t)-1;
2269 return NT_STATUS_OK;
2273 comparison function for sorting lsa_DomainInformation array
2275 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
2277 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
2281 lsa_EnumTrustedDomainsEx
2283 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2284 struct lsa_EnumTrustedDomainsEx *r)
2286 struct dcesrv_handle *policy_handle;
2287 struct lsa_TrustDomainInfoInfoEx *entries;
2288 struct lsa_policy_state *policy_state;
2289 struct ldb_message **domains;
2290 const char *attrs[] = {
2293 "securityIdentifier",
2303 *r->out.resume_handle = 0;
2305 r->out.domains->domains = NULL;
2306 r->out.domains->count = 0;
2308 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2310 policy_state = policy_handle->data;
2312 /* search for all users in this domain. This could possibly be cached and
2313 resumed based on resume_key */
2314 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2315 "objectclass=trustedDomain");
2317 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2320 /* convert to lsa_DomainInformation format */
2321 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
2323 return NT_STATUS_NO_MEMORY;
2325 for (i=0;i<count;i++) {
2326 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
2327 if (!NT_STATUS_IS_OK(nt_status)) {
2332 /* sort the results by name */
2333 TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
2335 if (*r->in.resume_handle >= count) {
2336 *r->out.resume_handle = -1;
2338 return NT_STATUS_NO_MORE_ENTRIES;
2341 /* return the rest, limit by max_size. Note that we
2342 use the w2k3 element size value of 60 */
2343 r->out.domains->count = count - *r->in.resume_handle;
2344 r->out.domains->count = MIN(r->out.domains->count,
2345 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
2347 r->out.domains->domains = entries + *r->in.resume_handle;
2348 r->out.domains->count = r->out.domains->count;
2350 if (r->out.domains->count < count - *r->in.resume_handle) {
2351 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2352 return STATUS_MORE_ENTRIES;
2355 return NT_STATUS_OK;
2362 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2363 struct lsa_OpenAccount *r)
2365 struct dcesrv_handle *h, *ah;
2366 struct lsa_policy_state *state;
2367 struct lsa_account_state *astate;
2369 ZERO_STRUCTP(r->out.acct_handle);
2371 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2375 astate = talloc(dce_call->conn, struct lsa_account_state);
2376 if (astate == NULL) {
2377 return NT_STATUS_NO_MEMORY;
2380 astate->account_sid = dom_sid_dup(astate, r->in.sid);
2381 if (astate->account_sid == NULL) {
2382 talloc_free(astate);
2383 return NT_STATUS_NO_MEMORY;
2386 astate->policy = talloc_reference(astate, state);
2387 astate->access_mask = r->in.access_mask;
2389 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
2391 talloc_free(astate);
2392 return NT_STATUS_NO_MEMORY;
2395 ah->data = talloc_steal(ah, astate);
2397 *r->out.acct_handle = ah->wire_handle;
2399 return NT_STATUS_OK;
2404 lsa_EnumPrivsAccount
2406 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
2407 TALLOC_CTX *mem_ctx,
2408 struct lsa_EnumPrivsAccount *r)
2410 struct dcesrv_handle *h;
2411 struct lsa_account_state *astate;
2414 struct ldb_message **res;
2415 const char * const attrs[] = { "privilege", NULL};
2416 struct ldb_message_element *el;
2418 struct lsa_PrivilegeSet *privs;
2420 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2424 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2425 if (privs == NULL) {
2426 return NT_STATUS_NO_MEMORY;
2432 *r->out.privs = privs;
2434 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
2435 if (sidstr == NULL) {
2436 return NT_STATUS_NO_MEMORY;
2439 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
2440 "objectSid=%s", sidstr);
2442 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2445 return NT_STATUS_OK;
2448 el = ldb_msg_find_element(res[0], "privilege");
2449 if (el == NULL || el->num_values == 0) {
2450 return NT_STATUS_OK;
2453 privs->set = talloc_array(privs,
2454 struct lsa_LUIDAttribute, el->num_values);
2455 if (privs->set == NULL) {
2456 return NT_STATUS_NO_MEMORY;
2459 for (i=0;i<el->num_values;i++) {
2460 int id = sec_privilege_id((const char *)el->values[i].data);
2462 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2464 privs->set[i].attribute = 0;
2465 privs->set[i].luid.low = id;
2466 privs->set[i].luid.high = 0;
2469 privs->count = el->num_values;
2471 return NT_STATUS_OK;
2475 lsa_EnumAccountRights
2477 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
2478 TALLOC_CTX *mem_ctx,
2479 struct lsa_EnumAccountRights *r)
2481 struct dcesrv_handle *h;
2482 struct lsa_policy_state *state;
2485 struct ldb_message **res;
2486 const char * const attrs[] = { "privilege", NULL};
2488 struct ldb_message_element *el;
2490 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2494 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
2495 if (sidstr == NULL) {
2496 return NT_STATUS_NO_MEMORY;
2499 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2500 "(&(objectSid=%s)(privilege=*))", sidstr);
2502 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2505 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
2506 dom_sid_string(mem_ctx, r->in.sid),
2507 ldb_errstring(state->pdb)));
2508 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2511 el = ldb_msg_find_element(res[0], "privilege");
2512 if (el == NULL || el->num_values == 0) {
2513 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2516 r->out.rights->count = el->num_values;
2517 r->out.rights->names = talloc_array(r->out.rights,
2518 struct lsa_StringLarge, r->out.rights->count);
2519 if (r->out.rights->names == NULL) {
2520 return NT_STATUS_NO_MEMORY;
2523 for (i=0;i<el->num_values;i++) {
2524 r->out.rights->names[i].string = (const char *)el->values[i].data;
2527 return NT_STATUS_OK;
2533 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
2535 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
2536 TALLOC_CTX *mem_ctx,
2537 struct lsa_policy_state *state,
2539 struct dom_sid *sid,
2540 const struct lsa_RightSet *rights)
2542 const char *sidstr, *sidndrstr;
2543 struct ldb_message *msg;
2544 struct ldb_message_element *el;
2547 struct lsa_EnumAccountRights r2;
2550 if (security_session_user_level(dce_call->conn->auth_state.session_info, NULL) <
2551 SECURITY_ADMINISTRATOR) {
2552 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
2553 return NT_STATUS_ACCESS_DENIED;
2556 msg = ldb_msg_new(mem_ctx);
2558 return NT_STATUS_NO_MEMORY;
2561 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
2562 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg);
2564 sidstr = dom_sid_string(msg, sid);
2565 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg);
2567 dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
2568 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg);
2570 msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
2571 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg);
2573 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
2576 r2.in.handle = &state->handle->wire_handle;
2578 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
2580 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2581 if (!NT_STATUS_IS_OK(status)) {
2582 ZERO_STRUCTP(r2.out.rights);
2586 for (i=0;i<rights->count;i++) {
2587 if (sec_privilege_id(rights->names[i].string) == -1) {
2589 return NT_STATUS_NO_SUCH_PRIVILEGE;
2592 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
2594 for (j=0;j<r2.out.rights->count;j++) {
2595 if (strcasecmp_m(r2.out.rights->names[j].string,
2596 rights->names[i].string) == 0) {
2600 if (j != r2.out.rights->count) continue;
2603 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2604 if (ret != LDB_SUCCESS) {
2606 return NT_STATUS_NO_MEMORY;
2610 el = ldb_msg_find_element(msg, "privilege");
2613 return NT_STATUS_OK;
2616 el->flags = ldb_flag;
2618 ret = ldb_modify(state->pdb, msg);
2619 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
2620 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
2622 return NT_STATUS_NO_MEMORY;
2624 samdb_msg_add_string(state->pdb, msg, msg, "comment", "added via LSA");
2625 ret = ldb_add(state->pdb, msg);
2627 if (ret != LDB_SUCCESS) {
2628 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2630 return NT_STATUS_OK;
2632 DEBUG(3, ("Could not %s attributes from %s: %s",
2633 LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2634 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
2636 return NT_STATUS_UNEXPECTED_IO_ERROR;
2640 return NT_STATUS_OK;
2644 lsa_AddPrivilegesToAccount
2646 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2647 struct lsa_AddPrivilegesToAccount *r)
2649 struct lsa_RightSet rights;
2650 struct dcesrv_handle *h;
2651 struct lsa_account_state *astate;
2654 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2658 rights.count = r->in.privs->count;
2659 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2660 if (rights.names == NULL) {
2661 return NT_STATUS_NO_MEMORY;
2663 for (i=0;i<rights.count;i++) {
2664 int id = r->in.privs->set[i].luid.low;
2665 if (r->in.privs->set[i].luid.high) {
2666 return NT_STATUS_NO_SUCH_PRIVILEGE;
2668 rights.names[i].string = sec_privilege_name(id);
2669 if (rights.names[i].string == NULL) {
2670 return NT_STATUS_NO_SUCH_PRIVILEGE;
2674 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2675 LDB_FLAG_MOD_ADD, astate->account_sid,
2681 lsa_RemovePrivilegesFromAccount
2683 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2684 struct lsa_RemovePrivilegesFromAccount *r)
2686 struct lsa_RightSet *rights;
2687 struct dcesrv_handle *h;
2688 struct lsa_account_state *astate;
2691 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2695 rights = talloc(mem_ctx, struct lsa_RightSet);
2697 if (r->in.remove_all == 1 &&
2698 r->in.privs == NULL) {
2699 struct lsa_EnumAccountRights r2;
2702 r2.in.handle = &astate->policy->handle->wire_handle;
2703 r2.in.sid = astate->account_sid;
2704 r2.out.rights = rights;
2706 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2707 if (!NT_STATUS_IS_OK(status)) {
2711 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2712 LDB_FLAG_MOD_DELETE, astate->account_sid,
2716 if (r->in.remove_all != 0) {
2717 return NT_STATUS_INVALID_PARAMETER;
2720 rights->count = r->in.privs->count;
2721 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2722 if (rights->names == NULL) {
2723 return NT_STATUS_NO_MEMORY;
2725 for (i=0;i<rights->count;i++) {
2726 int id = r->in.privs->set[i].luid.low;
2727 if (r->in.privs->set[i].luid.high) {
2728 return NT_STATUS_NO_SUCH_PRIVILEGE;
2730 rights->names[i].string = sec_privilege_name(id);
2731 if (rights->names[i].string == NULL) {
2732 return NT_STATUS_NO_SUCH_PRIVILEGE;
2736 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2737 LDB_FLAG_MOD_DELETE, astate->account_sid,
2743 lsa_GetQuotasForAccount
2745 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2746 struct lsa_GetQuotasForAccount *r)
2748 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2753 lsa_SetQuotasForAccount
2755 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2756 struct lsa_SetQuotasForAccount *r)
2758 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2763 lsa_GetSystemAccessAccount
2765 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2766 struct lsa_GetSystemAccessAccount *r)
2770 struct lsa_EnumPrivsAccount enumPrivs;
2771 struct lsa_PrivilegeSet *privs;
2773 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2775 return NT_STATUS_NO_MEMORY;
2781 enumPrivs.in.handle = r->in.handle;
2782 enumPrivs.out.privs = &privs;
2784 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2785 if (!NT_STATUS_IS_OK(status)) {
2789 *(r->out.access_mask) = 0x00000000;
2791 for (i = 0; i < privs->count; i++) {
2792 int priv = privs->set[i].luid.low;
2795 case SEC_PRIV_INTERACTIVE_LOGON:
2796 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2798 case SEC_PRIV_NETWORK_LOGON:
2799 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2801 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2802 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2807 return NT_STATUS_OK;
2812 lsa_SetSystemAccessAccount
2814 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2815 struct lsa_SetSystemAccessAccount *r)
2817 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2824 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2825 struct lsa_CreateSecret *r)
2827 struct dcesrv_handle *policy_handle;
2828 struct lsa_policy_state *policy_state;
2829 struct lsa_secret_state *secret_state;
2830 struct dcesrv_handle *handle;
2831 struct ldb_message **msgs, *msg;
2832 const char *attrs[] = {
2840 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2841 ZERO_STRUCTP(r->out.sec_handle);
2843 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
2845 case SECURITY_SYSTEM:
2846 case SECURITY_ADMINISTRATOR:
2849 /* Users and annonymous are not allowed create secrets */
2850 return NT_STATUS_ACCESS_DENIED;
2853 policy_state = policy_handle->data;
2855 if (!r->in.name.string) {
2856 return NT_STATUS_INVALID_PARAMETER;
2859 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2860 if (!secret_state) {
2861 return NT_STATUS_NO_MEMORY;
2863 secret_state->policy = policy_state;
2865 msg = ldb_msg_new(mem_ctx);
2867 return NT_STATUS_NO_MEMORY;
2870 if (strncmp("G$", r->in.name.string, 2) == 0) {
2872 name = &r->in.name.string[2];
2873 /* We need to connect to the database as system, as this is one of the rare RPC calls that must read the secrets (and this is denied otherwise) */
2874 secret_state->sam_ldb = talloc_reference(secret_state,
2875 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
2876 secret_state->global = true;
2878 if (strlen(name) < 1) {
2879 return NT_STATUS_INVALID_PARAMETER;
2882 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2883 /* search for the secret record */
2884 ret = gendb_search(secret_state->sam_ldb,
2885 mem_ctx, policy_state->system_dn, &msgs, attrs,
2886 "(&(cn=%s)(objectclass=secret))",
2889 return NT_STATUS_OBJECT_NAME_COLLISION;
2893 DEBUG(0,("Failure searching for CN=%s: %s\n",
2894 name2, ldb_errstring(secret_state->sam_ldb)));
2895 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2898 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2899 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2900 return NT_STATUS_NO_MEMORY;
2903 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2906 secret_state->global = false;
2908 name = r->in.name.string;
2909 if (strlen(name) < 1) {
2910 return NT_STATUS_INVALID_PARAMETER;
2913 secret_state->sam_ldb = talloc_reference(secret_state,
2914 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2915 /* search for the secret record */
2916 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2917 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2919 "(&(cn=%s)(objectclass=secret))",
2920 ldb_binary_encode_string(mem_ctx, name));
2922 return NT_STATUS_OBJECT_NAME_COLLISION;
2926 DEBUG(0,("Failure searching for CN=%s: %s\n",
2927 name, ldb_errstring(secret_state->sam_ldb)));
2928 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2931 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2932 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2935 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2937 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2939 /* create the secret */
2940 ret = dsdb_add(secret_state->sam_ldb, msg, DSDB_MODIFY_RELAX);
2941 if (ret != LDB_SUCCESS) {
2942 DEBUG(0,("Failed to create secret record %s: %s\n",
2943 ldb_dn_get_linearized(msg->dn),
2944 ldb_errstring(secret_state->sam_ldb)));
2945 return NT_STATUS_ACCESS_DENIED;
2948 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2950 return NT_STATUS_NO_MEMORY;
2953 handle->data = talloc_steal(handle, secret_state);
2955 secret_state->access_mask = r->in.access_mask;
2956 secret_state->policy = talloc_reference(secret_state, policy_state);
2958 *r->out.sec_handle = handle->wire_handle;
2960 return NT_STATUS_OK;
2967 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2968 struct lsa_OpenSecret *r)
2970 struct dcesrv_handle *policy_handle;
2972 struct lsa_policy_state *policy_state;
2973 struct lsa_secret_state *secret_state;
2974 struct dcesrv_handle *handle;
2975 struct ldb_message **msgs;
2976 const char *attrs[] = {
2984 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2985 ZERO_STRUCTP(r->out.sec_handle);
2986 policy_state = policy_handle->data;
2988 if (!r->in.name.string) {
2989 return NT_STATUS_INVALID_PARAMETER;
2992 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
2994 case SECURITY_SYSTEM:
2995 case SECURITY_ADMINISTRATOR:
2998 /* Users and annonymous are not allowed to access secrets */
2999 return NT_STATUS_ACCESS_DENIED;
3002 secret_state = talloc(mem_ctx, struct lsa_secret_state);
3003 if (!secret_state) {
3004 return NT_STATUS_NO_MEMORY;
3006 secret_state->policy = policy_state;
3008 if (strncmp("G$", r->in.name.string, 2) == 0) {
3009 name = &r->in.name.string[2];
3010 /* We need to connect to the database as system, as this is one of the rare RPC calls that must read the secrets (and this is denied otherwise) */
3011 secret_state->sam_ldb = talloc_reference(secret_state,
3012 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
3013 secret_state->global = true;
3015 if (strlen(name) < 1) {
3016 return NT_STATUS_INVALID_PARAMETER;
3019 /* search for the secret record */
3020 ret = gendb_search(secret_state->sam_ldb,
3021 mem_ctx, policy_state->system_dn, &msgs, attrs,
3022 "(&(cn=%s Secret)(objectclass=secret))",
3023 ldb_binary_encode_string(mem_ctx, name));
3025 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3029 DEBUG(0,("Found %d records matching DN %s\n", ret,
3030 ldb_dn_get_linearized(policy_state->system_dn)));
3031 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3035 secret_state->global = false;
3036 secret_state->sam_ldb = talloc_reference(secret_state,
3037 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
3039 name = r->in.name.string;
3040 if (strlen(name) < 1) {
3041 return NT_STATUS_INVALID_PARAMETER;
3044 /* search for the secret record */
3045 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
3046 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
3048 "(&(cn=%s)(objectclass=secret))",
3049 ldb_binary_encode_string(mem_ctx, name));
3051 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3055 DEBUG(0,("Found %d records matching CN=%s\n",
3056 ret, ldb_binary_encode_string(mem_ctx, name)));
3057 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3061 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
3063 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
3065 return NT_STATUS_NO_MEMORY;
3068 handle->data = talloc_steal(handle, secret_state);
3070 secret_state->access_mask = r->in.access_mask;
3071 secret_state->policy = talloc_reference(secret_state, policy_state);
3073 *r->out.sec_handle = handle->wire_handle;
3075 return NT_STATUS_OK;
3082 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3083 struct lsa_SetSecret *r)
3086 struct dcesrv_handle *h;
3087 struct lsa_secret_state *secret_state;
3088 struct ldb_message *msg;
3089 DATA_BLOB session_key;
3090 DATA_BLOB crypt_secret, secret;
3093 NTSTATUS status = NT_STATUS_OK;
3095 struct timeval now = timeval_current();
3096 NTTIME nt_now = timeval_to_nttime(&now);
3098 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3100 secret_state = h->data;
3102 msg = ldb_msg_new(mem_ctx);
3104 return NT_STATUS_NO_MEMORY;
3107 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
3109 return NT_STATUS_NO_MEMORY;
3111 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
3112 if (!NT_STATUS_IS_OK(status)) {
3116 if (r->in.old_val) {
3118 crypt_secret.data = r->in.old_val->data;
3119 crypt_secret.length = r->in.old_val->size;
3121 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3122 if (!NT_STATUS_IS_OK(status)) {
3126 val.data = secret.data;
3127 val.length = secret.length;
3130 if (samdb_msg_add_value(secret_state->sam_ldb,
3131 mem_ctx, msg, "priorValue", &val) != LDB_SUCCESS) {
3132 return NT_STATUS_NO_MEMORY;
3135 /* set old value mtime */
3136 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3137 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3138 return NT_STATUS_NO_MEMORY;
3142 /* If the old value is not set, then migrate the
3143 * current value to the old value */
3144 const struct ldb_val *old_val;
3145 NTTIME last_set_time;
3146 struct ldb_message **res;
3147 const char *attrs[] = {
3153 /* search for the secret record */
3154 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
3155 secret_state->secret_dn, &res, attrs);
3157 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3161 DEBUG(0,("Found %d records matching dn=%s\n", ret,
3162 ldb_dn_get_linearized(secret_state->secret_dn)));
3163 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3166 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3167 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3171 if (samdb_msg_add_value(secret_state->sam_ldb,
3172 mem_ctx, msg, "priorValue",
3174 return NT_STATUS_NO_MEMORY;
3177 if (samdb_msg_add_delete(secret_state->sam_ldb,
3178 mem_ctx, msg, "priorValue")) {
3179 return NT_STATUS_NO_MEMORY;
3184 /* set old value mtime */
3185 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
3186 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3187 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
3188 return NT_STATUS_NO_MEMORY;
3191 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3192 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3193 return NT_STATUS_NO_MEMORY;
3198 if (r->in.new_val) {
3200 crypt_secret.data = r->in.new_val->data;
3201 crypt_secret.length = r->in.new_val->size;
3203 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3204 if (!NT_STATUS_IS_OK(status)) {
3208 val.data = secret.data;
3209 val.length = secret.length;
3212 if (samdb_msg_add_value(secret_state->sam_ldb,
3213 mem_ctx, msg, "currentValue", &val) != LDB_SUCCESS) {
3214 return NT_STATUS_NO_MEMORY;
3217 /* set new value mtime */
3218 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3219 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3220 return NT_STATUS_NO_MEMORY;
3224 /* NULL out the NEW value */
3225 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3226 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3227 return NT_STATUS_NO_MEMORY;
3229 if (samdb_msg_add_delete(secret_state->sam_ldb,
3230 mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
3231 return NT_STATUS_NO_MEMORY;
3235 /* modify the samdb record */
3236 ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
3237 if (ret != LDB_SUCCESS) {
3238 /* we really need samdb.c to return NTSTATUS */
3239 return NT_STATUS_UNSUCCESSFUL;
3242 return NT_STATUS_OK;
3249 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3250 struct lsa_QuerySecret *r)
3252 struct dcesrv_handle *h;
3253 struct lsa_secret_state *secret_state;
3254 struct ldb_message *msg;
3255 DATA_BLOB session_key;
3256 DATA_BLOB crypt_secret, secret;
3258 struct ldb_message **res;
3259 const char *attrs[] = {
3269 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3271 /* Ensure user is permitted to read this... */
3272 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
3274 case SECURITY_SYSTEM:
3275 case SECURITY_ADMINISTRATOR:
3278 /* Users and annonymous are not allowed to read secrets */
3279 return NT_STATUS_ACCESS_DENIED;
3282 secret_state = h->data;
3284 /* pull all the user attributes */
3285 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
3286 secret_state->secret_dn, &res, attrs);
3288 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3292 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
3293 if (!NT_STATUS_IS_OK(nt_status)) {
3297 if (r->in.old_val) {
3298 const struct ldb_val *prior_val;
3299 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3300 if (!r->out.old_val) {
3301 return NT_STATUS_NO_MEMORY;
3303 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
3305 if (prior_val && prior_val->length) {
3306 secret.data = prior_val->data;
3307 secret.length = prior_val->length;
3310 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3311 if (!crypt_secret.length) {
3312 return NT_STATUS_NO_MEMORY;
3314 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3315 if (!r->out.old_val->buf) {
3316 return NT_STATUS_NO_MEMORY;
3318 r->out.old_val->buf->size = crypt_secret.length;
3319 r->out.old_val->buf->length = crypt_secret.length;
3320 r->out.old_val->buf->data = crypt_secret.data;
3324 if (r->in.old_mtime) {
3325 r->out.old_mtime = talloc(mem_ctx, NTTIME);
3326 if (!r->out.old_mtime) {
3327 return NT_STATUS_NO_MEMORY;
3329 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
3332 if (r->in.new_val) {
3333 const struct ldb_val *new_val;
3334 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3335 if (!r->out.new_val) {
3336 return NT_STATUS_NO_MEMORY;
3339 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3341 if (new_val && new_val->length) {
3342 secret.data = new_val->data;
3343 secret.length = new_val->length;
3346 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3347 if (!crypt_secret.length) {
3348 return NT_STATUS_NO_MEMORY;
3350 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3351 if (!r->out.new_val->buf) {
3352 return NT_STATUS_NO_MEMORY;
3354 r->out.new_val->buf->length = crypt_secret.length;
3355 r->out.new_val->buf->size = crypt_secret.length;
3356 r->out.new_val->buf->data = crypt_secret.data;
3360 if (r->in.new_mtime) {
3361 r->out.new_mtime = talloc(mem_ctx, NTTIME);
3362 if (!r->out.new_mtime) {
3363 return NT_STATUS_NO_MEMORY;
3365 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3368 return NT_STATUS_OK;
3375 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
3376 TALLOC_CTX *mem_ctx,
3377 struct lsa_LookupPrivValue *r)
3379 struct dcesrv_handle *h;
3380 struct lsa_policy_state *state;
3383 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3387 id = sec_privilege_id(r->in.name->string);
3389 return NT_STATUS_NO_SUCH_PRIVILEGE;
3392 r->out.luid->low = id;
3393 r->out.luid->high = 0;
3395 return NT_STATUS_OK;
3402 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
3403 TALLOC_CTX *mem_ctx,
3404 struct lsa_LookupPrivName *r)
3406 struct dcesrv_handle *h;
3407 struct lsa_policy_state *state;
3408 struct lsa_StringLarge *name;
3409 const char *privname;
3411 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3415 if (r->in.luid->high != 0) {
3416 return NT_STATUS_NO_SUCH_PRIVILEGE;
3419 privname = sec_privilege_name(r->in.luid->low);
3420 if (privname == NULL) {
3421 return NT_STATUS_NO_SUCH_PRIVILEGE;
3424 name = talloc(mem_ctx, struct lsa_StringLarge);
3426 return NT_STATUS_NO_MEMORY;
3429 name->string = privname;
3431 *r->out.name = name;
3433 return NT_STATUS_OK;
3438 lsa_LookupPrivDisplayName
3440 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
3441 TALLOC_CTX *mem_ctx,
3442 struct lsa_LookupPrivDisplayName *r)
3444 struct dcesrv_handle *h;
3445 struct lsa_policy_state *state;
3446 struct lsa_StringLarge *disp_name = NULL;
3449 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3453 id = sec_privilege_id(r->in.name->string);
3455 return NT_STATUS_NO_SUCH_PRIVILEGE;
3458 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
3459 if (disp_name == NULL) {
3460 return NT_STATUS_NO_MEMORY;
3463 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
3464 if (disp_name->string == NULL) {
3465 return NT_STATUS_INTERNAL_ERROR;
3468 *r->out.disp_name = disp_name;
3469 *r->out.returned_language_id = 0;
3471 return NT_STATUS_OK;
3476 lsa_EnumAccountsWithUserRight
3478 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
3479 TALLOC_CTX *mem_ctx,
3480 struct lsa_EnumAccountsWithUserRight *r)
3482 struct dcesrv_handle *h;
3483 struct lsa_policy_state *state;
3485 struct ldb_message **res;
3486 const char * const attrs[] = { "objectSid", NULL};
3487 const char *privname;
3489 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3493 if (r->in.name == NULL) {
3494 return NT_STATUS_NO_SUCH_PRIVILEGE;
3497 privname = r->in.name->string;
3498 if (sec_privilege_id(privname) == -1) {
3499 return NT_STATUS_NO_SUCH_PRIVILEGE;
3502 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
3503 "privilege=%s", privname);
3505 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3508 return NT_STATUS_NO_MORE_ENTRIES;
3511 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
3512 if (r->out.sids->sids == NULL) {
3513 return NT_STATUS_NO_MEMORY;
3515 for (i=0;i<ret;i++) {
3516 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
3517 res[i], "objectSid");
3518 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
3520 r->out.sids->num_sids = ret;
3522 return NT_STATUS_OK;
3527 lsa_AddAccountRights
3529 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
3530 TALLOC_CTX *mem_ctx,
3531 struct lsa_AddAccountRights *r)
3533 struct dcesrv_handle *h;
3534 struct lsa_policy_state *state;
3536 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3540 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3542 r->in.sid, r->in.rights);
3547 lsa_RemoveAccountRights
3549 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
3550 TALLOC_CTX *mem_ctx,
3551 struct lsa_RemoveAccountRights *r)
3553 struct dcesrv_handle *h;
3554 struct lsa_policy_state *state;
3556 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3560 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3561 LDB_FLAG_MOD_DELETE,
3562 r->in.sid, r->in.rights);
3567 lsa_StorePrivateData
3569 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3570 struct lsa_StorePrivateData *r)
3572 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3577 lsa_RetrievePrivateData
3579 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3580 struct lsa_RetrievePrivateData *r)
3582 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3589 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3590 struct lsa_GetUserName *r)
3592 NTSTATUS status = NT_STATUS_OK;
3593 const char *account_name;
3594 const char *authority_name;
3595 struct lsa_String *_account_name;
3596 struct lsa_String *_authority_name = NULL;
3598 /* this is what w2k3 does */
3599 r->out.account_name = r->in.account_name;
3600 r->out.authority_name = r->in.authority_name;
3602 if (r->in.account_name
3603 && *r->in.account_name
3604 /* && *(*r->in.account_name)->string */
3606 return NT_STATUS_INVALID_PARAMETER;
3609 if (r->in.authority_name
3610 && *r->in.authority_name
3611 /* && *(*r->in.authority_name)->string */
3613 return NT_STATUS_INVALID_PARAMETER;
3616 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
3617 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
3619 _account_name = talloc(mem_ctx, struct lsa_String);
3620 NT_STATUS_HAVE_NO_MEMORY(_account_name);
3621 _account_name->string = account_name;
3623 if (r->in.authority_name) {
3624 _authority_name = talloc(mem_ctx, struct lsa_String);
3625 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
3626 _authority_name->string = authority_name;
3629 *r->out.account_name = _account_name;
3630 if (r->out.authority_name) {
3631 *r->out.authority_name = _authority_name;
3640 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
3641 TALLOC_CTX *mem_ctx,
3642 struct lsa_SetInfoPolicy2 *r)
3644 /* need to support these */
3645 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3649 lsa_QueryDomainInformationPolicy
3651 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3652 TALLOC_CTX *mem_ctx,
3653 struct lsa_QueryDomainInformationPolicy *r)
3655 union lsa_DomainInformationPolicy *info;
3657 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
3659 return NT_STATUS_NO_MEMORY;
3662 switch (r->in.level) {
3663 case LSA_DOMAIN_INFO_POLICY_EFS:
3665 *r->out.info = NULL;
3666 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3667 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
3669 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
3670 struct smb_krb5_context *smb_krb5_context;
3671 int ret = smb_krb5_init_context(mem_ctx,
3672 dce_call->event_ctx,
3673 dce_call->conn->dce_ctx->lp_ctx,
3677 *r->out.info = NULL;
3678 return NT_STATUS_INTERNAL_ERROR;
3680 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
3681 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3682 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3683 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
3684 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
3685 talloc_free(smb_krb5_context);
3686 *r->out.info = info;
3687 return NT_STATUS_OK;
3691 *r->out.info = NULL;
3692 return NT_STATUS_INVALID_INFO_CLASS;
3697 lsa_SetDomInfoPolicy
3699 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3700 TALLOC_CTX *mem_ctx,
3701 struct lsa_SetDomainInformationPolicy *r)
3703 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3709 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3710 TALLOC_CTX *mem_ctx,
3711 struct lsa_TestCall *r)
3713 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3719 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3720 struct lsa_CREDRWRITE *r)
3722 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3729 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3730 struct lsa_CREDRREAD *r)
3732 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3739 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3740 struct lsa_CREDRENUMERATE *r)
3742 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3747 lsa_CREDRWRITEDOMAINCREDENTIALS
3749 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3750 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3752 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3757 lsa_CREDRREADDOMAINCREDENTIALS
3759 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3760 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3762 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3769 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3770 struct lsa_CREDRDELETE *r)
3772 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3777 lsa_CREDRGETTARGETINFO
3779 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3780 struct lsa_CREDRGETTARGETINFO *r)
3782 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3787 lsa_CREDRPROFILELOADED
3789 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3790 struct lsa_CREDRPROFILELOADED *r)
3792 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3797 lsa_CREDRGETSESSIONTYPES
3799 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3800 struct lsa_CREDRGETSESSIONTYPES *r)
3802 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3807 lsa_LSARREGISTERAUDITEVENT
3809 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3810 struct lsa_LSARREGISTERAUDITEVENT *r)
3812 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3817 lsa_LSARGENAUDITEVENT
3819 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3820 struct lsa_LSARGENAUDITEVENT *r)
3822 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3827 lsa_LSARUNREGISTERAUDITEVENT
3829 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3830 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3832 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3837 lsa_lsaRQueryForestTrustInformation
3839 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3840 struct lsa_lsaRQueryForestTrustInformation *r)
3842 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3845 #define DNS_CMP_MATCH 0
3846 #define DNS_CMP_FIRST_IS_CHILD 1
3847 #define DNS_CMP_SECOND_IS_CHILD 2
3848 #define DNS_CMP_NO_MATCH 3
3850 /* this function assumes names are well formed DNS names.
3851 * it doesn't validate them */
3852 static int dns_cmp(const char *s1, size_t l1,
3853 const char *s2, size_t l2)
3855 const char *p1, *p2;
3860 if (strcasecmp_m(s1, s2) == 0) {
3861 return DNS_CMP_MATCH;
3863 return DNS_CMP_NO_MATCH;
3871 cret = DNS_CMP_FIRST_IS_CHILD;
3877 cret = DNS_CMP_SECOND_IS_CHILD;
3880 if (p1[t1 - t2 - 1] != '.') {
3881 return DNS_CMP_NO_MATCH;
3884 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
3888 return DNS_CMP_NO_MATCH;
3891 /* decode all TDOs forest trust info blobs */
3892 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3893 struct ldb_message *msg,
3894 struct ForestTrustInfo *info)
3896 const struct ldb_val *ft_blob;
3897 enum ndr_err_code ndr_err;
3899 ft_blob = ldb_msg_find_ldb_val(msg, "msDS-TrustForestTrustInfo");
3900 if (!ft_blob || !ft_blob->data) {
3901 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3903 /* ldb_val is equivalent to DATA_BLOB */
3904 ndr_err = ndr_pull_struct_blob_all(ft_blob, mem_ctx, info,
3905 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3906 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3907 return NT_STATUS_INVALID_DOMAIN_STATE;
3910 return NT_STATUS_OK;
3913 static NTSTATUS own_ft_info(struct lsa_policy_state *ps,
3914 struct ForestTrustInfo *fti)
3916 struct ForestTrustDataDomainInfo *info;
3917 struct ForestTrustInfoRecord *rec;
3921 fti->records = talloc_array(fti,
3922 struct ForestTrustInfoRecordArmor, 2);
3923 if (!fti->records) {
3924 return NT_STATUS_NO_MEMORY;
3928 rec = &fti->records[0].record;
3932 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3934 rec->data.name.string = talloc_strdup(fti, ps->forest_dns);
3935 if (!rec->data.name.string) {
3936 return NT_STATUS_NO_MEMORY;
3938 rec->data.name.size = strlen(rec->data.name.string);
3941 rec = &fti->records[1].record;
3945 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3947 info = &rec->data.info;
3949 info->sid = *ps->domain_sid;
3950 info->dns_name.string = talloc_strdup(fti, ps->domain_dns);
3951 if (!info->dns_name.string) {
3952 return NT_STATUS_NO_MEMORY;
3954 info->dns_name.size = strlen(info->dns_name.string);
3955 info->netbios_name.string = talloc_strdup(fti, ps->domain_name);
3956 if (!info->netbios_name.string) {
3957 return NT_STATUS_NO_MEMORY;
3959 info->netbios_name.size = strlen(info->netbios_name.string);
3961 return NT_STATUS_OK;
3964 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3965 struct lsa_ForestTrustInformation *lfti,
3966 struct ForestTrustInfo *fti)
3968 struct lsa_ForestTrustRecord *lrec;
3969 struct ForestTrustInfoRecord *rec;
3970 struct lsa_StringLarge *tln;
3971 struct lsa_ForestTrustDomainInfo *info;
3975 fti->count = lfti->count;
3976 fti->records = talloc_array(mem_ctx,
3977 struct ForestTrustInfoRecordArmor,
3979 if (!fti->records) {
3980 return NT_STATUS_NO_MEMORY;
3982 for (i = 0; i < fti->count; i++) {
3983 lrec = lfti->entries[i];
3984 rec = &fti->records[i].record;
3986 rec->flags = lrec->flags;
3987 rec->timestamp = lrec->time;
3988 rec->type = lrec->type;
3990 switch (lrec->type) {
3991 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3992 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3993 tln = &lrec->forest_trust_data.top_level_name;
3994 rec->data.name.string =
3995 talloc_strdup(mem_ctx, tln->string);
3996 if (!rec->data.name.string) {
3997 return NT_STATUS_NO_MEMORY;
3999 rec->data.name.size = strlen(rec->data.name.string);
4001 case LSA_FOREST_TRUST_DOMAIN_INFO:
4002 info = &lrec->forest_trust_data.domain_info;
4003 rec->data.info.sid = *info->domain_sid;
4004 rec->data.info.dns_name.string =
4005 talloc_strdup(mem_ctx,
4006 info->dns_domain_name.string);
4007 if (!rec->data.info.dns_name.string) {
4008 return NT_STATUS_NO_MEMORY;
4010 rec->data.info.dns_name.size =
4011 strlen(rec->data.info.dns_name.string);
4012 rec->data.info.netbios_name.string =
4013 talloc_strdup(mem_ctx,
4014 info->netbios_domain_name.string);
4015 if (!rec->data.info.netbios_name.string) {
4016 return NT_STATUS_NO_MEMORY;
4018 rec->data.info.netbios_name.size =
4019 strlen(rec->data.info.netbios_name.string);
4022 return NT_STATUS_INVALID_DOMAIN_STATE;
4026 return NT_STATUS_OK;
4029 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4030 uint32_t index, uint32_t collision_type,
4031 uint32_t conflict_type, const char *tdo_name);
4033 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4034 const char *tdo_name,
4035 struct ForestTrustInfo *tdo_fti,
4036 struct ForestTrustInfo *new_fti,
4037 struct lsa_ForestTrustCollisionInfo *c_info)
4039 struct ForestTrustInfoRecord *nrec;
4040 struct ForestTrustInfoRecord *trec;
4041 const char *dns_name;
4042 const char *nb_name;
4043 struct dom_sid *sid;
4049 uint32_t new_fti_idx;
4051 /* use always TDO type, until we understand when Xref can be used */
4052 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
4060 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
4062 nrec = &new_fti->records[new_fti_idx].record;
4064 tln_conflict = false;
4065 sid_conflict = false;
4066 nb_conflict = false;
4069 switch (nrec->type) {
4070 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4071 /* exclusions do not conflict by definition */
4074 case FOREST_TRUST_TOP_LEVEL_NAME:
4075 dns_name = nrec->data.name.string;
4076 dns_len = nrec->data.name.size;
4079 case LSA_FOREST_TRUST_DOMAIN_INFO:
4080 dns_name = nrec->data.info.dns_name.string;
4081 dns_len = nrec->data.info.dns_name.size;
4082 nb_name = nrec->data.info.netbios_name.string;
4083 nb_len = nrec->data.info.netbios_name.size;
4084 sid = &nrec->data.info.sid;
4088 if (!dns_name) continue;
4090 /* check if this is already taken and not excluded */
4091 for (i = 0; i < tdo_fti->count; i++) {
4092 trec = &tdo_fti->records[i].record;
4094 switch (trec->type) {
4095 case FOREST_TRUST_TOP_LEVEL_NAME:
4097 tname = trec->data.name.string;
4098 tlen = trec->data.name.size;
4100 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4102 tname = trec->data.name.string;
4103 tlen = trec->data.name.size;
4105 case FOREST_TRUST_DOMAIN_INFO:
4107 tname = trec->data.info.dns_name.string;
4108 tlen = trec->data.info.dns_name.size;
4110 ret = dns_cmp(dns_name, dns_len, tname, tlen);
4113 /* if it matches exclusion,
4114 * it doesn't conflict */
4120 case DNS_CMP_FIRST_IS_CHILD:
4121 case DNS_CMP_SECOND_IS_CHILD:
4122 tln_conflict = true;
4128 /* explicit exclusion, no dns name conflict here */
4130 tln_conflict = false;
4133 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
4137 /* also test for domain info */
4138 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
4139 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
4140 sid_conflict = true;
4142 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
4143 strcasecmp_m(trec->data.info.netbios_name.string,
4150 nt_status = add_collision(c_info, new_fti_idx,
4152 LSA_TLN_DISABLED_CONFLICT,
4156 nt_status = add_collision(c_info, new_fti_idx,
4158 LSA_SID_DISABLED_CONFLICT,
4162 nt_status = add_collision(c_info, new_fti_idx,
4164 LSA_NB_DISABLED_CONFLICT,
4169 return NT_STATUS_OK;
4172 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4173 uint32_t idx, uint32_t collision_type,
4174 uint32_t conflict_type, const char *tdo_name)
4176 struct lsa_ForestTrustCollisionRecord **es;
4177 uint32_t i = c_info->count;
4179 es = talloc_realloc(c_info, c_info->entries,
4180 struct lsa_ForestTrustCollisionRecord *, i + 1);
4182 return NT_STATUS_NO_MEMORY;
4184 c_info->entries = es;
4185 c_info->count = i + 1;
4187 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4189 return NT_STATUS_NO_MEMORY;
4193 es[i]->type = collision_type;
4194 es[i]->flags.flags = conflict_type;
4195 es[i]->name.string = talloc_strdup(es[i], tdo_name);
4196 if (!es[i]->name.string) {
4197 return NT_STATUS_NO_MEMORY;
4199 es[i]->name.size = strlen(es[i]->name.string);
4201 return NT_STATUS_OK;
4205 lsa_lsaRSetForestTrustInformation
4207 static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_state *dce_call,
4208 TALLOC_CTX *mem_ctx,
4209 struct lsa_lsaRSetForestTrustInformation *r)
4211 struct dcesrv_handle *h;
4212 struct lsa_policy_state *p_state;
4213 const char *trust_attrs[] = { "trustPartner", "trustAttributes",
4214 "msDS-TrustForestTrustInfo", NULL };
4215 struct ldb_message **dom_res = NULL;
4216 struct ldb_dn *tdo_dn;
4217 struct ldb_message *msg;
4219 const char *td_name;
4220 uint32_t trust_attributes;
4221 struct lsa_ForestTrustCollisionInfo *c_info;
4222 struct ForestTrustInfo *nfti;
4223 struct ForestTrustInfo *fti;
4225 enum ndr_err_code ndr_err;
4230 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4234 if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
4235 return NT_STATUS_INVALID_DOMAIN_STATE;
4238 /* abort if we are not a PDC */
4239 if (!samdb_is_pdc(p_state->sam_ldb)) {
4240 return NT_STATUS_INVALID_DOMAIN_ROLE;
4243 ret = samdb_rodc(p_state->sam_ldb, &am_rodc);
4244 if (ret == LDB_SUCCESS && am_rodc) {
4245 return NT_STATUS_NO_SUCH_DOMAIN;
4248 /* check caller has TRUSTED_SET_AUTH */
4250 /* fetch all trusted domain objects */
4251 num_res = gendb_search(p_state->sam_ldb, mem_ctx,
4253 &dom_res, trust_attrs,
4254 "(objectclass=trustedDomain)");
4256 return NT_STATUS_NO_SUCH_DOMAIN;
4259 for (i = 0; i < num_res; i++) {
4260 td_name = ldb_msg_find_attr_as_string(dom_res[i],
4261 "trustPartner", NULL);
4263 return NT_STATUS_INVALID_DOMAIN_STATE;
4265 if (strcasecmp_m(td_name,
4266 r->in.trusted_domain_name->string) == 0) {
4271 return NT_STATUS_NO_SUCH_DOMAIN;
4274 tdo_dn = dom_res[i]->dn;
4276 trust_attributes = samdb_result_uint(dom_res[i],
4277 "trustAttributes", 0);
4278 if (!(trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4279 return NT_STATUS_INVALID_PARAMETER;
4282 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4283 return NT_STATUS_INVALID_PARAMETER;
4286 nfti = talloc(mem_ctx, struct ForestTrustInfo);
4288 return NT_STATUS_NO_MEMORY;
4291 nt_status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4292 if (!NT_STATUS_IS_OK(nt_status)) {
4296 c_info = talloc_zero(r->out.collision_info,
4297 struct lsa_ForestTrustCollisionInfo);
4299 return NT_STATUS_NO_MEMORY;
4302 /* first check own info, then other domains */
4303 fti = talloc(mem_ctx, struct ForestTrustInfo);
4305 return NT_STATUS_NO_MEMORY;
4308 nt_status = own_ft_info(p_state, fti);
4309 if (!NT_STATUS_IS_OK(nt_status)) {
4313 nt_status = check_ft_info(c_info, p_state->domain_dns,
4315 if (!NT_STATUS_IS_OK(nt_status)) {
4319 for (i = 0; i < num_res; i++) {
4320 fti = talloc(mem_ctx, struct ForestTrustInfo);
4322 return NT_STATUS_NO_MEMORY;
4325 nt_status = get_ft_info(mem_ctx, dom_res[i], fti);
4326 if (!NT_STATUS_IS_OK(nt_status)) {
4327 if (NT_STATUS_EQUAL(nt_status,
4328 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4334 td_name = ldb_msg_find_attr_as_string(dom_res[i],
4335 "trustPartner", NULL);
4337 return NT_STATUS_INVALID_DOMAIN_STATE;
4340 nt_status = check_ft_info(c_info, td_name, fti, nfti, c_info);
4341 if (!NT_STATUS_IS_OK(nt_status)) {
4346 *r->out.collision_info = c_info;
4348 if (r->in.check_only != 0) {
4349 return NT_STATUS_OK;
4352 /* not just a check, write info back */
4354 ndr_err = ndr_push_struct_blob(&ft_blob, mem_ctx, nfti,
4355 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4356 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4357 return NT_STATUS_INVALID_PARAMETER;
4360 msg = ldb_msg_new(mem_ctx);
4362 return NT_STATUS_NO_MEMORY;
4365 msg->dn = ldb_dn_copy(mem_ctx, tdo_dn);
4367 return NT_STATUS_NO_MEMORY;
4370 ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo",
4371 LDB_FLAG_MOD_REPLACE, NULL);
4372 if (ret != LDB_SUCCESS) {
4373 return NT_STATUS_NO_MEMORY;
4375 ret = ldb_msg_add_value(msg, "msDS-TrustForestTrustInfo",
4377 if (ret != LDB_SUCCESS) {
4378 return NT_STATUS_NO_MEMORY;
4381 ret = ldb_modify(p_state->sam_ldb, msg);
4382 if (ret != LDB_SUCCESS) {
4383 DEBUG(0, ("Failed to store Forest Trust Info: %s\n",
4384 ldb_errstring(p_state->sam_ldb)));
4387 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
4388 return NT_STATUS_ACCESS_DENIED;
4390 return NT_STATUS_INTERNAL_DB_CORRUPTION;
4394 return NT_STATUS_OK;
4400 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4401 struct lsa_CREDRRENAME *r)
4403 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4409 lsa_LSAROPENPOLICYSCE
4411 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4412 struct lsa_LSAROPENPOLICYSCE *r)
4414 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4419 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
4421 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4422 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4424 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4429 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
4431 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4432 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4434 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4439 lsa_LSARADTREPORTSECURITYEVENT
4441 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4442 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4444 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4448 /* include the generated boilerplate */
4449 #include "librpc/gen_ndr/ndr_lsa_s.c"
4453 /*****************************************
4454 NOTE! The remaining calls below were
4455 removed in w2k3, so the DCESRV_FAULT()
4456 replies are the correct implementation. Do
4457 not try and fill these in with anything else
4458 ******************************************/
4461 dssetup_DsRoleDnsNameToFlatName
4463 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4464 struct dssetup_DsRoleDnsNameToFlatName *r)
4466 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4471 dssetup_DsRoleDcAsDc
4473 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4474 struct dssetup_DsRoleDcAsDc *r)
4476 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4481 dssetup_DsRoleDcAsReplica
4483 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4484 struct dssetup_DsRoleDcAsReplica *r)
4486 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4491 dssetup_DsRoleDemoteDc
4493 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4494 struct dssetup_DsRoleDemoteDc *r)
4496 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4501 dssetup_DsRoleGetDcOperationProgress
4503 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4504 struct dssetup_DsRoleGetDcOperationProgress *r)
4506 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4511 dssetup_DsRoleGetDcOperationResults
4513 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4514 struct dssetup_DsRoleGetDcOperationResults *r)
4516 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4521 dssetup_DsRoleCancel
4523 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4524 struct dssetup_DsRoleCancel *r)
4526 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4531 dssetup_DsRoleServerSaveStateForUpgrade
4533 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4534 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
4536 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4541 dssetup_DsRoleUpgradeDownlevelServer
4543 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4544 struct dssetup_DsRoleUpgradeDownlevelServer *r)
4546 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4551 dssetup_DsRoleAbortDownlevelServerUpgrade
4553 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4554 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
4556 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4560 /* include the generated boilerplate */
4561 #include "librpc/gen_ndr/ndr_dssetup_s.c"
4563 NTSTATUS dcerpc_server_lsa_init(void)
4567 ret = dcerpc_server_dssetup_init();
4568 if (!NT_STATUS_IS_OK(ret)) {
4571 ret = dcerpc_server_lsarpc_init();
4572 if (!NT_STATUS_IS_OK(ret)) {