1 /* need access mask/acl implementation */
4 Unix SMB/CIFS implementation.
6 endpoint server for the lsarpc pipe
8 Copyright (C) Andrew Tridgell 2004
9 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "rpc_server/lsa/lsa.h"
26 #include "system/kerberos.h"
27 #include "auth/kerberos/kerberos.h"
28 #include "librpc/gen_ndr/ndr_drsblobs.h"
29 #include "librpc/gen_ndr/ndr_lsa.h"
30 #include "../lib/crypto/crypto.h"
31 #include "lib/util/tsort.h"
32 #include "dsdb/common/util.h"
33 #include "libcli/security/session.h"
34 #include "kdc/kdc-policy.h"
37 this type allows us to distinguish handle types
41 state associated with a lsa_OpenAccount() operation
43 struct lsa_account_state {
44 struct lsa_policy_state *policy;
46 struct dom_sid *account_sid;
51 state associated with a lsa_OpenSecret() operation
53 struct lsa_secret_state {
54 struct lsa_policy_state *policy;
56 struct ldb_dn *secret_dn;
57 struct ldb_context *sam_ldb;
62 state associated with a lsa_OpenTrustedDomain() operation
64 struct lsa_trusted_domain_state {
65 struct lsa_policy_state *policy;
67 struct ldb_dn *trusted_domain_dn;
68 struct ldb_dn *trusted_domain_user_dn;
72 this is based on the samba3 function make_lsa_object_sd()
73 It uses the same logic, but with samba4 helper functions
75 static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
76 struct security_descriptor **sd,
82 struct dom_sid *domain_sid, *domain_admins_sid;
83 const char *domain_admins_sid_str, *sidstr;
84 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
86 status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
87 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
89 domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
90 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid, tmp_ctx);
92 domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
93 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid_str, tmp_ctx);
95 sidstr = dom_sid_string(tmp_ctx, sid);
96 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, tmp_ctx);
98 *sd = security_descriptor_dacl_create(mem_ctx,
102 SEC_ACE_TYPE_ACCESS_ALLOWED,
103 SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,
105 SID_BUILTIN_ADMINISTRATORS,
106 SEC_ACE_TYPE_ACCESS_ALLOWED,
109 SID_BUILTIN_ACCOUNT_OPERATORS,
110 SEC_ACE_TYPE_ACCESS_ALLOWED,
113 domain_admins_sid_str,
114 SEC_ACE_TYPE_ACCESS_ALLOWED,
118 SEC_ACE_TYPE_ACCESS_ALLOWED,
122 talloc_free(tmp_ctx);
124 NT_STATUS_HAVE_NO_MEMORY(*sd);
130 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
132 struct lsa_EnumAccountRights *r);
134 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
136 struct lsa_policy_state *state,
139 const struct lsa_RightSet *rights);
144 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
147 struct dcesrv_handle *h;
149 *r->out.handle = *r->in.handle;
151 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
155 ZERO_STRUCTP(r->out.handle);
164 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
165 struct lsa_Delete *r)
167 return NT_STATUS_NOT_SUPPORTED;
174 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
175 struct lsa_DeleteObject *r)
177 struct dcesrv_handle *h;
180 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
182 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
183 struct lsa_secret_state *secret_state = h->data;
185 /* Ensure user is permitted to delete this... */
186 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
188 case SECURITY_SYSTEM:
189 case SECURITY_ADMINISTRATOR:
192 /* Users and anonymous are not allowed to delete things */
193 return NT_STATUS_ACCESS_DENIED;
196 ret = ldb_delete(secret_state->sam_ldb,
197 secret_state->secret_dn);
198 if (ret != LDB_SUCCESS) {
199 return NT_STATUS_INVALID_HANDLE;
202 ZERO_STRUCTP(r->out.handle);
206 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
207 struct lsa_trusted_domain_state *trusted_domain_state =
208 talloc_get_type(h->data, struct lsa_trusted_domain_state);
209 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
210 if (ret != LDB_SUCCESS) {
211 return NT_STATUS_INTERNAL_DB_CORRUPTION;
214 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
215 trusted_domain_state->trusted_domain_dn);
216 if (ret != LDB_SUCCESS) {
217 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
218 return NT_STATUS_INVALID_HANDLE;
221 if (trusted_domain_state->trusted_domain_user_dn) {
222 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
223 trusted_domain_state->trusted_domain_user_dn);
224 if (ret != LDB_SUCCESS) {
225 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
226 return NT_STATUS_INVALID_HANDLE;
230 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
231 if (ret != LDB_SUCCESS) {
232 return NT_STATUS_INTERNAL_DB_CORRUPTION;
235 ZERO_STRUCTP(r->out.handle);
239 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
240 struct lsa_RightSet *rights;
241 struct lsa_account_state *astate;
242 struct lsa_EnumAccountRights r2;
245 rights = talloc(mem_ctx, struct lsa_RightSet);
247 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
251 r2.in.handle = &astate->policy->handle->wire_handle;
252 r2.in.sid = astate->account_sid;
253 r2.out.rights = rights;
255 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
256 but we have a LSA_HANDLE_ACCOUNT here, so this call
258 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
259 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
263 if (!NT_STATUS_IS_OK(status)) {
267 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
268 LDB_FLAG_MOD_DELETE, astate->account_sid,
270 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
274 if (!NT_STATUS_IS_OK(status)) {
278 ZERO_STRUCTP(r->out.handle);
283 return NT_STATUS_INVALID_HANDLE;
290 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
291 struct lsa_EnumPrivs *r)
293 struct dcesrv_handle *h;
294 struct lsa_policy_state *state;
296 enum sec_privilege priv;
297 const char *privname;
299 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
303 i = *r->in.resume_handle;
305 while (((priv = sec_privilege_from_index(i)) != SEC_PRIV_INVALID) &&
306 r->out.privs->count < r->in.max_count) {
307 struct lsa_PrivEntry *e;
308 privname = sec_privilege_name(priv);
309 r->out.privs->privs = talloc_realloc(r->out.privs,
311 struct lsa_PrivEntry,
312 r->out.privs->count+1);
313 if (r->out.privs->privs == NULL) {
314 return NT_STATUS_NO_MEMORY;
316 e = &r->out.privs->privs[r->out.privs->count];
319 e->name.string = privname;
320 r->out.privs->count++;
324 *r->out.resume_handle = i;
333 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
334 struct lsa_QuerySecurity *r)
336 struct dcesrv_handle *h;
337 struct security_descriptor *sd;
341 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
343 sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
345 if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
346 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid, 0);
347 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
348 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid,
349 LSA_ACCOUNT_ALL_ACCESS);
351 return NT_STATUS_INVALID_HANDLE;
353 NT_STATUS_NOT_OK_RETURN(status);
355 (*r->out.sdbuf) = talloc(mem_ctx, struct sec_desc_buf);
356 NT_STATUS_HAVE_NO_MEMORY(*r->out.sdbuf);
358 (*r->out.sdbuf)->sd = sd;
367 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
368 struct lsa_SetSecObj *r)
370 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
377 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
378 struct lsa_ChangePassword *r)
380 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
384 dssetup_DsRoleGetPrimaryDomainInformation
386 This is not an LSA call, but is the only call left on the DSSETUP
387 pipe (after the pipe was truncated), and needs lsa_get_policy_state
389 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
391 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
393 union dssetup_DsRoleInfo *info;
395 info = talloc_zero(mem_ctx, union dssetup_DsRoleInfo);
396 W_ERROR_HAVE_NO_MEMORY(info);
398 switch (r->in.level) {
399 case DS_ROLE_BASIC_INFORMATION:
401 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
403 const char *domain = NULL;
404 const char *dns_domain = NULL;
405 const char *forest = NULL;
406 struct GUID domain_guid;
407 struct lsa_policy_state *state;
409 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
410 if (!NT_STATUS_IS_OK(status)) {
411 return ntstatus_to_werror(status);
414 ZERO_STRUCT(domain_guid);
416 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
417 case ROLE_STANDALONE:
418 role = DS_ROLE_STANDALONE_SERVER;
420 case ROLE_DOMAIN_MEMBER:
421 role = DS_ROLE_MEMBER_SERVER;
423 case ROLE_DOMAIN_CONTROLLER:
424 if (samdb_is_pdc(state->sam_ldb)) {
425 role = DS_ROLE_PRIMARY_DC;
427 role = DS_ROLE_BACKUP_DC;
432 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
433 case ROLE_STANDALONE:
434 domain = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
435 W_ERROR_HAVE_NO_MEMORY(domain);
437 case ROLE_DOMAIN_MEMBER:
438 domain = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
439 W_ERROR_HAVE_NO_MEMORY(domain);
440 /* TODO: what is with dns_domain and forest and guid? */
442 case ROLE_DOMAIN_CONTROLLER:
443 flags = DS_ROLE_PRIMARY_DS_RUNNING;
445 if (state->mixed_domain == 1) {
446 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
449 domain = state->domain_name;
450 dns_domain = state->domain_dns;
451 forest = state->forest_dns;
453 domain_guid = state->domain_guid;
454 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
458 info->basic.role = role;
459 info->basic.flags = flags;
460 info->basic.domain = domain;
461 info->basic.dns_domain = dns_domain;
462 info->basic.forest = forest;
463 info->basic.domain_guid = domain_guid;
468 case DS_ROLE_UPGRADE_STATUS:
470 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
471 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
476 case DS_ROLE_OP_STATUS:
478 info->opstatus.status = DS_ROLE_OP_IDLE;
484 return WERR_INVALID_PARAM;
489 fill in the AccountDomain info
491 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
492 struct lsa_DomainInfo *info)
494 info->name.string = state->domain_name;
495 info->sid = state->domain_sid;
501 fill in the DNS domain info
503 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
504 struct lsa_DnsDomainInfo *info)
506 info->name.string = state->domain_name;
507 info->sid = state->domain_sid;
508 info->dns_domain.string = state->domain_dns;
509 info->dns_forest.string = state->forest_dns;
510 info->domain_guid = state->domain_guid;
518 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
519 struct lsa_QueryInfoPolicy2 *r)
521 struct lsa_policy_state *state;
522 struct dcesrv_handle *h;
523 union lsa_PolicyInformation *info;
527 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
531 info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
533 return NT_STATUS_NO_MEMORY;
537 switch (r->in.level) {
538 case LSA_POLICY_INFO_AUDIT_LOG:
539 /* we don't need to fill in any of this */
540 ZERO_STRUCT(info->audit_log);
542 case LSA_POLICY_INFO_AUDIT_EVENTS:
543 /* we don't need to fill in any of this */
544 ZERO_STRUCT(info->audit_events);
546 case LSA_POLICY_INFO_PD:
547 /* we don't need to fill in any of this */
548 ZERO_STRUCT(info->pd);
551 case LSA_POLICY_INFO_DOMAIN:
552 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
553 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
554 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
555 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
556 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
558 case LSA_POLICY_INFO_ROLE:
559 info->role.role = LSA_ROLE_PRIMARY;
562 case LSA_POLICY_INFO_DNS:
563 case LSA_POLICY_INFO_DNS_INT:
564 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
566 case LSA_POLICY_INFO_REPLICA:
567 ZERO_STRUCT(info->replica);
570 case LSA_POLICY_INFO_QUOTA:
571 ZERO_STRUCT(info->quota);
574 case LSA_POLICY_INFO_MOD:
575 case LSA_POLICY_INFO_AUDIT_FULL_SET:
576 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
577 /* windows gives INVALID_PARAMETER */
579 return NT_STATUS_INVALID_PARAMETER;
583 return NT_STATUS_INVALID_INFO_CLASS;
589 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
590 struct lsa_QueryInfoPolicy *r)
592 struct lsa_QueryInfoPolicy2 r2;
597 r2.in.handle = r->in.handle;
598 r2.in.level = r->in.level;
599 r2.out.info = r->out.info;
601 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
609 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
610 struct lsa_SetInfoPolicy *r)
612 /* need to support this */
613 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
620 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
621 struct lsa_ClearAuditLog *r)
623 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
630 This call does not seem to have any long-term effects, hence no database operations
632 we need to talk to the MS product group to find out what this account database means!
634 answer is that the lsa database is totally separate from the SAM and
635 ldap databases. We are going to need a separate ldb to store these
636 accounts. The SIDs on this account bear no relation to the SIDs in
639 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
640 struct lsa_CreateAccount *r)
642 struct lsa_account_state *astate;
644 struct lsa_policy_state *state;
645 struct dcesrv_handle *h, *ah;
647 ZERO_STRUCTP(r->out.acct_handle);
649 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
653 astate = talloc(dce_call->conn, struct lsa_account_state);
654 if (astate == NULL) {
655 return NT_STATUS_NO_MEMORY;
658 astate->account_sid = dom_sid_dup(astate, r->in.sid);
659 if (astate->account_sid == NULL) {
661 return NT_STATUS_NO_MEMORY;
664 astate->policy = talloc_reference(astate, state);
665 astate->access_mask = r->in.access_mask;
667 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
670 return NT_STATUS_NO_MEMORY;
673 ah->data = talloc_steal(ah, astate);
675 *r->out.acct_handle = ah->wire_handle;
684 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
685 struct lsa_EnumAccounts *r)
687 struct dcesrv_handle *h;
688 struct lsa_policy_state *state;
690 struct ldb_message **res;
691 const char * const attrs[] = { "objectSid", NULL};
694 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
698 /* NOTE: This call must only return accounts that have at least
701 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
702 "(&(objectSid=*)(privilege=*))");
704 return NT_STATUS_INTERNAL_DB_CORRUPTION;
707 if (*r->in.resume_handle >= ret) {
708 return NT_STATUS_NO_MORE_ENTRIES;
711 count = ret - *r->in.resume_handle;
712 if (count > r->in.num_entries) {
713 count = r->in.num_entries;
717 return NT_STATUS_NO_MORE_ENTRIES;
720 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
721 if (r->out.sids->sids == NULL) {
722 return NT_STATUS_NO_MEMORY;
725 for (i=0;i<count;i++) {
726 r->out.sids->sids[i].sid =
727 samdb_result_dom_sid(r->out.sids->sids,
728 res[i + *r->in.resume_handle],
730 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
733 r->out.sids->num_sids = count;
734 *r->out.resume_handle = count + *r->in.resume_handle;
740 /* This decrypts and returns Trusted Domain Auth Information Internal data */
741 static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
742 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
743 struct trustDomainPasswords *auth_struct)
745 DATA_BLOB session_key = data_blob(NULL, 0);
746 enum ndr_err_code ndr_err;
749 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
750 if (!NT_STATUS_IS_OK(nt_status)) {
754 arcfour_crypt_blob(auth_blob->data, auth_blob->length, &session_key);
755 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
757 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
758 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
759 return NT_STATUS_INVALID_PARAMETER;
765 static NTSTATUS get_trustauth_inout_blob(struct dcesrv_call_state *dce_call,
767 struct trustAuthInOutBlob *iopw,
768 DATA_BLOB *trustauth_blob)
770 enum ndr_err_code ndr_err;
772 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
774 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
775 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
776 return NT_STATUS_INVALID_PARAMETER;
782 static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx,
783 struct ldb_context *sam_ldb,
784 struct ldb_dn *base_dn,
785 const char *netbios_name,
786 struct trustAuthInOutBlob *in,
787 struct ldb_dn **user_dn)
789 struct ldb_message *msg;
794 dn = ldb_dn_copy(mem_ctx, base_dn);
796 return NT_STATUS_NO_MEMORY;
798 if (!ldb_dn_add_child_fmt(dn, "cn=%s$,cn=users", netbios_name)) {
799 return NT_STATUS_NO_MEMORY;
802 msg = ldb_msg_new(mem_ctx);
804 return NT_STATUS_NO_MEMORY;
808 ret = ldb_msg_add_string(msg, "objectClass", "user");
809 if (ret != LDB_SUCCESS) {
810 return NT_STATUS_NO_MEMORY;
813 ret = ldb_msg_add_fmt(msg, "samAccountName", "%s$", netbios_name);
814 if (ret != LDB_SUCCESS) {
815 return NT_STATUS_NO_MEMORY;
818 ret = samdb_msg_add_uint(sam_ldb, msg, msg, "userAccountControl",
819 UF_INTERDOMAIN_TRUST_ACCOUNT);
820 if (ret != LDB_SUCCESS) {
821 return NT_STATUS_NO_MEMORY;
824 for (i = 0; i < in->count; i++) {
825 const char *attribute;
827 switch (in->current.array[i].AuthType) {
828 case TRUST_AUTH_TYPE_NT4OWF:
829 attribute = "unicodePwd";
830 v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
833 case TRUST_AUTH_TYPE_CLEAR:
834 attribute = "clearTextPassword";
835 v.data = in->current.array[i].AuthInfo.clear.password;
836 v.length = in->current.array[i].AuthInfo.clear.size;
842 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
843 if (ret != LDB_SUCCESS) {
844 return NT_STATUS_NO_MEMORY;
848 /* create the trusted_domain user account */
849 ret = ldb_add(sam_ldb, msg);
850 if (ret != LDB_SUCCESS) {
851 DEBUG(0,("Failed to create user record %s: %s\n",
852 ldb_dn_get_linearized(msg->dn),
853 ldb_errstring(sam_ldb)));
856 case LDB_ERR_ENTRY_ALREADY_EXISTS:
857 return NT_STATUS_DOMAIN_EXISTS;
858 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
859 return NT_STATUS_ACCESS_DENIED;
861 return NT_STATUS_INTERNAL_DB_CORRUPTION;
872 lsa_CreateTrustedDomainEx2
874 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
876 struct lsa_CreateTrustedDomainEx2 *r,
879 struct dcesrv_handle *policy_handle;
880 struct lsa_policy_state *policy_state;
881 struct lsa_trusted_domain_state *trusted_domain_state;
882 struct dcesrv_handle *handle;
883 struct ldb_message **msgs, *msg;
884 const char *attrs[] = {
887 const char *netbios_name;
888 const char *dns_name;
890 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
891 struct trustDomainPasswords auth_struct;
894 struct ldb_context *sam_ldb;
896 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
897 ZERO_STRUCTP(r->out.trustdom_handle);
899 policy_state = policy_handle->data;
900 sam_ldb = policy_state->sam_ldb;
902 netbios_name = r->in.info->netbios_name.string;
904 return NT_STATUS_INVALID_PARAMETER;
907 dns_name = r->in.info->domain_name.string;
909 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
910 if (!trusted_domain_state) {
911 return NT_STATUS_NO_MEMORY;
913 trusted_domain_state->policy = policy_state;
915 if (strcasecmp(netbios_name, "BUILTIN") == 0
916 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
917 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
918 return NT_STATUS_INVALID_PARAMETER;
921 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
922 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
923 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
924 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
925 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
926 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
929 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
930 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
931 /* No secrets are created at this time, for this function */
932 auth_struct.outgoing.count = 0;
933 auth_struct.incoming.count = 0;
935 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data,
936 r->in.auth_info->auth_blob.size);
937 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
938 &auth_blob, &auth_struct);
939 if (!NT_STATUS_IS_OK(nt_status)) {
943 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
944 if (auth_struct.incoming.count > 1) {
945 return NT_STATUS_INVALID_PARAMETER;
950 if (auth_struct.incoming.count) {
951 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
952 &auth_struct.incoming,
954 if (!NT_STATUS_IS_OK(nt_status)) {
958 trustAuthIncoming = data_blob(NULL, 0);
961 if (auth_struct.outgoing.count) {
962 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
963 &auth_struct.outgoing,
965 if (!NT_STATUS_IS_OK(nt_status)) {
969 trustAuthOutgoing = data_blob(NULL, 0);
972 ret = ldb_transaction_start(sam_ldb);
973 if (ret != LDB_SUCCESS) {
974 return NT_STATUS_INTERNAL_DB_CORRUPTION;
978 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
979 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
980 /* search for the trusted_domain record */
981 ret = gendb_search(sam_ldb,
982 mem_ctx, policy_state->system_dn, &msgs, attrs,
983 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
984 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
986 ldb_transaction_cancel(sam_ldb);
987 return NT_STATUS_OBJECT_NAME_COLLISION;
990 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
991 /* search for the trusted_domain record */
992 ret = gendb_search(sam_ldb,
993 mem_ctx, policy_state->system_dn, &msgs, attrs,
994 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
995 netbios_encoded, netbios_encoded, netbios_encoded);
997 ldb_transaction_cancel(sam_ldb);
998 return NT_STATUS_OBJECT_NAME_COLLISION;
1003 ldb_transaction_cancel(sam_ldb);
1004 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1007 name = dns_name ? dns_name : netbios_name;
1009 msg = ldb_msg_new(mem_ctx);
1011 return NT_STATUS_NO_MEMORY;
1014 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1015 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
1016 ldb_transaction_cancel(sam_ldb);
1017 return NT_STATUS_NO_MEMORY;
1020 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "flatname", netbios_name);
1022 if (r->in.info->sid) {
1023 ret = samdb_msg_add_dom_sid(sam_ldb, mem_ctx, msg, "securityIdentifier", r->in.info->sid);
1024 if (ret != LDB_SUCCESS) {
1025 ldb_transaction_cancel(sam_ldb);
1026 return NT_STATUS_INVALID_PARAMETER;
1030 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
1032 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
1034 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
1036 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
1039 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
1042 if (trustAuthIncoming.data) {
1043 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
1044 if (ret != LDB_SUCCESS) {
1045 ldb_transaction_cancel(sam_ldb);
1046 return NT_STATUS_NO_MEMORY;
1049 if (trustAuthOutgoing.data) {
1050 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
1051 if (ret != LDB_SUCCESS) {
1052 ldb_transaction_cancel(sam_ldb);
1053 return NT_STATUS_NO_MEMORY;
1057 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
1059 /* create the trusted_domain */
1060 ret = ldb_add(sam_ldb, msg);
1064 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1065 ldb_transaction_cancel(sam_ldb);
1066 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1067 ldb_dn_get_linearized(msg->dn),
1068 ldb_errstring(sam_ldb)));
1069 return NT_STATUS_DOMAIN_EXISTS;
1070 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1071 ldb_transaction_cancel(sam_ldb);
1072 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1073 ldb_dn_get_linearized(msg->dn),
1074 ldb_errstring(sam_ldb)));
1075 return NT_STATUS_ACCESS_DENIED;
1077 ldb_transaction_cancel(sam_ldb);
1078 DEBUG(0,("Failed to create user record %s: %s\n",
1079 ldb_dn_get_linearized(msg->dn),
1080 ldb_errstring(sam_ldb)));
1081 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1084 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1085 struct ldb_dn *user_dn;
1086 /* Inbound trusts must also create a cn=users object to match */
1087 nt_status = add_trust_user(mem_ctx, sam_ldb,
1088 policy_state->domain_dn,
1090 &auth_struct.incoming,
1092 if (!NT_STATUS_IS_OK(nt_status)) {
1093 ldb_transaction_cancel(sam_ldb);
1097 /* save the trust user dn */
1098 trusted_domain_state->trusted_domain_user_dn
1099 = talloc_steal(trusted_domain_state, user_dn);
1102 ret = ldb_transaction_commit(sam_ldb);
1103 if (ret != LDB_SUCCESS) {
1104 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1107 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1109 return NT_STATUS_NO_MEMORY;
1112 handle->data = talloc_steal(handle, trusted_domain_state);
1114 trusted_domain_state->access_mask = r->in.access_mask;
1115 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1117 *r->out.trustdom_handle = handle->wire_handle;
1119 return NT_STATUS_OK;
1123 lsa_CreateTrustedDomainEx2
1125 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1126 TALLOC_CTX *mem_ctx,
1127 struct lsa_CreateTrustedDomainEx2 *r)
1129 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
1132 lsa_CreateTrustedDomainEx
1134 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1135 TALLOC_CTX *mem_ctx,
1136 struct lsa_CreateTrustedDomainEx *r)
1138 struct lsa_CreateTrustedDomainEx2 r2;
1140 r2.in.policy_handle = r->in.policy_handle;
1141 r2.in.info = r->in.info;
1142 r2.in.auth_info = r->in.auth_info;
1143 r2.out.trustdom_handle = r->out.trustdom_handle;
1144 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
1148 lsa_CreateTrustedDomain
1150 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1151 struct lsa_CreateTrustedDomain *r)
1153 struct lsa_CreateTrustedDomainEx2 r2;
1155 r2.in.policy_handle = r->in.policy_handle;
1156 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1158 return NT_STATUS_NO_MEMORY;
1161 r2.in.info->domain_name.string = NULL;
1162 r2.in.info->netbios_name = r->in.info->name;
1163 r2.in.info->sid = r->in.info->sid;
1164 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1165 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1166 r2.in.info->trust_attributes = 0;
1168 r2.in.access_mask = r->in.access_mask;
1169 r2.out.trustdom_handle = r->out.trustdom_handle;
1171 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1176 lsa_OpenTrustedDomain
1178 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1179 struct lsa_OpenTrustedDomain *r)
1181 struct dcesrv_handle *policy_handle;
1183 struct lsa_policy_state *policy_state;
1184 struct lsa_trusted_domain_state *trusted_domain_state;
1185 struct dcesrv_handle *handle;
1186 struct ldb_message **msgs;
1187 const char *attrs[] = {
1193 const char *sid_string;
1196 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1197 ZERO_STRUCTP(r->out.trustdom_handle);
1198 policy_state = policy_handle->data;
1200 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1201 if (!trusted_domain_state) {
1202 return NT_STATUS_NO_MEMORY;
1204 trusted_domain_state->policy = policy_state;
1206 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1208 return NT_STATUS_NO_MEMORY;
1211 /* search for the trusted_domain record */
1212 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1213 mem_ctx, policy_state->system_dn, &msgs, attrs,
1214 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
1217 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1221 DEBUG(0,("Found %d records matching DN %s\n", ret,
1222 ldb_dn_get_linearized(policy_state->system_dn)));
1223 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1226 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1228 trusted_domain_state->trusted_domain_user_dn = NULL;
1230 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1231 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1232 /* search for the trusted_domain record */
1233 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1234 mem_ctx, policy_state->domain_dn, &msgs, attrs,
1235 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%u))",
1236 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1238 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1241 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1243 return NT_STATUS_NO_MEMORY;
1246 handle->data = talloc_steal(handle, trusted_domain_state);
1248 trusted_domain_state->access_mask = r->in.access_mask;
1249 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1251 *r->out.trustdom_handle = handle->wire_handle;
1253 return NT_STATUS_OK;
1258 lsa_OpenTrustedDomainByName
1260 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1261 TALLOC_CTX *mem_ctx,
1262 struct lsa_OpenTrustedDomainByName *r)
1264 struct dcesrv_handle *policy_handle;
1266 struct lsa_policy_state *policy_state;
1267 struct lsa_trusted_domain_state *trusted_domain_state;
1268 struct dcesrv_handle *handle;
1269 struct ldb_message **msgs;
1270 const char *attrs[] = {
1276 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1277 ZERO_STRUCTP(r->out.trustdom_handle);
1278 policy_state = policy_handle->data;
1280 if (!r->in.name.string) {
1281 return NT_STATUS_INVALID_PARAMETER;
1284 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1285 if (!trusted_domain_state) {
1286 return NT_STATUS_NO_MEMORY;
1288 trusted_domain_state->policy = policy_state;
1290 /* search for the trusted_domain record */
1291 td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string);
1292 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1293 mem_ctx, policy_state->system_dn, &msgs, attrs,
1294 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))"
1295 "(objectclass=trustedDomain))",
1296 td_name, td_name, td_name);
1298 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1302 DEBUG(0,("Found %d records matching DN %s\n", ret,
1303 ldb_dn_get_linearized(policy_state->system_dn)));
1304 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1307 /* TODO: perform access checks */
1309 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1311 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1313 return NT_STATUS_NO_MEMORY;
1316 handle->data = talloc_steal(handle, trusted_domain_state);
1318 trusted_domain_state->access_mask = r->in.access_mask;
1319 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1321 *r->out.trustdom_handle = handle->wire_handle;
1323 return NT_STATUS_OK;
1329 lsa_SetTrustedDomainInfo
1331 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1332 struct lsa_SetTrustedDomainInfo *r)
1334 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1339 /* parameters 4 to 6 are optional if the dn is a dn of a TDO object,
1340 * otherwise at least one must be provided */
1341 static NTSTATUS get_tdo(struct ldb_context *sam, TALLOC_CTX *mem_ctx,
1342 struct ldb_dn *basedn, const char *dns_domain,
1343 const char *netbios, struct dom_sid2 *sid,
1344 struct ldb_message ***msgs)
1346 const char *attrs[] = { "flatname", "trustPartner",
1347 "securityIdentifier", "trustDirection",
1348 "trustType", "trustAttributes",
1350 "msDs-supportedEncryptionTypes", NULL };
1353 char *sidstr = NULL;
1358 if (dns_domain || netbios || sid) {
1359 filter = talloc_strdup(mem_ctx,
1360 "(&(objectclass=trustedDomain)(|");
1362 filter = talloc_strdup(mem_ctx,
1363 "(objectclass=trustedDomain)");
1366 return NT_STATUS_NO_MEMORY;
1370 dns = ldb_binary_encode_string(mem_ctx, dns_domain);
1372 return NT_STATUS_NO_MEMORY;
1374 filter = talloc_asprintf_append(filter,
1375 "(trustPartner=%s)", dns);
1377 return NT_STATUS_NO_MEMORY;
1381 nbn = ldb_binary_encode_string(mem_ctx, netbios);
1383 return NT_STATUS_NO_MEMORY;
1385 filter = talloc_asprintf_append(filter,
1386 "(flatname=%s)", nbn);
1388 return NT_STATUS_NO_MEMORY;
1392 sidstr = dom_sid_string(mem_ctx, sid);
1394 return NT_STATUS_INVALID_PARAMETER;
1396 filter = talloc_asprintf_append(filter,
1397 "(securityIdentifier=%s)",
1400 return NT_STATUS_NO_MEMORY;
1403 if (dns_domain || netbios || sid) {
1404 filter = talloc_asprintf_append(filter, "))");
1406 return NT_STATUS_NO_MEMORY;
1410 ret = gendb_search(sam, mem_ctx, basedn, msgs, attrs, "%s", filter);
1412 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1416 return NT_STATUS_OBJECT_NAME_COLLISION;
1419 return NT_STATUS_OK;
1422 static NTSTATUS update_uint32_t_value(TALLOC_CTX *mem_ctx,
1423 struct ldb_context *sam_ldb,
1424 struct ldb_message *orig,
1425 struct ldb_message *dest,
1426 const char *attribute,
1428 uint32_t *orig_value)
1430 const struct ldb_val *orig_val;
1431 uint32_t orig_uint = 0;
1435 orig_val = ldb_msg_find_ldb_val(orig, attribute);
1436 if (!orig_val || !orig_val->data) {
1437 /* add new attribute */
1438 flags = LDB_FLAG_MOD_ADD;
1442 orig_uint = strtoul((const char *)orig_val->data, NULL, 0);
1443 if (errno != 0 || orig_uint != value) {
1444 /* replace also if can't get value */
1445 flags = LDB_FLAG_MOD_REPLACE;
1450 /* stored value is identical, nothing to change */
1454 ret = ldb_msg_add_empty(dest, attribute, flags, NULL);
1455 if (ret != LDB_SUCCESS) {
1456 return NT_STATUS_NO_MEMORY;
1459 ret = samdb_msg_add_uint(sam_ldb, dest, dest, attribute, value);
1460 if (ret != LDB_SUCCESS) {
1461 return NT_STATUS_NO_MEMORY;
1466 *orig_value = orig_uint;
1468 return NT_STATUS_OK;
1471 static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx,
1472 struct ldb_context *sam_ldb,
1473 struct ldb_dn *base_dn,
1475 const char *netbios_name,
1476 struct trustAuthInOutBlob *in)
1478 const char *attrs[] = { "userAccountControl", NULL };
1479 struct ldb_message **msgs;
1480 struct ldb_message *msg;
1485 ret = gendb_search(sam_ldb, mem_ctx,
1486 base_dn, &msgs, attrs,
1487 "samAccountName=%s$", netbios_name);
1489 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1494 return NT_STATUS_OK;
1497 /* ok no existing user, add it from scratch */
1498 return add_trust_user(mem_ctx, sam_ldb, base_dn,
1499 netbios_name, in, NULL);
1502 /* check user is what we are looking for */
1503 uac = ldb_msg_find_attr_as_uint(msgs[0],
1504 "userAccountControl", 0);
1505 if (!(uac & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
1506 return NT_STATUS_OBJECT_NAME_COLLISION;
1510 ret = ldb_delete(sam_ldb, msgs[0]->dn);
1513 return NT_STATUS_OK;
1514 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1515 return NT_STATUS_ACCESS_DENIED;
1517 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1521 /* entry exists, just modify secret if any */
1522 if (in->count == 0) {
1523 return NT_STATUS_OK;
1526 msg = ldb_msg_new(mem_ctx);
1528 return NT_STATUS_NO_MEMORY;
1530 msg->dn = msgs[0]->dn;
1532 for (i = 0; i < in->count; i++) {
1533 const char *attribute;
1535 switch (in->current.array[i].AuthType) {
1536 case TRUST_AUTH_TYPE_NT4OWF:
1537 attribute = "unicodePwd";
1538 v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
1541 case TRUST_AUTH_TYPE_CLEAR:
1542 attribute = "clearTextPassword";
1543 v.data = in->current.array[i].AuthInfo.clear.password;
1544 v.length = in->current.array[i].AuthInfo.clear.size;
1550 ret = ldb_msg_add_empty(msg, attribute,
1551 LDB_FLAG_MOD_REPLACE, NULL);
1552 if (ret != LDB_SUCCESS) {
1553 return NT_STATUS_NO_MEMORY;
1556 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
1557 if (ret != LDB_SUCCESS) {
1558 return NT_STATUS_NO_MEMORY;
1562 /* create the trusted_domain user account */
1563 ret = ldb_modify(sam_ldb, msg);
1564 if (ret != LDB_SUCCESS) {
1565 DEBUG(0,("Failed to create user record %s: %s\n",
1566 ldb_dn_get_linearized(msg->dn),
1567 ldb_errstring(sam_ldb)));
1570 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1571 return NT_STATUS_DOMAIN_EXISTS;
1572 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1573 return NT_STATUS_ACCESS_DENIED;
1575 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1579 return NT_STATUS_OK;
1583 static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call,
1584 struct dcesrv_handle *p_handle,
1585 TALLOC_CTX *mem_ctx,
1586 struct ldb_message *dom_msg,
1587 enum lsa_TrustDomInfoEnum level,
1588 union lsa_TrustedDomainInfo *info)
1590 struct lsa_policy_state *p_state = p_handle->data;
1591 uint32_t *posix_offset = NULL;
1592 struct lsa_TrustDomainInfoInfoEx *info_ex = NULL;
1593 struct lsa_TrustDomainInfoAuthInfo *auth_info = NULL;
1594 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
1595 uint32_t *enc_types = NULL;
1596 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
1597 struct trustDomainPasswords auth_struct;
1599 struct ldb_message **msgs;
1600 struct ldb_message *msg;
1601 bool add_outgoing = false;
1602 bool add_incoming = false;
1603 bool del_outgoing = false;
1604 bool del_incoming = false;
1605 bool in_transaction = false;
1610 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1611 posix_offset = &info->posix_offset.posix_offset;
1613 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1614 info_ex = &info->info_ex;
1616 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1617 auth_info = &info->auth_info;
1619 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1620 posix_offset = &info->full_info.posix_offset.posix_offset;
1621 info_ex = &info->full_info.info_ex;
1622 auth_info = &info->full_info.auth_info;
1624 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1625 auth_info_int = &info->auth_info_internal;
1627 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1628 posix_offset = &info->full_info_internal.posix_offset.posix_offset;
1629 info_ex = &info->full_info_internal.info_ex;
1630 auth_info_int = &info->full_info_internal.auth_info;
1632 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1633 enc_types = &info->enc_types.enc_types;
1636 return NT_STATUS_INVALID_PARAMETER;
1640 /* FIXME: not handled yet */
1641 return NT_STATUS_INVALID_PARAMETER;
1644 /* decode auth_info_int if set */
1645 if (auth_info_int) {
1647 /* now decrypt blob */
1648 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
1649 auth_info_int->auth_blob.size);
1651 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
1652 &auth_blob, &auth_struct);
1653 if (!NT_STATUS_IS_OK(nt_status)) {
1659 /* verify data matches */
1660 if (info_ex->trust_attributes &
1661 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1662 /* TODO: check what behavior level we have */
1663 if (strcasecmp_m(p_state->domain_dns,
1664 p_state->forest_dns) != 0) {
1665 return NT_STATUS_INVALID_DOMAIN_STATE;
1669 ret = samdb_rodc(p_state->sam_ldb, &am_rodc);
1670 if (ret == LDB_SUCCESS && am_rodc) {
1671 return NT_STATUS_NO_SUCH_DOMAIN;
1674 /* verify only one object matches the dns/netbios/sid
1675 * triplet and that this is the one we already have */
1676 nt_status = get_tdo(p_state->sam_ldb, mem_ctx,
1678 info_ex->domain_name.string,
1679 info_ex->netbios_name.string,
1680 info_ex->sid, &msgs);
1681 if (!NT_STATUS_IS_OK(nt_status)) {
1684 if (ldb_dn_compare(dom_msg->dn, msgs[0]->dn) != 0) {
1685 return NT_STATUS_OBJECT_NAME_COLLISION;
1690 /* TODO: should we fetch previous values from the existing entry
1691 * and append them ? */
1692 if (auth_struct.incoming.count) {
1693 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1694 &auth_struct.incoming,
1695 &trustAuthIncoming);
1696 if (!NT_STATUS_IS_OK(nt_status)) {
1700 trustAuthIncoming = data_blob(NULL, 0);
1703 if (auth_struct.outgoing.count) {
1704 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1705 &auth_struct.outgoing,
1706 &trustAuthOutgoing);
1707 if (!NT_STATUS_IS_OK(nt_status)) {
1711 trustAuthOutgoing = data_blob(NULL, 0);
1714 msg = ldb_msg_new(mem_ctx);
1716 return NT_STATUS_NO_MEMORY;
1718 msg->dn = dom_msg->dn;
1721 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
1724 *posix_offset, NULL);
1725 if (!NT_STATUS_IS_OK(nt_status)) {
1736 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
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, p_state->sam_ldb,
1771 info_ex->trust_attributes,
1773 if (!NT_STATUS_IS_OK(nt_status)) {
1776 /* TODO: check forestFunctionality from ldb opaque */
1777 /* TODO: check what is set makes sense */
1778 /* for now refuse changes */
1779 if (origattrs == -1 ||
1780 origattrs != info_ex->trust_attributes) {
1781 DEBUG(1, ("Attempted to change trust attributes! "
1782 "Operation not handled\n"));
1783 return NT_STATUS_INVALID_PARAMETER;
1788 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
1790 "msDS-SupportedEncryptionTypes",
1792 if (!NT_STATUS_IS_OK(nt_status)) {
1797 if (add_incoming && trustAuthIncoming.data) {
1798 ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
1799 LDB_FLAG_MOD_REPLACE, NULL);
1800 if (ret != LDB_SUCCESS) {
1801 return NT_STATUS_NO_MEMORY;
1803 ret = ldb_msg_add_value(msg, "trustAuthIncoming",
1804 &trustAuthIncoming, NULL);
1805 if (ret != LDB_SUCCESS) {
1806 return NT_STATUS_NO_MEMORY;
1809 if (add_outgoing && trustAuthOutgoing.data) {
1810 ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
1811 LDB_FLAG_MOD_REPLACE, NULL);
1812 if (ret != LDB_SUCCESS) {
1813 return NT_STATUS_NO_MEMORY;
1815 ret = ldb_msg_add_value(msg, "trustAuthOutgoing",
1816 &trustAuthOutgoing, NULL);
1817 if (ret != LDB_SUCCESS) {
1818 return NT_STATUS_NO_MEMORY;
1822 /* start transaction */
1823 ret = ldb_transaction_start(p_state->sam_ldb);
1824 if (ret != LDB_SUCCESS) {
1825 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1827 in_transaction = true;
1829 ret = ldb_modify(p_state->sam_ldb, msg);
1830 if (ret != LDB_SUCCESS) {
1831 DEBUG(1,("Failed to modify trusted domain record %s: %s\n",
1832 ldb_dn_get_linearized(msg->dn),
1833 ldb_errstring(p_state->sam_ldb)));
1834 if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
1835 nt_status = NT_STATUS_ACCESS_DENIED;
1837 nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1842 if (add_incoming || del_incoming) {
1843 const char *netbios_name;
1845 netbios_name = ldb_msg_find_attr_as_string(dom_msg,
1847 if (!netbios_name) {
1848 nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
1852 nt_status = update_trust_user(mem_ctx,
1857 &auth_struct.incoming);
1858 if (!NT_STATUS_IS_OK(nt_status)) {
1863 /* ok, all fine, commit transaction and return */
1864 ret = ldb_transaction_commit(p_state->sam_ldb);
1865 if (ret != LDB_SUCCESS) {
1866 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1868 in_transaction = false;
1870 nt_status = NT_STATUS_OK;
1873 if (in_transaction) {
1874 ldb_transaction_cancel(p_state->sam_ldb);
1880 lsa_SetInfomrationTrustedDomain
1882 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(
1883 struct dcesrv_call_state *dce_call,
1884 TALLOC_CTX *mem_ctx,
1885 struct lsa_SetInformationTrustedDomain *r)
1887 struct dcesrv_handle *h;
1888 struct lsa_trusted_domain_state *td_state;
1889 struct ldb_message **msgs;
1892 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle,
1893 LSA_HANDLE_TRUSTED_DOMAIN);
1895 td_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1897 /* get the trusted domain object */
1898 nt_status = get_tdo(td_state->policy->sam_ldb, mem_ctx,
1899 td_state->trusted_domain_dn,
1900 NULL, NULL, NULL, &msgs);
1901 if (!NT_STATUS_IS_OK(nt_status)) {
1902 if (NT_STATUS_EQUAL(nt_status,
1903 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1906 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1909 return setInfoTrustedDomain_base(dce_call, h, mem_ctx,
1910 msgs[0], r->in.level, r->in.info);
1915 lsa_DeleteTrustedDomain
1917 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1918 struct lsa_DeleteTrustedDomain *r)
1921 struct lsa_OpenTrustedDomain opn;
1922 struct lsa_DeleteObject del;
1923 struct dcesrv_handle *h;
1925 opn.in.handle = r->in.handle;
1926 opn.in.sid = r->in.dom_sid;
1927 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1928 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1929 if (!opn.out.trustdom_handle) {
1930 return NT_STATUS_NO_MEMORY;
1932 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1933 if (!NT_STATUS_IS_OK(status)) {
1937 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1938 talloc_steal(mem_ctx, h);
1940 del.in.handle = opn.out.trustdom_handle;
1941 del.out.handle = opn.out.trustdom_handle;
1942 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
1943 if (!NT_STATUS_IS_OK(status)) {
1946 return NT_STATUS_OK;
1949 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1950 struct ldb_message *msg,
1951 struct lsa_TrustDomainInfoInfoEx *info_ex)
1953 info_ex->domain_name.string
1954 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1955 info_ex->netbios_name.string
1956 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1958 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1959 info_ex->trust_direction
1960 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1962 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1963 info_ex->trust_attributes
1964 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1965 return NT_STATUS_OK;
1969 lsa_QueryTrustedDomainInfo
1971 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1972 struct lsa_QueryTrustedDomainInfo *r)
1974 union lsa_TrustedDomainInfo *info = NULL;
1975 struct dcesrv_handle *h;
1976 struct lsa_trusted_domain_state *trusted_domain_state;
1977 struct ldb_message *msg;
1979 struct ldb_message **res;
1980 const char *attrs[] = {
1983 "securityIdentifier",
1987 "msDs-supportedEncryptionTypes",
1991 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1993 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1995 /* pull all the user attributes */
1996 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1997 trusted_domain_state->trusted_domain_dn, &res, attrs);
1999 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2003 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
2005 return NT_STATUS_NO_MEMORY;
2007 *r->out.info = info;
2009 switch (r->in.level) {
2010 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2011 info->name.netbios_name.string
2012 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2014 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2015 info->posix_offset.posix_offset
2016 = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
2018 #if 0 /* Win2k3 doesn't implement this */
2019 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2020 r->out.info->info_basic.netbios_name.string
2021 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2022 r->out.info->info_basic.sid
2023 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
2026 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2027 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
2029 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2030 ZERO_STRUCT(info->full_info);
2031 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
2032 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2033 ZERO_STRUCT(info->full_info2_internal);
2034 info->full_info2_internal.posix_offset.posix_offset
2035 = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
2036 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
2038 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2039 info->enc_types.enc_types
2040 = ldb_msg_find_attr_as_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
2043 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2044 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2045 /* oops, we don't want to return the info after all */
2047 *r->out.info = NULL;
2048 return NT_STATUS_INVALID_PARAMETER;
2050 /* oops, we don't want to return the info after all */
2052 *r->out.info = NULL;
2053 return NT_STATUS_INVALID_INFO_CLASS;
2056 return NT_STATUS_OK;
2061 lsa_QueryTrustedDomainInfoBySid
2063 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2064 struct lsa_QueryTrustedDomainInfoBySid *r)
2067 struct lsa_OpenTrustedDomain opn;
2068 struct lsa_QueryTrustedDomainInfo query;
2069 struct dcesrv_handle *h;
2071 opn.in.handle = r->in.handle;
2072 opn.in.sid = r->in.dom_sid;
2073 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2074 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2075 if (!opn.out.trustdom_handle) {
2076 return NT_STATUS_NO_MEMORY;
2078 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
2079 if (!NT_STATUS_IS_OK(status)) {
2083 /* Ensure this handle goes away at the end of this call */
2084 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2085 talloc_steal(mem_ctx, h);
2087 query.in.trustdom_handle = opn.out.trustdom_handle;
2088 query.in.level = r->in.level;
2089 query.out.info = r->out.info;
2090 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2091 if (!NT_STATUS_IS_OK(status)) {
2095 return NT_STATUS_OK;
2099 lsa_SetTrustedDomainInfoByName
2101 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2102 TALLOC_CTX *mem_ctx,
2103 struct lsa_SetTrustedDomainInfoByName *r)
2105 struct dcesrv_handle *policy_handle;
2106 struct lsa_policy_state *policy_state;
2107 struct ldb_message **msgs;
2110 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2111 policy_state = policy_handle->data;
2113 /* get the trusted domain object */
2114 nt_status = get_tdo(policy_state->sam_ldb, mem_ctx,
2115 policy_state->domain_dn,
2116 r->in.trusted_domain->string,
2117 r->in.trusted_domain->string,
2119 if (!NT_STATUS_IS_OK(nt_status)) {
2120 if (NT_STATUS_EQUAL(nt_status,
2121 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2124 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2127 return setInfoTrustedDomain_base(dce_call, policy_handle, mem_ctx,
2128 msgs[0], r->in.level, r->in.info);
2132 lsa_QueryTrustedDomainInfoByName
2134 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2135 TALLOC_CTX *mem_ctx,
2136 struct lsa_QueryTrustedDomainInfoByName *r)
2139 struct lsa_OpenTrustedDomainByName opn;
2140 struct lsa_QueryTrustedDomainInfo query;
2141 struct dcesrv_handle *h;
2143 opn.in.handle = r->in.handle;
2144 opn.in.name = *r->in.trusted_domain;
2145 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2146 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2147 if (!opn.out.trustdom_handle) {
2148 return NT_STATUS_NO_MEMORY;
2150 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
2151 if (!NT_STATUS_IS_OK(status)) {
2155 /* Ensure this handle goes away at the end of this call */
2156 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2157 talloc_steal(mem_ctx, h);
2159 query.in.trustdom_handle = opn.out.trustdom_handle;
2160 query.in.level = r->in.level;
2161 query.out.info = r->out.info;
2162 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2163 if (!NT_STATUS_IS_OK(status)) {
2167 return NT_STATUS_OK;
2171 lsa_CloseTrustedDomainEx
2173 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
2174 TALLOC_CTX *mem_ctx,
2175 struct lsa_CloseTrustedDomainEx *r)
2177 /* The result of a bad hair day from an IDL programmer? Not
2178 * implmented in Win2k3. You should always just lsa_Close
2180 return NT_STATUS_NOT_IMPLEMENTED;
2185 comparison function for sorting lsa_DomainInformation array
2187 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
2189 return strcasecmp_m(e1->name.string, e2->name.string);
2195 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2196 struct lsa_EnumTrustDom *r)
2198 struct dcesrv_handle *policy_handle;
2199 struct lsa_DomainInfo *entries;
2200 struct lsa_policy_state *policy_state;
2201 struct ldb_message **domains;
2202 const char *attrs[] = {
2204 "securityIdentifier",
2211 *r->out.resume_handle = 0;
2213 r->out.domains->domains = NULL;
2214 r->out.domains->count = 0;
2216 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2218 policy_state = policy_handle->data;
2220 /* search for all users in this domain. This could possibly be cached and
2221 resumed based on resume_key */
2222 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2223 "objectclass=trustedDomain");
2225 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2228 /* convert to lsa_TrustInformation format */
2229 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
2231 return NT_STATUS_NO_MEMORY;
2233 for (i=0;i<count;i++) {
2234 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
2235 entries[i].name.string = ldb_msg_find_attr_as_string(domains[i], "flatname", NULL);
2238 /* sort the results by name */
2239 TYPESAFE_QSORT(entries, count, compare_DomainInfo);
2241 if (*r->in.resume_handle >= count) {
2242 *r->out.resume_handle = -1;
2244 return NT_STATUS_NO_MORE_ENTRIES;
2247 /* return the rest, limit by max_size. Note that we
2248 use the w2k3 element size value of 60 */
2249 r->out.domains->count = count - *r->in.resume_handle;
2250 r->out.domains->count = MIN(r->out.domains->count,
2251 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
2253 r->out.domains->domains = entries + *r->in.resume_handle;
2254 r->out.domains->count = r->out.domains->count;
2256 if (r->out.domains->count < count - *r->in.resume_handle) {
2257 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2258 return STATUS_MORE_ENTRIES;
2261 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2262 * always be larger than the previous input resume handle, in
2263 * particular when hitting the last query it is vital to set the
2264 * resume handle correctly to avoid infinite client loops, as
2265 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2266 * status is NT_STATUS_OK - gd */
2268 *r->out.resume_handle = (uint32_t)-1;
2270 return NT_STATUS_OK;
2274 comparison function for sorting lsa_DomainInformation array
2276 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
2278 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
2282 lsa_EnumTrustedDomainsEx
2284 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2285 struct lsa_EnumTrustedDomainsEx *r)
2287 struct dcesrv_handle *policy_handle;
2288 struct lsa_TrustDomainInfoInfoEx *entries;
2289 struct lsa_policy_state *policy_state;
2290 struct ldb_message **domains;
2291 const char *attrs[] = {
2294 "securityIdentifier",
2304 *r->out.resume_handle = 0;
2306 r->out.domains->domains = NULL;
2307 r->out.domains->count = 0;
2309 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2311 policy_state = policy_handle->data;
2313 /* search for all users in this domain. This could possibly be cached and
2314 resumed based on resume_key */
2315 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2316 "objectclass=trustedDomain");
2318 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2321 /* convert to lsa_DomainInformation format */
2322 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
2324 return NT_STATUS_NO_MEMORY;
2326 for (i=0;i<count;i++) {
2327 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
2328 if (!NT_STATUS_IS_OK(nt_status)) {
2333 /* sort the results by name */
2334 TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
2336 if (*r->in.resume_handle >= count) {
2337 *r->out.resume_handle = -1;
2339 return NT_STATUS_NO_MORE_ENTRIES;
2342 /* return the rest, limit by max_size. Note that we
2343 use the w2k3 element size value of 60 */
2344 r->out.domains->count = count - *r->in.resume_handle;
2345 r->out.domains->count = MIN(r->out.domains->count,
2346 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
2348 r->out.domains->domains = entries + *r->in.resume_handle;
2349 r->out.domains->count = r->out.domains->count;
2351 if (r->out.domains->count < count - *r->in.resume_handle) {
2352 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2353 return STATUS_MORE_ENTRIES;
2356 return NT_STATUS_OK;
2363 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2364 struct lsa_OpenAccount *r)
2366 struct dcesrv_handle *h, *ah;
2367 struct lsa_policy_state *state;
2368 struct lsa_account_state *astate;
2370 ZERO_STRUCTP(r->out.acct_handle);
2372 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2376 astate = talloc(dce_call->conn, struct lsa_account_state);
2377 if (astate == NULL) {
2378 return NT_STATUS_NO_MEMORY;
2381 astate->account_sid = dom_sid_dup(astate, r->in.sid);
2382 if (astate->account_sid == NULL) {
2383 talloc_free(astate);
2384 return NT_STATUS_NO_MEMORY;
2387 astate->policy = talloc_reference(astate, state);
2388 astate->access_mask = r->in.access_mask;
2390 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
2392 talloc_free(astate);
2393 return NT_STATUS_NO_MEMORY;
2396 ah->data = talloc_steal(ah, astate);
2398 *r->out.acct_handle = ah->wire_handle;
2400 return NT_STATUS_OK;
2405 lsa_EnumPrivsAccount
2407 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
2408 TALLOC_CTX *mem_ctx,
2409 struct lsa_EnumPrivsAccount *r)
2411 struct dcesrv_handle *h;
2412 struct lsa_account_state *astate;
2415 struct ldb_message **res;
2416 const char * const attrs[] = { "privilege", NULL};
2417 struct ldb_message_element *el;
2419 struct lsa_PrivilegeSet *privs;
2421 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2425 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2426 if (privs == NULL) {
2427 return NT_STATUS_NO_MEMORY;
2433 *r->out.privs = privs;
2435 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
2436 if (sidstr == NULL) {
2437 return NT_STATUS_NO_MEMORY;
2440 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
2441 "objectSid=%s", sidstr);
2443 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2446 return NT_STATUS_OK;
2449 el = ldb_msg_find_element(res[0], "privilege");
2450 if (el == NULL || el->num_values == 0) {
2451 return NT_STATUS_OK;
2454 privs->set = talloc_array(privs,
2455 struct lsa_LUIDAttribute, el->num_values);
2456 if (privs->set == NULL) {
2457 return NT_STATUS_NO_MEMORY;
2461 for (i=0;i<el->num_values;i++) {
2462 int id = sec_privilege_id((const char *)el->values[i].data);
2463 if (id == SEC_PRIV_INVALID) {
2464 /* Perhaps an account right, not a privilege */
2467 privs->set[j].attribute = 0;
2468 privs->set[j].luid.low = id;
2469 privs->set[j].luid.high = 0;
2475 return NT_STATUS_OK;
2479 lsa_EnumAccountRights
2481 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
2482 TALLOC_CTX *mem_ctx,
2483 struct lsa_EnumAccountRights *r)
2485 struct dcesrv_handle *h;
2486 struct lsa_policy_state *state;
2489 struct ldb_message **res;
2490 const char * const attrs[] = { "privilege", NULL};
2492 struct ldb_message_element *el;
2494 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2498 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
2499 if (sidstr == NULL) {
2500 return NT_STATUS_NO_MEMORY;
2503 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2504 "(&(objectSid=%s)(privilege=*))", sidstr);
2506 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2509 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
2510 dom_sid_string(mem_ctx, r->in.sid),
2511 ldb_errstring(state->pdb)));
2512 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2515 el = ldb_msg_find_element(res[0], "privilege");
2516 if (el == NULL || el->num_values == 0) {
2517 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2520 r->out.rights->count = el->num_values;
2521 r->out.rights->names = talloc_array(r->out.rights,
2522 struct lsa_StringLarge, r->out.rights->count);
2523 if (r->out.rights->names == NULL) {
2524 return NT_STATUS_NO_MEMORY;
2527 for (i=0;i<el->num_values;i++) {
2528 r->out.rights->names[i].string = (const char *)el->values[i].data;
2531 return NT_STATUS_OK;
2537 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
2539 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
2540 TALLOC_CTX *mem_ctx,
2541 struct lsa_policy_state *state,
2543 struct dom_sid *sid,
2544 const struct lsa_RightSet *rights)
2546 const char *sidstr, *sidndrstr;
2547 struct ldb_message *msg;
2548 struct ldb_message_element *el;
2551 struct lsa_EnumAccountRights r2;
2554 if (security_session_user_level(dce_call->conn->auth_state.session_info, NULL) <
2555 SECURITY_ADMINISTRATOR) {
2556 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
2557 return NT_STATUS_ACCESS_DENIED;
2560 msg = ldb_msg_new(mem_ctx);
2562 return NT_STATUS_NO_MEMORY;
2565 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
2566 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg);
2568 sidstr = dom_sid_string(msg, sid);
2569 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg);
2571 dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
2572 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg);
2574 msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
2575 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg);
2577 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
2580 r2.in.handle = &state->handle->wire_handle;
2582 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
2584 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2585 if (!NT_STATUS_IS_OK(status)) {
2586 ZERO_STRUCTP(r2.out.rights);
2590 for (i=0;i<rights->count;i++) {
2591 if (sec_privilege_id(rights->names[i].string) == SEC_PRIV_INVALID) {
2592 if (sec_right_bit(rights->names[i].string) == 0) {
2594 return NT_STATUS_NO_SUCH_PRIVILEGE;
2598 return NT_STATUS_NO_SUCH_PRIVILEGE;
2601 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
2603 for (j=0;j<r2.out.rights->count;j++) {
2604 if (strcasecmp_m(r2.out.rights->names[j].string,
2605 rights->names[i].string) == 0) {
2609 if (j != r2.out.rights->count) continue;
2612 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2613 if (ret != LDB_SUCCESS) {
2615 return NT_STATUS_NO_MEMORY;
2619 el = ldb_msg_find_element(msg, "privilege");
2622 return NT_STATUS_OK;
2625 el->flags = ldb_flag;
2627 ret = ldb_modify(state->pdb, msg);
2628 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
2629 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
2631 return NT_STATUS_NO_MEMORY;
2633 samdb_msg_add_string(state->pdb, msg, msg, "comment", "added via LSA");
2634 ret = ldb_add(state->pdb, msg);
2636 if (ret != LDB_SUCCESS) {
2637 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2639 return NT_STATUS_OK;
2641 DEBUG(3, ("Could not %s attributes from %s: %s",
2642 LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2643 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
2645 return NT_STATUS_UNEXPECTED_IO_ERROR;
2649 return NT_STATUS_OK;
2653 lsa_AddPrivilegesToAccount
2655 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2656 struct lsa_AddPrivilegesToAccount *r)
2658 struct lsa_RightSet rights;
2659 struct dcesrv_handle *h;
2660 struct lsa_account_state *astate;
2663 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2667 rights.count = r->in.privs->count;
2668 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2669 if (rights.names == NULL) {
2670 return NT_STATUS_NO_MEMORY;
2672 for (i=0;i<rights.count;i++) {
2673 int id = r->in.privs->set[i].luid.low;
2674 if (r->in.privs->set[i].luid.high) {
2675 return NT_STATUS_NO_SUCH_PRIVILEGE;
2677 rights.names[i].string = sec_privilege_name(id);
2678 if (rights.names[i].string == NULL) {
2679 return NT_STATUS_NO_SUCH_PRIVILEGE;
2683 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2684 LDB_FLAG_MOD_ADD, astate->account_sid,
2690 lsa_RemovePrivilegesFromAccount
2692 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2693 struct lsa_RemovePrivilegesFromAccount *r)
2695 struct lsa_RightSet *rights;
2696 struct dcesrv_handle *h;
2697 struct lsa_account_state *astate;
2700 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2704 rights = talloc(mem_ctx, struct lsa_RightSet);
2706 if (r->in.remove_all == 1 &&
2707 r->in.privs == NULL) {
2708 struct lsa_EnumAccountRights r2;
2711 r2.in.handle = &astate->policy->handle->wire_handle;
2712 r2.in.sid = astate->account_sid;
2713 r2.out.rights = rights;
2715 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2716 if (!NT_STATUS_IS_OK(status)) {
2720 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2721 LDB_FLAG_MOD_DELETE, astate->account_sid,
2725 if (r->in.remove_all != 0) {
2726 return NT_STATUS_INVALID_PARAMETER;
2729 rights->count = r->in.privs->count;
2730 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2731 if (rights->names == NULL) {
2732 return NT_STATUS_NO_MEMORY;
2734 for (i=0;i<rights->count;i++) {
2735 int id = r->in.privs->set[i].luid.low;
2736 if (r->in.privs->set[i].luid.high) {
2737 return NT_STATUS_NO_SUCH_PRIVILEGE;
2739 rights->names[i].string = sec_privilege_name(id);
2740 if (rights->names[i].string == NULL) {
2741 return NT_STATUS_NO_SUCH_PRIVILEGE;
2745 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2746 LDB_FLAG_MOD_DELETE, astate->account_sid,
2752 lsa_GetQuotasForAccount
2754 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2755 struct lsa_GetQuotasForAccount *r)
2757 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2762 lsa_SetQuotasForAccount
2764 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2765 struct lsa_SetQuotasForAccount *r)
2767 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2772 lsa_GetSystemAccessAccount
2774 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2775 struct lsa_GetSystemAccessAccount *r)
2777 struct dcesrv_handle *h;
2778 struct lsa_account_state *astate;
2781 struct ldb_message **res;
2782 const char * const attrs[] = { "privilege", NULL};
2783 struct ldb_message_element *el;
2786 *(r->out.access_mask) = 0x00000000;
2788 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2792 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
2793 if (sidstr == NULL) {
2794 return NT_STATUS_NO_MEMORY;
2797 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
2798 "objectSid=%s", sidstr);
2800 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2803 return NT_STATUS_OK;
2806 el = ldb_msg_find_element(res[0], "privilege");
2807 if (el == NULL || el->num_values == 0) {
2808 return NT_STATUS_OK;
2811 for (i=0;i<el->num_values;i++) {
2812 uint32_t right_bit = sec_right_bit((const char *)el->values[i].data);
2813 if (right_bit == 0) {
2814 /* Perhaps an privilege, not a right */
2817 *(r->out.access_mask) |= right_bit;
2820 return NT_STATUS_OK;
2825 lsa_SetSystemAccessAccount
2827 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2828 struct lsa_SetSystemAccessAccount *r)
2830 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2837 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2838 struct lsa_CreateSecret *r)
2840 struct dcesrv_handle *policy_handle;
2841 struct lsa_policy_state *policy_state;
2842 struct lsa_secret_state *secret_state;
2843 struct dcesrv_handle *handle;
2844 struct ldb_message **msgs, *msg;
2845 const char *attrs[] = {
2853 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2854 ZERO_STRUCTP(r->out.sec_handle);
2856 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
2858 case SECURITY_SYSTEM:
2859 case SECURITY_ADMINISTRATOR:
2862 /* Users and annonymous are not allowed create secrets */
2863 return NT_STATUS_ACCESS_DENIED;
2866 policy_state = policy_handle->data;
2868 if (!r->in.name.string) {
2869 return NT_STATUS_INVALID_PARAMETER;
2872 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2873 NT_STATUS_HAVE_NO_MEMORY(secret_state);
2874 secret_state->policy = policy_state;
2876 msg = ldb_msg_new(mem_ctx);
2878 return NT_STATUS_NO_MEMORY;
2881 if (strncmp("G$", r->in.name.string, 2) == 0) {
2884 secret_state->global = true;
2886 name = &r->in.name.string[2];
2887 if (strlen(name) == 0) {
2888 return NT_STATUS_INVALID_PARAMETER;
2891 name2 = talloc_asprintf(mem_ctx, "%s Secret",
2892 ldb_binary_encode_string(mem_ctx, name));
2893 NT_STATUS_HAVE_NO_MEMORY(name2);
2895 /* We need to connect to the database as system, as this is one
2896 * of the rare RPC calls that must read the secrets (and this
2897 * is denied otherwise) */
2898 secret_state->sam_ldb = talloc_reference(secret_state,
2899 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx), 0));
2900 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
2902 /* search for the secret record */
2903 ret = gendb_search(secret_state->sam_ldb,
2904 mem_ctx, policy_state->system_dn, &msgs, attrs,
2905 "(&(cn=%s)(objectclass=secret))",
2908 return NT_STATUS_OBJECT_NAME_COLLISION;
2912 DEBUG(0,("Failure searching for CN=%s: %s\n",
2913 name2, ldb_errstring(secret_state->sam_ldb)));
2914 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2917 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2918 NT_STATUS_HAVE_NO_MEMORY(msg->dn);
2919 if (!ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2920 return NT_STATUS_NO_MEMORY;
2923 ret = ldb_msg_add_string(msg, "cn", name2);
2924 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
2926 secret_state->global = false;
2928 name = r->in.name.string;
2929 if (strlen(name) == 0) {
2930 return NT_STATUS_INVALID_PARAMETER;
2933 secret_state->sam_ldb = talloc_reference(secret_state,
2934 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
2935 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
2937 /* search for the secret record */
2938 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2939 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2941 "(&(cn=%s)(objectclass=secret))",
2942 ldb_binary_encode_string(mem_ctx, name));
2944 return NT_STATUS_OBJECT_NAME_COLLISION;
2948 DEBUG(0,("Failure searching for CN=%s: %s\n",
2949 name, ldb_errstring(secret_state->sam_ldb)));
2950 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2953 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb,
2954 "cn=%s,cn=LSA Secrets", name);
2955 NT_STATUS_HAVE_NO_MEMORY(msg->dn);
2956 ret = ldb_msg_add_string(msg, "cn", name);
2957 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
2960 ret = samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg,
2961 "objectClass", "secret");
2962 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
2964 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2965 NT_STATUS_HAVE_NO_MEMORY(secret_state->secret_dn);
2967 /* create the secret */
2968 ret = ldb_add(secret_state->sam_ldb, msg);
2969 if (ret != LDB_SUCCESS) {
2970 DEBUG(0,("Failed to create secret record %s: %s\n",
2971 ldb_dn_get_linearized(msg->dn),
2972 ldb_errstring(secret_state->sam_ldb)));
2973 return NT_STATUS_ACCESS_DENIED;
2976 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2977 NT_STATUS_HAVE_NO_MEMORY(handle);
2979 handle->data = talloc_steal(handle, secret_state);
2981 secret_state->access_mask = r->in.access_mask;
2982 secret_state->policy = talloc_reference(secret_state, policy_state);
2983 NT_STATUS_HAVE_NO_MEMORY(secret_state->policy);
2985 *r->out.sec_handle = handle->wire_handle;
2987 return NT_STATUS_OK;
2994 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2995 struct lsa_OpenSecret *r)
2997 struct dcesrv_handle *policy_handle;
2999 struct lsa_policy_state *policy_state;
3000 struct lsa_secret_state *secret_state;
3001 struct dcesrv_handle *handle;
3002 struct ldb_message **msgs;
3003 const char *attrs[] = {
3011 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3012 ZERO_STRUCTP(r->out.sec_handle);
3013 policy_state = policy_handle->data;
3015 if (!r->in.name.string) {
3016 return NT_STATUS_INVALID_PARAMETER;
3019 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
3021 case SECURITY_SYSTEM:
3022 case SECURITY_ADMINISTRATOR:
3025 /* Users and annonymous are not allowed to access secrets */
3026 return NT_STATUS_ACCESS_DENIED;
3029 secret_state = talloc(mem_ctx, struct lsa_secret_state);
3030 if (!secret_state) {
3031 return NT_STATUS_NO_MEMORY;
3033 secret_state->policy = policy_state;
3035 if (strncmp("G$", r->in.name.string, 2) == 0) {
3036 name = &r->in.name.string[2];
3037 /* 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) */
3038 secret_state->sam_ldb = talloc_reference(secret_state,
3039 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx), 0));
3040 secret_state->global = true;
3042 if (strlen(name) < 1) {
3043 return NT_STATUS_INVALID_PARAMETER;
3046 /* search for the secret record */
3047 ret = gendb_search(secret_state->sam_ldb,
3048 mem_ctx, policy_state->system_dn, &msgs, attrs,
3049 "(&(cn=%s Secret)(objectclass=secret))",
3050 ldb_binary_encode_string(mem_ctx, name));
3052 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3056 DEBUG(0,("Found %d records matching DN %s\n", ret,
3057 ldb_dn_get_linearized(policy_state->system_dn)));
3058 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3062 secret_state->global = false;
3063 secret_state->sam_ldb = talloc_reference(secret_state,
3064 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
3066 name = r->in.name.string;
3067 if (strlen(name) < 1) {
3068 return NT_STATUS_INVALID_PARAMETER;
3071 /* search for the secret record */
3072 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
3073 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
3075 "(&(cn=%s)(objectclass=secret))",
3076 ldb_binary_encode_string(mem_ctx, name));
3078 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3082 DEBUG(0,("Found %d records matching CN=%s\n",
3083 ret, ldb_binary_encode_string(mem_ctx, name)));
3084 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3088 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
3090 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
3092 return NT_STATUS_NO_MEMORY;
3095 handle->data = talloc_steal(handle, secret_state);
3097 secret_state->access_mask = r->in.access_mask;
3098 secret_state->policy = talloc_reference(secret_state, policy_state);
3100 *r->out.sec_handle = handle->wire_handle;
3102 return NT_STATUS_OK;
3109 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3110 struct lsa_SetSecret *r)
3113 struct dcesrv_handle *h;
3114 struct lsa_secret_state *secret_state;
3115 struct ldb_message *msg;
3116 DATA_BLOB session_key;
3117 DATA_BLOB crypt_secret, secret;
3120 NTSTATUS status = NT_STATUS_OK;
3122 struct timeval now = timeval_current();
3123 NTTIME nt_now = timeval_to_nttime(&now);
3125 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3127 secret_state = h->data;
3129 msg = ldb_msg_new(mem_ctx);
3131 return NT_STATUS_NO_MEMORY;
3134 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
3136 return NT_STATUS_NO_MEMORY;
3138 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
3139 if (!NT_STATUS_IS_OK(status)) {
3143 if (r->in.old_val) {
3145 crypt_secret.data = r->in.old_val->data;
3146 crypt_secret.length = r->in.old_val->size;
3148 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3149 if (!NT_STATUS_IS_OK(status)) {
3153 val.data = secret.data;
3154 val.length = secret.length;
3157 if (ldb_msg_add_value(msg, "priorValue", &val, NULL) != LDB_SUCCESS) {
3158 return NT_STATUS_NO_MEMORY;
3161 /* set old value mtime */
3162 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3163 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3164 return NT_STATUS_NO_MEMORY;
3168 /* If the old value is not set, then migrate the
3169 * current value to the old value */
3170 const struct ldb_val *old_val;
3171 NTTIME last_set_time;
3172 struct ldb_message **res;
3173 const char *attrs[] = {
3179 /* search for the secret record */
3180 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
3181 secret_state->secret_dn, &res, attrs);
3183 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3187 DEBUG(0,("Found %d records matching dn=%s\n", ret,
3188 ldb_dn_get_linearized(secret_state->secret_dn)));
3189 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3192 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3193 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3197 if (ldb_msg_add_value(msg, "priorValue",
3198 old_val, NULL) != LDB_SUCCESS) {
3199 return NT_STATUS_NO_MEMORY;
3202 if (samdb_msg_add_delete(secret_state->sam_ldb,
3203 mem_ctx, msg, "priorValue") != LDB_SUCCESS) {
3204 return NT_STATUS_NO_MEMORY;
3209 /* set old value mtime */
3210 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
3211 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3212 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
3213 return NT_STATUS_NO_MEMORY;
3216 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3217 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3218 return NT_STATUS_NO_MEMORY;
3223 if (r->in.new_val) {
3225 crypt_secret.data = r->in.new_val->data;
3226 crypt_secret.length = r->in.new_val->size;
3228 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3229 if (!NT_STATUS_IS_OK(status)) {
3233 val.data = secret.data;
3234 val.length = secret.length;
3237 if (ldb_msg_add_value(msg, "currentValue", &val, NULL) != LDB_SUCCESS) {
3238 return NT_STATUS_NO_MEMORY;
3241 /* set new value mtime */
3242 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3243 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3244 return NT_STATUS_NO_MEMORY;
3248 /* NULL out the NEW value */
3249 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3250 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3251 return NT_STATUS_NO_MEMORY;
3253 if (samdb_msg_add_delete(secret_state->sam_ldb,
3254 mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
3255 return NT_STATUS_NO_MEMORY;
3259 /* modify the samdb record */
3260 ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
3261 if (ret != LDB_SUCCESS) {
3262 /* we really need samdb.c to return NTSTATUS */
3263 return NT_STATUS_UNSUCCESSFUL;
3266 return NT_STATUS_OK;
3273 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3274 struct lsa_QuerySecret *r)
3276 struct dcesrv_handle *h;
3277 struct lsa_secret_state *secret_state;
3278 struct ldb_message *msg;
3279 DATA_BLOB session_key;
3280 DATA_BLOB crypt_secret, secret;
3282 struct ldb_message **res;
3283 const char *attrs[] = {
3293 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3295 /* Ensure user is permitted to read this... */
3296 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
3298 case SECURITY_SYSTEM:
3299 case SECURITY_ADMINISTRATOR:
3302 /* Users and annonymous are not allowed to read secrets */
3303 return NT_STATUS_ACCESS_DENIED;
3306 secret_state = h->data;
3308 /* pull all the user attributes */
3309 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
3310 secret_state->secret_dn, &res, attrs);
3312 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3316 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
3317 if (!NT_STATUS_IS_OK(nt_status)) {
3321 if (r->in.old_val) {
3322 const struct ldb_val *prior_val;
3323 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3324 if (!r->out.old_val) {
3325 return NT_STATUS_NO_MEMORY;
3327 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
3329 if (prior_val && prior_val->length) {
3330 secret.data = prior_val->data;
3331 secret.length = prior_val->length;
3334 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3335 if (!crypt_secret.length) {
3336 return NT_STATUS_NO_MEMORY;
3338 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3339 if (!r->out.old_val->buf) {
3340 return NT_STATUS_NO_MEMORY;
3342 r->out.old_val->buf->size = crypt_secret.length;
3343 r->out.old_val->buf->length = crypt_secret.length;
3344 r->out.old_val->buf->data = crypt_secret.data;
3348 if (r->in.old_mtime) {
3349 r->out.old_mtime = talloc(mem_ctx, NTTIME);
3350 if (!r->out.old_mtime) {
3351 return NT_STATUS_NO_MEMORY;
3353 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
3356 if (r->in.new_val) {
3357 const struct ldb_val *new_val;
3358 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3359 if (!r->out.new_val) {
3360 return NT_STATUS_NO_MEMORY;
3363 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3365 if (new_val && new_val->length) {
3366 secret.data = new_val->data;
3367 secret.length = new_val->length;
3370 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3371 if (!crypt_secret.length) {
3372 return NT_STATUS_NO_MEMORY;
3374 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3375 if (!r->out.new_val->buf) {
3376 return NT_STATUS_NO_MEMORY;
3378 r->out.new_val->buf->length = crypt_secret.length;
3379 r->out.new_val->buf->size = crypt_secret.length;
3380 r->out.new_val->buf->data = crypt_secret.data;
3384 if (r->in.new_mtime) {
3385 r->out.new_mtime = talloc(mem_ctx, NTTIME);
3386 if (!r->out.new_mtime) {
3387 return NT_STATUS_NO_MEMORY;
3389 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3392 return NT_STATUS_OK;
3399 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
3400 TALLOC_CTX *mem_ctx,
3401 struct lsa_LookupPrivValue *r)
3403 struct dcesrv_handle *h;
3404 struct lsa_policy_state *state;
3407 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3411 id = sec_privilege_id(r->in.name->string);
3412 if (id == SEC_PRIV_INVALID) {
3413 return NT_STATUS_NO_SUCH_PRIVILEGE;
3416 r->out.luid->low = id;
3417 r->out.luid->high = 0;
3419 return NT_STATUS_OK;
3426 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
3427 TALLOC_CTX *mem_ctx,
3428 struct lsa_LookupPrivName *r)
3430 struct dcesrv_handle *h;
3431 struct lsa_policy_state *state;
3432 struct lsa_StringLarge *name;
3433 const char *privname;
3435 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3439 if (r->in.luid->high != 0) {
3440 return NT_STATUS_NO_SUCH_PRIVILEGE;
3443 privname = sec_privilege_name(r->in.luid->low);
3444 if (privname == NULL) {
3445 return NT_STATUS_NO_SUCH_PRIVILEGE;
3448 name = talloc(mem_ctx, struct lsa_StringLarge);
3450 return NT_STATUS_NO_MEMORY;
3453 name->string = privname;
3455 *r->out.name = name;
3457 return NT_STATUS_OK;
3462 lsa_LookupPrivDisplayName
3464 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
3465 TALLOC_CTX *mem_ctx,
3466 struct lsa_LookupPrivDisplayName *r)
3468 struct dcesrv_handle *h;
3469 struct lsa_policy_state *state;
3470 struct lsa_StringLarge *disp_name = NULL;
3471 enum sec_privilege id;
3473 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3477 id = sec_privilege_id(r->in.name->string);
3478 if (id == SEC_PRIV_INVALID) {
3479 return NT_STATUS_NO_SUCH_PRIVILEGE;
3482 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
3483 if (disp_name == NULL) {
3484 return NT_STATUS_NO_MEMORY;
3487 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
3488 if (disp_name->string == NULL) {
3489 return NT_STATUS_INTERNAL_ERROR;
3492 *r->out.disp_name = disp_name;
3493 *r->out.returned_language_id = 0;
3495 return NT_STATUS_OK;
3500 lsa_EnumAccountsWithUserRight
3502 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
3503 TALLOC_CTX *mem_ctx,
3504 struct lsa_EnumAccountsWithUserRight *r)
3506 struct dcesrv_handle *h;
3507 struct lsa_policy_state *state;
3509 struct ldb_message **res;
3510 const char * const attrs[] = { "objectSid", NULL};
3511 const char *privname;
3513 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3517 if (r->in.name == NULL) {
3518 return NT_STATUS_NO_SUCH_PRIVILEGE;
3521 privname = r->in.name->string;
3522 if (sec_privilege_id(privname) == SEC_PRIV_INVALID && sec_right_bit(privname) == 0) {
3523 return NT_STATUS_NO_SUCH_PRIVILEGE;
3526 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
3527 "privilege=%s", privname);
3529 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3532 return NT_STATUS_NO_MORE_ENTRIES;
3535 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
3536 if (r->out.sids->sids == NULL) {
3537 return NT_STATUS_NO_MEMORY;
3539 for (i=0;i<ret;i++) {
3540 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
3541 res[i], "objectSid");
3542 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
3544 r->out.sids->num_sids = ret;
3546 return NT_STATUS_OK;
3551 lsa_AddAccountRights
3553 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
3554 TALLOC_CTX *mem_ctx,
3555 struct lsa_AddAccountRights *r)
3557 struct dcesrv_handle *h;
3558 struct lsa_policy_state *state;
3560 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3564 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3566 r->in.sid, r->in.rights);
3571 lsa_RemoveAccountRights
3573 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
3574 TALLOC_CTX *mem_ctx,
3575 struct lsa_RemoveAccountRights *r)
3577 struct dcesrv_handle *h;
3578 struct lsa_policy_state *state;
3580 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3584 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3585 LDB_FLAG_MOD_DELETE,
3586 r->in.sid, r->in.rights);
3591 lsa_StorePrivateData
3593 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3594 struct lsa_StorePrivateData *r)
3596 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3601 lsa_RetrievePrivateData
3603 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3604 struct lsa_RetrievePrivateData *r)
3606 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3613 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3614 struct lsa_GetUserName *r)
3616 NTSTATUS status = NT_STATUS_OK;
3617 const char *account_name;
3618 const char *authority_name;
3619 struct lsa_String *_account_name;
3620 struct lsa_String *_authority_name = NULL;
3622 /* this is what w2k3 does */
3623 r->out.account_name = r->in.account_name;
3624 r->out.authority_name = r->in.authority_name;
3626 if (r->in.account_name
3627 && *r->in.account_name
3628 /* && *(*r->in.account_name)->string */
3630 return NT_STATUS_INVALID_PARAMETER;
3633 if (r->in.authority_name
3634 && *r->in.authority_name
3635 /* && *(*r->in.authority_name)->string */
3637 return NT_STATUS_INVALID_PARAMETER;
3640 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->info->account_name);
3641 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->info->domain_name);
3643 _account_name = talloc(mem_ctx, struct lsa_String);
3644 NT_STATUS_HAVE_NO_MEMORY(_account_name);
3645 _account_name->string = account_name;
3647 if (r->in.authority_name) {
3648 _authority_name = talloc(mem_ctx, struct lsa_String);
3649 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
3650 _authority_name->string = authority_name;
3653 *r->out.account_name = _account_name;
3654 if (r->out.authority_name) {
3655 *r->out.authority_name = _authority_name;
3664 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
3665 TALLOC_CTX *mem_ctx,
3666 struct lsa_SetInfoPolicy2 *r)
3668 /* need to support these */
3669 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3673 lsa_QueryDomainInformationPolicy
3675 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3676 TALLOC_CTX *mem_ctx,
3677 struct lsa_QueryDomainInformationPolicy *r)
3679 union lsa_DomainInformationPolicy *info;
3681 info = talloc_zero(r->out.info, union lsa_DomainInformationPolicy);
3683 return NT_STATUS_NO_MEMORY;
3686 switch (r->in.level) {
3687 case LSA_DOMAIN_INFO_POLICY_EFS:
3689 *r->out.info = NULL;
3690 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3691 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
3693 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
3694 struct smb_krb5_context *smb_krb5_context;
3695 int ret = smb_krb5_init_context(mem_ctx,
3696 dce_call->event_ctx,
3697 dce_call->conn->dce_ctx->lp_ctx,
3701 *r->out.info = NULL;
3702 return NT_STATUS_INTERNAL_ERROR;
3704 kdc_get_policy(dce_call->conn->dce_ctx->lp_ctx,
3707 talloc_free(smb_krb5_context);
3708 *r->out.info = info;
3709 return NT_STATUS_OK;
3713 *r->out.info = NULL;
3714 return NT_STATUS_INVALID_INFO_CLASS;
3719 lsa_SetDomInfoPolicy
3721 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3722 TALLOC_CTX *mem_ctx,
3723 struct lsa_SetDomainInformationPolicy *r)
3725 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3731 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3732 TALLOC_CTX *mem_ctx,
3733 struct lsa_TestCall *r)
3735 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3741 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3742 struct lsa_CREDRWRITE *r)
3744 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3751 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3752 struct lsa_CREDRREAD *r)
3754 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3761 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3762 struct lsa_CREDRENUMERATE *r)
3764 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3769 lsa_CREDRWRITEDOMAINCREDENTIALS
3771 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3772 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3774 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3779 lsa_CREDRREADDOMAINCREDENTIALS
3781 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3782 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3784 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3791 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3792 struct lsa_CREDRDELETE *r)
3794 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3799 lsa_CREDRGETTARGETINFO
3801 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3802 struct lsa_CREDRGETTARGETINFO *r)
3804 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3809 lsa_CREDRPROFILELOADED
3811 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3812 struct lsa_CREDRPROFILELOADED *r)
3814 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3819 lsa_CREDRGETSESSIONTYPES
3821 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3822 struct lsa_CREDRGETSESSIONTYPES *r)
3824 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3829 lsa_LSARREGISTERAUDITEVENT
3831 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3832 struct lsa_LSARREGISTERAUDITEVENT *r)
3834 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3839 lsa_LSARGENAUDITEVENT
3841 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3842 struct lsa_LSARGENAUDITEVENT *r)
3844 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3849 lsa_LSARUNREGISTERAUDITEVENT
3851 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3852 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3854 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3859 lsa_lsaRQueryForestTrustInformation
3861 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3862 struct lsa_lsaRQueryForestTrustInformation *r)
3864 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3867 #define DNS_CMP_MATCH 0
3868 #define DNS_CMP_FIRST_IS_CHILD 1
3869 #define DNS_CMP_SECOND_IS_CHILD 2
3870 #define DNS_CMP_NO_MATCH 3
3872 /* this function assumes names are well formed DNS names.
3873 * it doesn't validate them */
3874 static int dns_cmp(const char *s1, size_t l1,
3875 const char *s2, size_t l2)
3877 const char *p1, *p2;
3882 if (strcasecmp_m(s1, s2) == 0) {
3883 return DNS_CMP_MATCH;
3885 return DNS_CMP_NO_MATCH;
3893 cret = DNS_CMP_FIRST_IS_CHILD;
3899 cret = DNS_CMP_SECOND_IS_CHILD;
3902 if (p1[t1 - t2 - 1] != '.') {
3903 return DNS_CMP_NO_MATCH;
3906 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
3910 return DNS_CMP_NO_MATCH;
3913 /* decode all TDOs forest trust info blobs */
3914 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3915 struct ldb_message *msg,
3916 struct ForestTrustInfo *info)
3918 const struct ldb_val *ft_blob;
3919 enum ndr_err_code ndr_err;
3921 ft_blob = ldb_msg_find_ldb_val(msg, "msDS-TrustForestTrustInfo");
3922 if (!ft_blob || !ft_blob->data) {
3923 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3925 /* ldb_val is equivalent to DATA_BLOB */
3926 ndr_err = ndr_pull_struct_blob_all(ft_blob, mem_ctx, info,
3927 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3928 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3929 return NT_STATUS_INVALID_DOMAIN_STATE;
3932 return NT_STATUS_OK;
3935 static NTSTATUS own_ft_info(struct lsa_policy_state *ps,
3936 struct ForestTrustInfo *fti)
3938 struct ForestTrustDataDomainInfo *info;
3939 struct ForestTrustInfoRecord *rec;
3943 fti->records = talloc_array(fti,
3944 struct ForestTrustInfoRecordArmor, 2);
3945 if (!fti->records) {
3946 return NT_STATUS_NO_MEMORY;
3950 rec = &fti->records[0].record;
3954 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3956 rec->data.name.string = talloc_strdup(fti, ps->forest_dns);
3957 if (!rec->data.name.string) {
3958 return NT_STATUS_NO_MEMORY;
3960 rec->data.name.size = strlen(rec->data.name.string);
3963 rec = &fti->records[1].record;
3967 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3969 info = &rec->data.info;
3971 info->sid = *ps->domain_sid;
3972 info->dns_name.string = talloc_strdup(fti, ps->domain_dns);
3973 if (!info->dns_name.string) {
3974 return NT_STATUS_NO_MEMORY;
3976 info->dns_name.size = strlen(info->dns_name.string);
3977 info->netbios_name.string = talloc_strdup(fti, ps->domain_name);
3978 if (!info->netbios_name.string) {
3979 return NT_STATUS_NO_MEMORY;
3981 info->netbios_name.size = strlen(info->netbios_name.string);
3983 return NT_STATUS_OK;
3986 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3987 struct lsa_ForestTrustInformation *lfti,
3988 struct ForestTrustInfo *fti)
3990 struct lsa_ForestTrustRecord *lrec;
3991 struct ForestTrustInfoRecord *rec;
3992 struct lsa_StringLarge *tln;
3993 struct lsa_ForestTrustDomainInfo *info;
3997 fti->count = lfti->count;
3998 fti->records = talloc_array(mem_ctx,
3999 struct ForestTrustInfoRecordArmor,
4001 if (!fti->records) {
4002 return NT_STATUS_NO_MEMORY;
4004 for (i = 0; i < fti->count; i++) {
4005 lrec = lfti->entries[i];
4006 rec = &fti->records[i].record;
4008 rec->flags = lrec->flags;
4009 rec->timestamp = lrec->time;
4010 rec->type = lrec->type;
4012 switch (lrec->type) {
4013 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
4014 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4015 tln = &lrec->forest_trust_data.top_level_name;
4016 rec->data.name.string =
4017 talloc_strdup(mem_ctx, tln->string);
4018 if (!rec->data.name.string) {
4019 return NT_STATUS_NO_MEMORY;
4021 rec->data.name.size = strlen(rec->data.name.string);
4023 case LSA_FOREST_TRUST_DOMAIN_INFO:
4024 info = &lrec->forest_trust_data.domain_info;
4025 rec->data.info.sid = *info->domain_sid;
4026 rec->data.info.dns_name.string =
4027 talloc_strdup(mem_ctx,
4028 info->dns_domain_name.string);
4029 if (!rec->data.info.dns_name.string) {
4030 return NT_STATUS_NO_MEMORY;
4032 rec->data.info.dns_name.size =
4033 strlen(rec->data.info.dns_name.string);
4034 rec->data.info.netbios_name.string =
4035 talloc_strdup(mem_ctx,
4036 info->netbios_domain_name.string);
4037 if (!rec->data.info.netbios_name.string) {
4038 return NT_STATUS_NO_MEMORY;
4040 rec->data.info.netbios_name.size =
4041 strlen(rec->data.info.netbios_name.string);
4044 return NT_STATUS_INVALID_DOMAIN_STATE;
4048 return NT_STATUS_OK;
4051 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4052 uint32_t idx, uint32_t collision_type,
4053 uint32_t conflict_type, const char *tdo_name);
4055 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4056 const char *tdo_name,
4057 struct ForestTrustInfo *tdo_fti,
4058 struct ForestTrustInfo *new_fti,
4059 struct lsa_ForestTrustCollisionInfo *c_info)
4061 struct ForestTrustInfoRecord *nrec;
4062 struct ForestTrustInfoRecord *trec;
4063 const char *dns_name;
4064 const char *nb_name;
4065 struct dom_sid *sid;
4071 uint32_t new_fti_idx;
4073 /* use always TDO type, until we understand when Xref can be used */
4074 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
4082 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
4084 nrec = &new_fti->records[new_fti_idx].record;
4086 tln_conflict = false;
4087 sid_conflict = false;
4088 nb_conflict = false;
4091 switch (nrec->type) {
4092 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4093 /* exclusions do not conflict by definition */
4096 case FOREST_TRUST_TOP_LEVEL_NAME:
4097 dns_name = nrec->data.name.string;
4098 dns_len = nrec->data.name.size;
4101 case LSA_FOREST_TRUST_DOMAIN_INFO:
4102 dns_name = nrec->data.info.dns_name.string;
4103 dns_len = nrec->data.info.dns_name.size;
4104 nb_name = nrec->data.info.netbios_name.string;
4105 nb_len = nrec->data.info.netbios_name.size;
4106 sid = &nrec->data.info.sid;
4110 if (!dns_name) continue;
4112 /* check if this is already taken and not excluded */
4113 for (i = 0; i < tdo_fti->count; i++) {
4114 trec = &tdo_fti->records[i].record;
4116 switch (trec->type) {
4117 case FOREST_TRUST_TOP_LEVEL_NAME:
4119 tname = trec->data.name.string;
4120 tlen = trec->data.name.size;
4122 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4124 tname = trec->data.name.string;
4125 tlen = trec->data.name.size;
4127 case FOREST_TRUST_DOMAIN_INFO:
4129 tname = trec->data.info.dns_name.string;
4130 tlen = trec->data.info.dns_name.size;
4132 ret = dns_cmp(dns_name, dns_len, tname, tlen);
4135 /* if it matches exclusion,
4136 * it doesn't conflict */
4142 case DNS_CMP_FIRST_IS_CHILD:
4143 case DNS_CMP_SECOND_IS_CHILD:
4144 tln_conflict = true;
4150 /* explicit exclusion, no dns name conflict here */
4152 tln_conflict = false;
4155 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
4159 /* also test for domain info */
4160 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
4161 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
4162 sid_conflict = true;
4164 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
4165 strcasecmp_m(trec->data.info.netbios_name.string,
4172 nt_status = add_collision(c_info, new_fti_idx,
4174 LSA_TLN_DISABLED_CONFLICT,
4178 nt_status = add_collision(c_info, new_fti_idx,
4180 LSA_SID_DISABLED_CONFLICT,
4184 nt_status = add_collision(c_info, new_fti_idx,
4186 LSA_NB_DISABLED_CONFLICT,
4191 return NT_STATUS_OK;
4194 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4195 uint32_t idx, uint32_t collision_type,
4196 uint32_t conflict_type, const char *tdo_name)
4198 struct lsa_ForestTrustCollisionRecord **es;
4199 uint32_t i = c_info->count;
4201 es = talloc_realloc(c_info, c_info->entries,
4202 struct lsa_ForestTrustCollisionRecord *, i + 1);
4204 return NT_STATUS_NO_MEMORY;
4206 c_info->entries = es;
4207 c_info->count = i + 1;
4209 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4211 return NT_STATUS_NO_MEMORY;
4215 es[i]->type = collision_type;
4216 es[i]->flags.flags = conflict_type;
4217 es[i]->name.string = talloc_strdup(es[i], tdo_name);
4218 if (!es[i]->name.string) {
4219 return NT_STATUS_NO_MEMORY;
4221 es[i]->name.size = strlen(es[i]->name.string);
4223 return NT_STATUS_OK;
4227 lsa_lsaRSetForestTrustInformation
4229 static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_state *dce_call,
4230 TALLOC_CTX *mem_ctx,
4231 struct lsa_lsaRSetForestTrustInformation *r)
4233 struct dcesrv_handle *h;
4234 struct lsa_policy_state *p_state;
4235 const char *trust_attrs[] = { "trustPartner", "trustAttributes",
4236 "msDS-TrustForestTrustInfo", NULL };
4237 struct ldb_message **dom_res = NULL;
4238 struct ldb_dn *tdo_dn;
4239 struct ldb_message *msg;
4241 const char *td_name;
4242 uint32_t trust_attributes;
4243 struct lsa_ForestTrustCollisionInfo *c_info;
4244 struct ForestTrustInfo *nfti;
4245 struct ForestTrustInfo *fti;
4247 enum ndr_err_code ndr_err;
4252 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4256 if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
4257 return NT_STATUS_INVALID_DOMAIN_STATE;
4260 /* abort if we are not a PDC */
4261 if (!samdb_is_pdc(p_state->sam_ldb)) {
4262 return NT_STATUS_INVALID_DOMAIN_ROLE;
4265 ret = samdb_rodc(p_state->sam_ldb, &am_rodc);
4266 if (ret == LDB_SUCCESS && am_rodc) {
4267 return NT_STATUS_NO_SUCH_DOMAIN;
4270 /* check caller has TRUSTED_SET_AUTH */
4272 /* fetch all trusted domain objects */
4273 num_res = gendb_search(p_state->sam_ldb, mem_ctx,
4275 &dom_res, trust_attrs,
4276 "(objectclass=trustedDomain)");
4278 return NT_STATUS_NO_SUCH_DOMAIN;
4281 for (i = 0; i < num_res; i++) {
4282 td_name = ldb_msg_find_attr_as_string(dom_res[i],
4283 "trustPartner", NULL);
4285 return NT_STATUS_INVALID_DOMAIN_STATE;
4287 if (strcasecmp_m(td_name,
4288 r->in.trusted_domain_name->string) == 0) {
4293 return NT_STATUS_NO_SUCH_DOMAIN;
4296 tdo_dn = dom_res[i]->dn;
4298 trust_attributes = ldb_msg_find_attr_as_uint(dom_res[i],
4299 "trustAttributes", 0);
4300 if (!(trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4301 return NT_STATUS_INVALID_PARAMETER;
4304 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4305 return NT_STATUS_INVALID_PARAMETER;
4308 nfti = talloc(mem_ctx, struct ForestTrustInfo);
4310 return NT_STATUS_NO_MEMORY;
4313 nt_status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4314 if (!NT_STATUS_IS_OK(nt_status)) {
4318 c_info = talloc_zero(r->out.collision_info,
4319 struct lsa_ForestTrustCollisionInfo);
4321 return NT_STATUS_NO_MEMORY;
4324 /* first check own info, then other domains */
4325 fti = talloc(mem_ctx, struct ForestTrustInfo);
4327 return NT_STATUS_NO_MEMORY;
4330 nt_status = own_ft_info(p_state, fti);
4331 if (!NT_STATUS_IS_OK(nt_status)) {
4335 nt_status = check_ft_info(c_info, p_state->domain_dns,
4337 if (!NT_STATUS_IS_OK(nt_status)) {
4341 for (i = 0; i < num_res; i++) {
4342 fti = talloc(mem_ctx, struct ForestTrustInfo);
4344 return NT_STATUS_NO_MEMORY;
4347 nt_status = get_ft_info(mem_ctx, dom_res[i], fti);
4348 if (!NT_STATUS_IS_OK(nt_status)) {
4349 if (NT_STATUS_EQUAL(nt_status,
4350 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4356 td_name = ldb_msg_find_attr_as_string(dom_res[i],
4357 "trustPartner", NULL);
4359 return NT_STATUS_INVALID_DOMAIN_STATE;
4362 nt_status = check_ft_info(c_info, td_name, fti, nfti, c_info);
4363 if (!NT_STATUS_IS_OK(nt_status)) {
4368 *r->out.collision_info = c_info;
4370 if (r->in.check_only != 0) {
4371 return NT_STATUS_OK;
4374 /* not just a check, write info back */
4376 ndr_err = ndr_push_struct_blob(&ft_blob, mem_ctx, nfti,
4377 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4378 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4379 return NT_STATUS_INVALID_PARAMETER;
4382 msg = ldb_msg_new(mem_ctx);
4384 return NT_STATUS_NO_MEMORY;
4387 msg->dn = ldb_dn_copy(mem_ctx, tdo_dn);
4389 return NT_STATUS_NO_MEMORY;
4392 ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo",
4393 LDB_FLAG_MOD_REPLACE, NULL);
4394 if (ret != LDB_SUCCESS) {
4395 return NT_STATUS_NO_MEMORY;
4397 ret = ldb_msg_add_value(msg, "msDS-TrustForestTrustInfo",
4399 if (ret != LDB_SUCCESS) {
4400 return NT_STATUS_NO_MEMORY;
4403 ret = ldb_modify(p_state->sam_ldb, msg);
4404 if (ret != LDB_SUCCESS) {
4405 DEBUG(0, ("Failed to store Forest Trust Info: %s\n",
4406 ldb_errstring(p_state->sam_ldb)));
4409 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
4410 return NT_STATUS_ACCESS_DENIED;
4412 return NT_STATUS_INTERNAL_DB_CORRUPTION;
4416 return NT_STATUS_OK;
4422 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4423 struct lsa_CREDRRENAME *r)
4425 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4431 lsa_LSAROPENPOLICYSCE
4433 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4434 struct lsa_LSAROPENPOLICYSCE *r)
4436 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4441 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
4443 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4444 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4446 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4451 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
4453 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4454 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4456 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4461 lsa_LSARADTREPORTSECURITYEVENT
4463 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4464 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4466 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4470 /* include the generated boilerplate */
4471 #include "librpc/gen_ndr/ndr_lsa_s.c"
4475 /*****************************************
4476 NOTE! The remaining calls below were
4477 removed in w2k3, so the DCESRV_FAULT()
4478 replies are the correct implementation. Do
4479 not try and fill these in with anything else
4480 ******************************************/
4483 dssetup_DsRoleDnsNameToFlatName
4485 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4486 struct dssetup_DsRoleDnsNameToFlatName *r)
4488 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4493 dssetup_DsRoleDcAsDc
4495 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4496 struct dssetup_DsRoleDcAsDc *r)
4498 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4503 dssetup_DsRoleDcAsReplica
4505 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4506 struct dssetup_DsRoleDcAsReplica *r)
4508 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4513 dssetup_DsRoleDemoteDc
4515 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4516 struct dssetup_DsRoleDemoteDc *r)
4518 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4523 dssetup_DsRoleGetDcOperationProgress
4525 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4526 struct dssetup_DsRoleGetDcOperationProgress *r)
4528 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4533 dssetup_DsRoleGetDcOperationResults
4535 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4536 struct dssetup_DsRoleGetDcOperationResults *r)
4538 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4543 dssetup_DsRoleCancel
4545 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4546 struct dssetup_DsRoleCancel *r)
4548 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4553 dssetup_DsRoleServerSaveStateForUpgrade
4555 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4556 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
4558 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4563 dssetup_DsRoleUpgradeDownlevelServer
4565 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4566 struct dssetup_DsRoleUpgradeDownlevelServer *r)
4568 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4573 dssetup_DsRoleAbortDownlevelServerUpgrade
4575 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4576 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
4578 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4582 /* include the generated boilerplate */
4583 #include "librpc/gen_ndr/ndr_dssetup_s.c"
4585 NTSTATUS dcerpc_server_lsa_init(void)
4589 ret = dcerpc_server_dssetup_init();
4590 if (!NT_STATUS_IS_OK(ret)) {
4593 ret = dcerpc_server_lsarpc_init();
4594 if (!NT_STATUS_IS_OK(ret)) {