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"
34 this type allows us to distinguish handle types
38 state associated with a lsa_OpenAccount() operation
40 struct lsa_account_state {
41 struct lsa_policy_state *policy;
43 struct dom_sid *account_sid;
48 state associated with a lsa_OpenSecret() operation
50 struct lsa_secret_state {
51 struct lsa_policy_state *policy;
53 struct ldb_dn *secret_dn;
54 struct ldb_context *sam_ldb;
59 state associated with a lsa_OpenTrustedDomain() operation
61 struct lsa_trusted_domain_state {
62 struct lsa_policy_state *policy;
64 struct ldb_dn *trusted_domain_dn;
65 struct ldb_dn *trusted_domain_user_dn;
69 this is based on the samba3 function make_lsa_object_sd()
70 It uses the same logic, but with samba4 helper functions
72 static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
73 struct security_descriptor **sd,
79 struct dom_sid *domain_sid, *domain_admins_sid;
80 const char *domain_admins_sid_str, *sidstr;
81 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
83 status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
84 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
86 domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
87 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid, tmp_ctx);
89 domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
90 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid_str, tmp_ctx);
92 sidstr = dom_sid_string(tmp_ctx, sid);
93 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, tmp_ctx);
95 *sd = security_descriptor_dacl_create(mem_ctx,
99 SEC_ACE_TYPE_ACCESS_ALLOWED,
100 SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,
102 SID_BUILTIN_ADMINISTRATORS,
103 SEC_ACE_TYPE_ACCESS_ALLOWED,
106 SID_BUILTIN_ACCOUNT_OPERATORS,
107 SEC_ACE_TYPE_ACCESS_ALLOWED,
110 domain_admins_sid_str,
111 SEC_ACE_TYPE_ACCESS_ALLOWED,
115 SEC_ACE_TYPE_ACCESS_ALLOWED,
119 talloc_free(tmp_ctx);
121 NT_STATUS_HAVE_NO_MEMORY(*sd);
127 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
129 struct lsa_EnumAccountRights *r);
131 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
133 struct lsa_policy_state *state,
136 const struct lsa_RightSet *rights);
141 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
144 struct dcesrv_handle *h;
146 *r->out.handle = *r->in.handle;
148 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
152 ZERO_STRUCTP(r->out.handle);
161 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
162 struct lsa_Delete *r)
164 return NT_STATUS_NOT_SUPPORTED;
171 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
172 struct lsa_DeleteObject *r)
174 struct dcesrv_handle *h;
177 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
179 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
180 struct lsa_secret_state *secret_state = h->data;
182 /* Ensure user is permitted to delete this... */
183 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
185 case SECURITY_SYSTEM:
186 case SECURITY_ADMINISTRATOR:
189 /* Users and annonymous are not allowed delete things */
190 return NT_STATUS_ACCESS_DENIED;
193 ret = ldb_delete(secret_state->sam_ldb,
194 secret_state->secret_dn);
196 if (ret != LDB_SUCCESS) {
197 return NT_STATUS_INVALID_HANDLE;
200 ZERO_STRUCTP(r->out.handle);
203 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
204 struct lsa_trusted_domain_state *trusted_domain_state =
205 talloc_get_type(h->data, struct lsa_trusted_domain_state);
206 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
207 if (ret != LDB_SUCCESS) {
208 return NT_STATUS_INTERNAL_DB_CORRUPTION;
211 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
212 trusted_domain_state->trusted_domain_dn);
213 if (ret != LDB_SUCCESS) {
214 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
215 return NT_STATUS_INVALID_HANDLE;
218 if (trusted_domain_state->trusted_domain_user_dn) {
219 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
220 trusted_domain_state->trusted_domain_user_dn);
221 if (ret != LDB_SUCCESS) {
222 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
223 return NT_STATUS_INVALID_HANDLE;
227 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
228 if (ret != LDB_SUCCESS) {
229 return NT_STATUS_INTERNAL_DB_CORRUPTION;
232 ZERO_STRUCTP(r->out.handle);
235 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
236 struct lsa_RightSet *rights;
237 struct lsa_account_state *astate;
238 struct lsa_EnumAccountRights r2;
241 rights = talloc(mem_ctx, struct lsa_RightSet);
243 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
247 r2.in.handle = &astate->policy->handle->wire_handle;
248 r2.in.sid = astate->account_sid;
249 r2.out.rights = rights;
251 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
252 but we have a LSA_HANDLE_ACCOUNT here, so this call
254 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
255 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
259 if (!NT_STATUS_IS_OK(status)) {
263 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
264 LDB_FLAG_MOD_DELETE, astate->account_sid,
266 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
270 if (!NT_STATUS_IS_OK(status)) {
274 ZERO_STRUCTP(r->out.handle);
277 return NT_STATUS_INVALID_HANDLE;
284 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
285 struct lsa_EnumPrivs *r)
287 struct dcesrv_handle *h;
288 struct lsa_policy_state *state;
290 const char *privname;
292 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
296 i = *r->in.resume_handle;
299 while ((privname = sec_privilege_name(i)) &&
300 r->out.privs->count < r->in.max_count) {
301 struct lsa_PrivEntry *e;
303 r->out.privs->privs = talloc_realloc(r->out.privs,
305 struct lsa_PrivEntry,
306 r->out.privs->count+1);
307 if (r->out.privs->privs == NULL) {
308 return NT_STATUS_NO_MEMORY;
310 e = &r->out.privs->privs[r->out.privs->count];
313 e->name.string = privname;
314 r->out.privs->count++;
318 *r->out.resume_handle = i;
327 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
328 struct lsa_QuerySecurity *r)
330 struct dcesrv_handle *h;
331 struct security_descriptor *sd;
335 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
337 sid = dce_call->conn->auth_state.session_info->security_token->user_sid;
339 if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
340 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid, 0);
341 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
342 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid,
343 LSA_ACCOUNT_ALL_ACCESS);
345 return NT_STATUS_INVALID_HANDLE;
347 NT_STATUS_NOT_OK_RETURN(status);
349 (*r->out.sdbuf) = talloc(mem_ctx, struct sec_desc_buf);
350 NT_STATUS_HAVE_NO_MEMORY(*r->out.sdbuf);
352 (*r->out.sdbuf)->sd = sd;
361 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
362 struct lsa_SetSecObj *r)
364 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
371 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
372 struct lsa_ChangePassword *r)
374 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
378 dssetup_DsRoleGetPrimaryDomainInformation
380 This is not an LSA call, but is the only call left on the DSSETUP
381 pipe (after the pipe was truncated), and needs lsa_get_policy_state
383 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
385 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
387 union dssetup_DsRoleInfo *info;
389 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
390 W_ERROR_HAVE_NO_MEMORY(info);
392 switch (r->in.level) {
393 case DS_ROLE_BASIC_INFORMATION:
395 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
397 const char *domain = NULL;
398 const char *dns_domain = NULL;
399 const char *forest = NULL;
400 struct GUID domain_guid;
401 struct lsa_policy_state *state;
403 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
404 if (!NT_STATUS_IS_OK(status)) {
405 return ntstatus_to_werror(status);
408 ZERO_STRUCT(domain_guid);
410 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
411 case ROLE_STANDALONE:
412 role = DS_ROLE_STANDALONE_SERVER;
414 case ROLE_DOMAIN_MEMBER:
415 role = DS_ROLE_MEMBER_SERVER;
417 case ROLE_DOMAIN_CONTROLLER:
418 if (samdb_is_pdc(state->sam_ldb)) {
419 role = DS_ROLE_PRIMARY_DC;
421 role = DS_ROLE_BACKUP_DC;
426 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
427 case ROLE_STANDALONE:
428 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
429 W_ERROR_HAVE_NO_MEMORY(domain);
431 case ROLE_DOMAIN_MEMBER:
432 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
433 W_ERROR_HAVE_NO_MEMORY(domain);
434 /* TODO: what is with dns_domain and forest and guid? */
436 case ROLE_DOMAIN_CONTROLLER:
437 flags = DS_ROLE_PRIMARY_DS_RUNNING;
439 if (state->mixed_domain == 1) {
440 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
443 domain = state->domain_name;
444 dns_domain = state->domain_dns;
445 forest = state->forest_dns;
447 domain_guid = state->domain_guid;
448 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
452 info->basic.role = role;
453 info->basic.flags = flags;
454 info->basic.domain = domain;
455 info->basic.dns_domain = dns_domain;
456 info->basic.forest = forest;
457 info->basic.domain_guid = domain_guid;
462 case DS_ROLE_UPGRADE_STATUS:
464 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
465 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
470 case DS_ROLE_OP_STATUS:
472 info->opstatus.status = DS_ROLE_OP_IDLE;
478 return WERR_INVALID_PARAM;
481 return WERR_INVALID_PARAM;
485 fill in the AccountDomain info
487 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
488 struct lsa_DomainInfo *info)
490 info->name.string = state->domain_name;
491 info->sid = state->domain_sid;
497 fill in the DNS domain info
499 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
500 struct lsa_DnsDomainInfo *info)
502 info->name.string = state->domain_name;
503 info->sid = state->domain_sid;
504 info->dns_domain.string = state->domain_dns;
505 info->dns_forest.string = state->forest_dns;
506 info->domain_guid = state->domain_guid;
514 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
515 struct lsa_QueryInfoPolicy2 *r)
517 struct lsa_policy_state *state;
518 struct dcesrv_handle *h;
519 union lsa_PolicyInformation *info;
523 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
527 info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
529 return NT_STATUS_NO_MEMORY;
533 switch (r->in.level) {
534 case LSA_POLICY_INFO_AUDIT_LOG:
535 /* we don't need to fill in any of this */
536 ZERO_STRUCT(info->audit_log);
538 case LSA_POLICY_INFO_AUDIT_EVENTS:
539 /* we don't need to fill in any of this */
540 ZERO_STRUCT(info->audit_events);
542 case LSA_POLICY_INFO_PD:
543 /* we don't need to fill in any of this */
544 ZERO_STRUCT(info->pd);
547 case LSA_POLICY_INFO_DOMAIN:
548 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
549 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
550 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
551 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
552 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
554 case LSA_POLICY_INFO_ROLE:
555 info->role.role = LSA_ROLE_PRIMARY;
558 case LSA_POLICY_INFO_DNS:
559 case LSA_POLICY_INFO_DNS_INT:
560 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
562 case LSA_POLICY_INFO_REPLICA:
563 ZERO_STRUCT(info->replica);
566 case LSA_POLICY_INFO_QUOTA:
567 ZERO_STRUCT(info->quota);
570 case LSA_POLICY_INFO_MOD:
571 case LSA_POLICY_INFO_AUDIT_FULL_SET:
572 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
573 /* windows gives INVALID_PARAMETER */
575 return NT_STATUS_INVALID_PARAMETER;
579 return NT_STATUS_INVALID_INFO_CLASS;
585 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
586 struct lsa_QueryInfoPolicy *r)
588 struct lsa_QueryInfoPolicy2 r2;
593 r2.in.handle = r->in.handle;
594 r2.in.level = r->in.level;
595 r2.out.info = r->out.info;
597 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
605 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
606 struct lsa_SetInfoPolicy *r)
608 /* need to support this */
609 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
616 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
617 struct lsa_ClearAuditLog *r)
619 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
626 This call does not seem to have any long-term effects, hence no database operations
628 we need to talk to the MS product group to find out what this account database means!
630 answer is that the lsa database is totally separate from the SAM and
631 ldap databases. We are going to need a separate ldb to store these
632 accounts. The SIDs on this account bear no relation to the SIDs in
635 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
636 struct lsa_CreateAccount *r)
638 struct lsa_account_state *astate;
640 struct lsa_policy_state *state;
641 struct dcesrv_handle *h, *ah;
643 ZERO_STRUCTP(r->out.acct_handle);
645 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
649 astate = talloc(dce_call->conn, struct lsa_account_state);
650 if (astate == NULL) {
651 return NT_STATUS_NO_MEMORY;
654 astate->account_sid = dom_sid_dup(astate, r->in.sid);
655 if (astate->account_sid == NULL) {
657 return NT_STATUS_NO_MEMORY;
660 astate->policy = talloc_reference(astate, state);
661 astate->access_mask = r->in.access_mask;
663 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
666 return NT_STATUS_NO_MEMORY;
669 ah->data = talloc_steal(ah, astate);
671 *r->out.acct_handle = ah->wire_handle;
680 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
681 struct lsa_EnumAccounts *r)
683 struct dcesrv_handle *h;
684 struct lsa_policy_state *state;
686 struct ldb_message **res;
687 const char * const attrs[] = { "objectSid", NULL};
690 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
694 /* NOTE: This call must only return accounts that have at least
697 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
698 "(&(objectSid=*)(privilege=*))");
700 return NT_STATUS_INTERNAL_DB_CORRUPTION;
703 if (*r->in.resume_handle >= ret) {
704 return NT_STATUS_NO_MORE_ENTRIES;
707 count = ret - *r->in.resume_handle;
708 if (count > r->in.num_entries) {
709 count = r->in.num_entries;
713 return NT_STATUS_NO_MORE_ENTRIES;
716 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
717 if (r->out.sids->sids == NULL) {
718 return NT_STATUS_NO_MEMORY;
721 for (i=0;i<count;i++) {
722 r->out.sids->sids[i].sid =
723 samdb_result_dom_sid(r->out.sids->sids,
724 res[i + *r->in.resume_handle],
726 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
729 r->out.sids->num_sids = count;
730 *r->out.resume_handle = count + *r->in.resume_handle;
736 /* This decrypts and returns Trusted Domain Auth Information Internal data */
737 static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
738 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
739 struct trustDomainPasswords *auth_struct)
741 DATA_BLOB session_key = data_blob(NULL, 0);
742 enum ndr_err_code ndr_err;
745 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
746 if (!NT_STATUS_IS_OK(nt_status)) {
750 arcfour_crypt_blob(auth_blob->data, auth_blob->length, &session_key);
751 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
753 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
754 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
755 return NT_STATUS_INVALID_PARAMETER;
761 static NTSTATUS get_trustauth_inout_blob(struct dcesrv_call_state *dce_call,
763 struct trustCurrentPasswords *iopw,
764 DATA_BLOB *trustauth_blob)
767 struct trustAuthInOutBlob ioblob;
768 enum ndr_err_code ndr_err;
770 ioblob.count = iopw->count;
771 ioblob.current = talloc(mem_ctx,
772 struct AuthenticationInformationArray);
773 if (!ioblob.current) {
774 return NT_STATUS_NO_MEMORY;
777 ioblob.current->array = *iopw->current;
778 if (!ioblob.current->array) {
779 return NT_STATUS_NO_MEMORY;
782 ioblob.previous = talloc(mem_ctx,
783 struct AuthenticationInformationArray);
784 if (!ioblob.previous) {
785 return NT_STATUS_NO_MEMORY;
787 ioblob.previous->array = talloc_array(mem_ctx,
788 struct AuthenticationInformation,
790 if (!ioblob.previous->array) {
791 return NT_STATUS_NO_MEMORY;
794 for (i = 0; i < ioblob.count; i++) {
795 ioblob.previous->array[i].LastUpdateTime = 0;
796 ioblob.previous->array[i].AuthType = 0;
798 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
800 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
801 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
802 return NT_STATUS_INVALID_PARAMETER;
808 static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx,
809 struct ldb_context *sam_ldb,
810 struct ldb_dn *base_dn,
811 const char *netbios_name,
812 struct trustCurrentPasswords *in,
813 struct ldb_dn **user_dn)
815 struct ldb_message *msg;
820 dn = ldb_dn_copy(mem_ctx, base_dn);
822 return NT_STATUS_NO_MEMORY;
824 if (!ldb_dn_add_child_fmt(dn, "cn=%s$,cn=users", netbios_name)) {
825 return NT_STATUS_NO_MEMORY;
828 msg = ldb_msg_new(mem_ctx);
830 return NT_STATUS_NO_MEMORY;
834 ret = ldb_msg_add_string(msg, "objectClass", "user");
835 if (ret != LDB_SUCCESS) {
836 return NT_STATUS_NO_MEMORY;
839 ret = ldb_msg_add_fmt(msg, "samAccountName", "%s$", netbios_name);
840 if (ret != LDB_SUCCESS) {
841 return NT_STATUS_NO_MEMORY;
844 ret = ldb_msg_add_fmt(msg, "userAccountControl", "%u",
845 UF_INTERDOMAIN_TRUST_ACCOUNT);
846 if (ret != LDB_SUCCESS) {
847 return NT_STATUS_NO_MEMORY;
850 for (i = 0; i < in->count; i++) {
851 const char *attribute;
853 switch (in->current[i]->AuthType) {
854 case TRUST_AUTH_TYPE_NT4OWF:
855 attribute = "unicodePwd";
856 v.data = (uint8_t *)&in->current[i]->AuthInfo.nt4owf.password;
859 case TRUST_AUTH_TYPE_CLEAR:
860 attribute = "clearTextPassword";
861 v.data = in->current[i]->AuthInfo.clear.password;
862 v.length = in->current[i]->AuthInfo.clear.size;
868 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
869 if (ret != LDB_SUCCESS) {
870 return NT_STATUS_NO_MEMORY;
874 /* create the trusted_domain user account */
875 ret = ldb_add(sam_ldb, msg);
876 if (ret != LDB_SUCCESS) {
877 DEBUG(0,("Failed to create user record %s: %s\n",
878 ldb_dn_get_linearized(msg->dn),
879 ldb_errstring(sam_ldb)));
882 case LDB_ERR_ENTRY_ALREADY_EXISTS:
883 return NT_STATUS_DOMAIN_EXISTS;
884 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
885 return NT_STATUS_ACCESS_DENIED;
887 return NT_STATUS_INTERNAL_DB_CORRUPTION;
898 lsa_CreateTrustedDomainEx2
900 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
902 struct lsa_CreateTrustedDomainEx2 *r,
905 struct dcesrv_handle *policy_handle;
906 struct lsa_policy_state *policy_state;
907 struct lsa_trusted_domain_state *trusted_domain_state;
908 struct dcesrv_handle *handle;
909 struct ldb_message **msgs, *msg;
910 const char *attrs[] = {
913 const char *netbios_name;
914 const char *dns_name;
916 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
917 struct trustDomainPasswords auth_struct;
920 struct ldb_context *sam_ldb;
922 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
923 ZERO_STRUCTP(r->out.trustdom_handle);
925 policy_state = policy_handle->data;
926 sam_ldb = policy_state->sam_ldb;
928 netbios_name = r->in.info->netbios_name.string;
930 return NT_STATUS_INVALID_PARAMETER;
933 dns_name = r->in.info->domain_name.string;
935 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
936 if (!trusted_domain_state) {
937 return NT_STATUS_NO_MEMORY;
939 trusted_domain_state->policy = policy_state;
941 if (strcasecmp(netbios_name, "BUILTIN") == 0
942 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
943 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
944 return NT_STATUS_INVALID_PARAMETER;
947 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
948 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
949 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
950 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
951 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
952 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
955 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
956 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
957 /* No secrets are created at this time, for this function */
958 auth_struct.outgoing.count = 0;
959 auth_struct.incoming.count = 0;
961 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data,
962 r->in.auth_info->auth_blob.size);
963 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
964 &auth_blob, &auth_struct);
965 if (!NT_STATUS_IS_OK(nt_status)) {
969 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
970 if (auth_struct.incoming.count > 1) {
971 return NT_STATUS_INVALID_PARAMETER;
976 if (auth_struct.incoming.count) {
977 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
978 &auth_struct.incoming,
980 if (!NT_STATUS_IS_OK(nt_status)) {
984 trustAuthIncoming = data_blob(NULL, 0);
987 if (auth_struct.outgoing.count) {
988 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
989 &auth_struct.outgoing,
991 if (!NT_STATUS_IS_OK(nt_status)) {
995 trustAuthOutgoing = data_blob(NULL, 0);
998 ret = ldb_transaction_start(sam_ldb);
999 if (ret != LDB_SUCCESS) {
1000 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1004 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
1005 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
1006 /* search for the trusted_domain record */
1007 ret = gendb_search(sam_ldb,
1008 mem_ctx, policy_state->system_dn, &msgs, attrs,
1009 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
1010 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
1012 ldb_transaction_cancel(sam_ldb);
1013 return NT_STATUS_OBJECT_NAME_COLLISION;
1016 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
1017 /* search for the trusted_domain record */
1018 ret = gendb_search(sam_ldb,
1019 mem_ctx, policy_state->system_dn, &msgs, attrs,
1020 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
1021 netbios_encoded, netbios_encoded, netbios_encoded);
1023 ldb_transaction_cancel(sam_ldb);
1024 return NT_STATUS_OBJECT_NAME_COLLISION;
1029 ldb_transaction_cancel(sam_ldb);
1030 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1033 name = dns_name ? dns_name : netbios_name;
1035 msg = ldb_msg_new(mem_ctx);
1037 return NT_STATUS_NO_MEMORY;
1040 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1041 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
1042 ldb_transaction_cancel(sam_ldb);
1043 return NT_STATUS_NO_MEMORY;
1046 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "flatname", netbios_name);
1048 if (r->in.info->sid) {
1049 ret = samdb_msg_add_dom_sid(sam_ldb, mem_ctx, msg, "securityIdentifier", r->in.info->sid);
1050 if (ret != LDB_SUCCESS) {
1051 ldb_transaction_cancel(sam_ldb);
1052 return NT_STATUS_INVALID_PARAMETER;
1056 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
1058 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
1060 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
1062 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
1065 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
1068 if (trustAuthIncoming.data) {
1069 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
1070 if (ret != LDB_SUCCESS) {
1071 ldb_transaction_cancel(sam_ldb);
1072 return NT_STATUS_NO_MEMORY;
1075 if (trustAuthOutgoing.data) {
1076 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
1077 if (ret != LDB_SUCCESS) {
1078 ldb_transaction_cancel(sam_ldb);
1079 return NT_STATUS_NO_MEMORY;
1083 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
1085 /* create the trusted_domain */
1086 ret = ldb_add(sam_ldb, msg);
1090 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1091 ldb_transaction_cancel(sam_ldb);
1092 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1093 ldb_dn_get_linearized(msg->dn),
1094 ldb_errstring(sam_ldb)));
1095 return NT_STATUS_DOMAIN_EXISTS;
1096 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1097 ldb_transaction_cancel(sam_ldb);
1098 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1099 ldb_dn_get_linearized(msg->dn),
1100 ldb_errstring(sam_ldb)));
1101 return NT_STATUS_ACCESS_DENIED;
1103 ldb_transaction_cancel(sam_ldb);
1104 DEBUG(0,("Failed to create user record %s: %s\n",
1105 ldb_dn_get_linearized(msg->dn),
1106 ldb_errstring(sam_ldb)));
1107 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1110 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1111 struct ldb_dn *user_dn;
1112 /* Inbound trusts must also create a cn=users object to match */
1113 nt_status = add_trust_user(mem_ctx, sam_ldb,
1114 policy_state->domain_dn,
1116 &auth_struct.incoming,
1118 if (!NT_STATUS_IS_OK(nt_status)) {
1119 ldb_transaction_cancel(sam_ldb);
1123 /* save the trust user dn */
1124 trusted_domain_state->trusted_domain_user_dn
1125 = talloc_steal(trusted_domain_state, user_dn);
1128 ret = ldb_transaction_commit(sam_ldb);
1129 if (ret != LDB_SUCCESS) {
1130 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1133 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1135 return NT_STATUS_NO_MEMORY;
1138 handle->data = talloc_steal(handle, trusted_domain_state);
1140 trusted_domain_state->access_mask = r->in.access_mask;
1141 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1143 *r->out.trustdom_handle = handle->wire_handle;
1145 return NT_STATUS_OK;
1149 lsa_CreateTrustedDomainEx2
1151 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1152 TALLOC_CTX *mem_ctx,
1153 struct lsa_CreateTrustedDomainEx2 *r)
1155 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
1158 lsa_CreateTrustedDomainEx
1160 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1161 TALLOC_CTX *mem_ctx,
1162 struct lsa_CreateTrustedDomainEx *r)
1164 struct lsa_CreateTrustedDomainEx2 r2;
1166 r2.in.policy_handle = r->in.policy_handle;
1167 r2.in.info = r->in.info;
1168 r2.in.auth_info = r->in.auth_info;
1169 r2.out.trustdom_handle = r->out.trustdom_handle;
1170 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
1174 lsa_CreateTrustedDomain
1176 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1177 struct lsa_CreateTrustedDomain *r)
1179 struct lsa_CreateTrustedDomainEx2 r2;
1181 r2.in.policy_handle = r->in.policy_handle;
1182 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1184 return NT_STATUS_NO_MEMORY;
1187 r2.in.info->domain_name.string = NULL;
1188 r2.in.info->netbios_name = r->in.info->name;
1189 r2.in.info->sid = r->in.info->sid;
1190 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1191 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1192 r2.in.info->trust_attributes = 0;
1194 r2.in.access_mask = r->in.access_mask;
1195 r2.out.trustdom_handle = r->out.trustdom_handle;
1197 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1202 lsa_OpenTrustedDomain
1204 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1205 struct lsa_OpenTrustedDomain *r)
1207 struct dcesrv_handle *policy_handle;
1209 struct lsa_policy_state *policy_state;
1210 struct lsa_trusted_domain_state *trusted_domain_state;
1211 struct dcesrv_handle *handle;
1212 struct ldb_message **msgs;
1213 const char *attrs[] = {
1219 const char *sid_string;
1222 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1223 ZERO_STRUCTP(r->out.trustdom_handle);
1224 policy_state = policy_handle->data;
1226 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1227 if (!trusted_domain_state) {
1228 return NT_STATUS_NO_MEMORY;
1230 trusted_domain_state->policy = policy_state;
1232 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1234 return NT_STATUS_NO_MEMORY;
1237 /* search for the trusted_domain record */
1238 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1239 mem_ctx, policy_state->system_dn, &msgs, attrs,
1240 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
1243 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1247 DEBUG(0,("Found %d records matching DN %s\n", ret,
1248 ldb_dn_get_linearized(policy_state->system_dn)));
1249 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1252 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1254 trusted_domain_state->trusted_domain_user_dn = NULL;
1256 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1257 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1258 /* search for the trusted_domain record */
1259 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1260 mem_ctx, policy_state->domain_dn, &msgs, attrs,
1261 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%d))",
1262 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1264 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1267 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1269 return NT_STATUS_NO_MEMORY;
1272 handle->data = talloc_steal(handle, trusted_domain_state);
1274 trusted_domain_state->access_mask = r->in.access_mask;
1275 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1277 *r->out.trustdom_handle = handle->wire_handle;
1279 return NT_STATUS_OK;
1284 lsa_OpenTrustedDomainByName
1286 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1287 TALLOC_CTX *mem_ctx,
1288 struct lsa_OpenTrustedDomainByName *r)
1290 struct dcesrv_handle *policy_handle;
1292 struct lsa_policy_state *policy_state;
1293 struct lsa_trusted_domain_state *trusted_domain_state;
1294 struct dcesrv_handle *handle;
1295 struct ldb_message **msgs;
1296 const char *attrs[] = {
1302 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1303 ZERO_STRUCTP(r->out.trustdom_handle);
1304 policy_state = policy_handle->data;
1306 if (!r->in.name.string) {
1307 return NT_STATUS_INVALID_PARAMETER;
1310 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1311 if (!trusted_domain_state) {
1312 return NT_STATUS_NO_MEMORY;
1314 trusted_domain_state->policy = policy_state;
1316 /* search for the trusted_domain record */
1317 td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string);
1318 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1319 mem_ctx, policy_state->system_dn, &msgs, attrs,
1320 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))"
1321 "(objectclass=trustedDomain))",
1322 td_name, td_name, td_name);
1324 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1328 DEBUG(0,("Found %d records matching DN %s\n", ret,
1329 ldb_dn_get_linearized(policy_state->system_dn)));
1330 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1333 /* TODO: perform access checks */
1335 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1337 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1339 return NT_STATUS_NO_MEMORY;
1342 handle->data = talloc_steal(handle, trusted_domain_state);
1344 trusted_domain_state->access_mask = r->in.access_mask;
1345 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1347 *r->out.trustdom_handle = handle->wire_handle;
1349 return NT_STATUS_OK;
1355 lsa_SetTrustedDomainInfo
1357 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1358 struct lsa_SetTrustedDomainInfo *r)
1360 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1365 /* parameters 4 to 6 are optional if the dn is a dn of a TDO object,
1366 * otherwise at least one must be provided */
1367 static NTSTATUS get_tdo(struct ldb_context *sam, TALLOC_CTX *mem_ctx,
1368 struct ldb_dn *basedn, const char *dns_domain,
1369 const char *netbios, struct dom_sid2 *sid,
1370 struct ldb_message ***msgs)
1372 const char *attrs[] = { "flatname", "trustPartner",
1373 "securityIdentifier", "trustDirection",
1374 "trustType", "trustAttributes",
1376 "msDs-supportedEncryptionTypes", NULL };
1379 char *sidstr = NULL;
1384 if (dns_domain || netbios || sid) {
1385 filter = talloc_strdup(mem_ctx,
1386 "(&(objectclass=trustedDomain)(|");
1388 filter = talloc_strdup(mem_ctx,
1389 "(objectclass=trustedDomain)");
1392 return NT_STATUS_NO_MEMORY;
1396 dns = ldb_binary_encode_string(mem_ctx, dns_domain);
1398 return NT_STATUS_NO_MEMORY;
1400 filter = talloc_asprintf_append(filter,
1401 "(trustPartner=%s)", dns);
1403 return NT_STATUS_NO_MEMORY;
1407 nbn = ldb_binary_encode_string(mem_ctx, netbios);
1409 return NT_STATUS_NO_MEMORY;
1411 filter = talloc_asprintf_append(filter,
1412 "(flatname=%s)", nbn);
1414 return NT_STATUS_NO_MEMORY;
1418 sidstr = dom_sid_string(mem_ctx, sid);
1420 return NT_STATUS_INVALID_PARAMETER;
1422 filter = talloc_asprintf_append(filter,
1423 "(securityIdentifier=%s)",
1426 return NT_STATUS_NO_MEMORY;
1429 if (dns_domain || netbios || sid) {
1430 filter = talloc_asprintf_append(filter, "))");
1432 return NT_STATUS_NO_MEMORY;
1436 ret = gendb_search(sam, mem_ctx, basedn, msgs, attrs, "%s", filter);
1438 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1442 return NT_STATUS_OBJECT_NAME_COLLISION;
1445 return NT_STATUS_OK;
1448 static NTSTATUS update_uint32_t_value(TALLOC_CTX *mem_ctx,
1449 struct ldb_message *orig,
1450 struct ldb_message *dest,
1451 const char *attribute,
1453 uint32_t *orig_value)
1455 const struct ldb_val *orig_val;
1456 uint32_t orig_uint = 0;
1461 orig_val = ldb_msg_find_ldb_val(orig, attribute);
1462 if (!orig_val || !orig_val->data) {
1463 /* add new attribute */
1464 flags = LDB_FLAG_MOD_ADD;
1468 orig_uint = strtoul((const char *)orig_val->data, NULL, 0);
1469 if (errno != 0 || orig_uint != value) {
1470 /* replace also if can't get value */
1471 flags = LDB_FLAG_MOD_REPLACE;
1476 /* stored value is identical, nothing to change */
1480 ret = ldb_msg_add_empty(dest, attribute, flags, NULL);
1481 if (ret != LDB_SUCCESS) {
1482 return NT_STATUS_NO_MEMORY;
1485 str_val = talloc_asprintf(mem_ctx, "%u", value);
1487 return NT_STATUS_NO_MEMORY;
1489 ret = ldb_msg_add_steal_string(dest, attribute, str_val);
1490 if (ret != LDB_SUCCESS) {
1491 return NT_STATUS_NO_MEMORY;
1496 *orig_value = orig_uint;
1498 return NT_STATUS_OK;
1501 static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx,
1502 struct ldb_context *sam_ldb,
1503 struct ldb_dn *base_dn,
1505 const char *netbios_name,
1506 struct trustCurrentPasswords *in)
1508 const char *attrs[] = { "userAccountControl", NULL };
1509 struct ldb_message **msgs;
1510 struct ldb_message *msg;
1515 ret = gendb_search(sam_ldb, mem_ctx,
1516 base_dn, &msgs, attrs,
1517 "samAccountName=%s$", netbios_name);
1519 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1524 return NT_STATUS_OK;
1527 /* ok no existing user, add it from scratch */
1528 return add_trust_user(mem_ctx, sam_ldb, base_dn,
1529 netbios_name, in, NULL);
1532 /* check user is what we are looking for */
1533 uac = ldb_msg_find_attr_as_uint(msgs[0],
1534 "userAccountControl", 0);
1535 if (!(uac & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
1536 return NT_STATUS_OBJECT_NAME_COLLISION;
1540 ret = ldb_delete(sam_ldb, msgs[0]->dn);
1543 return NT_STATUS_OK;
1544 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1545 return NT_STATUS_ACCESS_DENIED;
1547 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1551 /* entry exists, just modify secret if any */
1552 if (in->count == 0) {
1553 return NT_STATUS_OK;
1556 msg = ldb_msg_new(mem_ctx);
1558 return NT_STATUS_NO_MEMORY;
1560 msg->dn = msgs[0]->dn;
1562 for (i = 0; i < in->count; i++) {
1563 const char *attribute;
1565 switch (in->current[i]->AuthType) {
1566 case TRUST_AUTH_TYPE_NT4OWF:
1567 attribute = "unicodePwd";
1568 v.data = (uint8_t *)&in->current[i]->AuthInfo.nt4owf.password;
1571 case TRUST_AUTH_TYPE_CLEAR:
1572 attribute = "clearTextPassword";
1573 v.data = in->current[i]->AuthInfo.clear.password;
1574 v.length = in->current[i]->AuthInfo.clear.size;
1580 ret = ldb_msg_add_empty(msg, attribute,
1581 LDB_FLAG_MOD_REPLACE, NULL);
1582 if (ret != LDB_SUCCESS) {
1583 return NT_STATUS_NO_MEMORY;
1586 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
1587 if (ret != LDB_SUCCESS) {
1588 return NT_STATUS_NO_MEMORY;
1592 /* create the trusted_domain user account */
1593 ret = ldb_modify(sam_ldb, msg);
1594 if (ret != LDB_SUCCESS) {
1595 DEBUG(0,("Failed to create user record %s: %s\n",
1596 ldb_dn_get_linearized(msg->dn),
1597 ldb_errstring(sam_ldb)));
1600 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1601 return NT_STATUS_DOMAIN_EXISTS;
1602 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1603 return NT_STATUS_ACCESS_DENIED;
1605 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1609 return NT_STATUS_OK;
1613 static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call,
1614 struct dcesrv_handle *p_handle,
1615 TALLOC_CTX *mem_ctx,
1616 struct ldb_message *dom_msg,
1617 enum lsa_TrustDomInfoEnum level,
1618 union lsa_TrustedDomainInfo *info)
1620 struct lsa_policy_state *p_state = p_handle->data;
1621 uint32_t *posix_offset = NULL;
1622 struct lsa_TrustDomainInfoInfoEx *info_ex = NULL;
1623 struct lsa_TrustDomainInfoAuthInfo *auth_info = NULL;
1624 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
1625 uint32_t *enc_types = NULL;
1626 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
1627 struct trustDomainPasswords auth_struct;
1629 struct ldb_message **msgs;
1630 struct ldb_message *msg;
1631 bool add_outgoing = false;
1632 bool add_incoming = false;
1633 bool del_outgoing = false;
1634 bool del_incoming = false;
1635 bool in_transaction = false;
1640 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1641 posix_offset = &info->posix_offset.posix_offset;
1643 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1644 info_ex = &info->info_ex;
1646 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1647 auth_info = &info->auth_info;
1649 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1650 posix_offset = &info->full_info.posix_offset.posix_offset;
1651 info_ex = &info->full_info.info_ex;
1652 auth_info = &info->full_info.auth_info;
1654 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1655 auth_info_int = &info->auth_info_internal;
1657 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1658 posix_offset = &info->full_info_internal.posix_offset.posix_offset;
1659 info_ex = &info->full_info_internal.info_ex;
1660 auth_info_int = &info->full_info_internal.auth_info;
1662 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1663 enc_types = &info->enc_types.enc_types;
1666 return NT_STATUS_INVALID_PARAMETER;
1670 /* FIXME: not handled yet */
1671 return NT_STATUS_INVALID_PARAMETER;
1674 /* decode auth_info_int if set */
1675 if (auth_info_int) {
1677 /* now decrypt blob */
1678 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
1679 auth_info_int->auth_blob.size);
1681 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
1682 &auth_blob, &auth_struct);
1683 if (!NT_STATUS_IS_OK(nt_status)) {
1689 /* verify data matches */
1690 if (info_ex->trust_attributes &
1691 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1692 /* TODO: check what behavior level we have */
1693 if (strcasecmp_m(p_state->domain_dns,
1694 p_state->forest_dns) != 0) {
1695 return NT_STATUS_INVALID_DOMAIN_STATE;
1699 ret = samdb_rodc(p_state->sam_ldb, &am_rodc);
1700 if (ret == LDB_SUCCESS && am_rodc) {
1701 return NT_STATUS_NO_SUCH_DOMAIN;
1704 /* verify only one object matches the dns/netbios/sid
1705 * triplet and that this is the one we already have */
1706 nt_status = get_tdo(p_state->sam_ldb, mem_ctx,
1708 info_ex->domain_name.string,
1709 info_ex->netbios_name.string,
1710 info_ex->sid, &msgs);
1711 if (!NT_STATUS_IS_OK(nt_status)) {
1714 if (ldb_dn_compare(dom_msg->dn, msgs[0]->dn) != 0) {
1715 return NT_STATUS_OBJECT_NAME_COLLISION;
1720 /* TODO: should we fetch previous values from the existing entry
1721 * and append them ? */
1722 if (auth_struct.incoming.count) {
1723 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1724 &auth_struct.incoming,
1725 &trustAuthIncoming);
1726 if (!NT_STATUS_IS_OK(nt_status)) {
1730 trustAuthIncoming = data_blob(NULL, 0);
1733 if (auth_struct.outgoing.count) {
1734 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1735 &auth_struct.outgoing,
1736 &trustAuthOutgoing);
1737 if (!NT_STATUS_IS_OK(nt_status)) {
1741 trustAuthOutgoing = data_blob(NULL, 0);
1744 msg = ldb_msg_new(mem_ctx);
1746 return NT_STATUS_NO_MEMORY;
1748 msg->dn = dom_msg->dn;
1751 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1753 *posix_offset, NULL);
1754 if (!NT_STATUS_IS_OK(nt_status)) {
1765 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1767 info_ex->trust_direction,
1769 if (!NT_STATUS_IS_OK(nt_status)) {
1773 tmp = info_ex->trust_direction ^ origdir;
1774 if (tmp & LSA_TRUST_DIRECTION_INBOUND) {
1775 if (origdir & LSA_TRUST_DIRECTION_INBOUND) {
1776 del_incoming = true;
1778 add_incoming = true;
1781 if (tmp & LSA_TRUST_DIRECTION_OUTBOUND) {
1782 if (origdir & LSA_TRUST_DIRECTION_OUTBOUND) {
1783 del_outgoing = true;
1785 add_outgoing = true;
1789 origtype = ldb_msg_find_attr_as_int(dom_msg, "trustType", -1);
1790 if (origtype == -1 || origtype != info_ex->trust_type) {
1791 DEBUG(1, ("Attempted to change trust type! "
1792 "Operation not handled\n"));
1793 return NT_STATUS_INVALID_PARAMETER;
1796 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1798 info_ex->trust_attributes,
1800 if (!NT_STATUS_IS_OK(nt_status)) {
1803 /* TODO: check forestFunctionality from ldb opaque */
1804 /* TODO: check what is set makes sense */
1805 /* for now refuse changes */
1806 if (origattrs == -1 ||
1807 origattrs != info_ex->trust_attributes) {
1808 DEBUG(1, ("Attempted to change trust attributes! "
1809 "Operation not handled\n"));
1810 return NT_STATUS_INVALID_PARAMETER;
1815 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1816 "msDS-SupportedEncryptionTypes",
1818 if (!NT_STATUS_IS_OK(nt_status)) {
1823 if (add_incoming && trustAuthIncoming.data) {
1824 ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
1825 LDB_FLAG_MOD_REPLACE, NULL);
1826 if (ret != LDB_SUCCESS) {
1827 return NT_STATUS_NO_MEMORY;
1829 ret = ldb_msg_add_value(msg, "trustAuthIncoming",
1830 &trustAuthIncoming, NULL);
1831 if (ret != LDB_SUCCESS) {
1832 return NT_STATUS_NO_MEMORY;
1835 if (add_outgoing && trustAuthOutgoing.data) {
1836 ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
1837 LDB_FLAG_MOD_REPLACE, NULL);
1838 if (ret != LDB_SUCCESS) {
1839 return NT_STATUS_NO_MEMORY;
1841 ret = ldb_msg_add_value(msg, "trustAuthOutgoing",
1842 &trustAuthOutgoing, NULL);
1843 if (ret != LDB_SUCCESS) {
1844 return NT_STATUS_NO_MEMORY;
1848 /* start transaction */
1849 ret = ldb_transaction_start(p_state->sam_ldb);
1850 if (ret != LDB_SUCCESS) {
1851 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1853 in_transaction = true;
1855 ret = ldb_modify(p_state->sam_ldb, msg);
1856 if (ret != LDB_SUCCESS) {
1857 DEBUG(1,("Failed to modify trusted domain record %s: %s\n",
1858 ldb_dn_get_linearized(msg->dn),
1859 ldb_errstring(p_state->sam_ldb)));
1860 if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
1861 nt_status = NT_STATUS_ACCESS_DENIED;
1863 nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1868 if (add_incoming || del_incoming) {
1869 const char *netbios_name;
1871 netbios_name = ldb_msg_find_attr_as_string(dom_msg,
1873 if (!netbios_name) {
1874 nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
1878 nt_status = update_trust_user(mem_ctx,
1883 &auth_struct.incoming);
1884 if (!NT_STATUS_IS_OK(nt_status)) {
1889 /* ok, all fine, commit transaction and return */
1890 ret = ldb_transaction_commit(p_state->sam_ldb);
1891 if (ret != LDB_SUCCESS) {
1892 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1894 in_transaction = false;
1896 nt_status = NT_STATUS_OK;
1899 if (in_transaction) {
1900 ldb_transaction_cancel(p_state->sam_ldb);
1906 lsa_SetInfomrationTrustedDomain
1908 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(
1909 struct dcesrv_call_state *dce_call,
1910 TALLOC_CTX *mem_ctx,
1911 struct lsa_SetInformationTrustedDomain *r)
1913 struct dcesrv_handle *h;
1914 struct lsa_trusted_domain_state *td_state;
1915 struct ldb_message **msgs;
1918 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle,
1919 LSA_HANDLE_TRUSTED_DOMAIN);
1921 td_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1923 /* get the trusted domain object */
1924 nt_status = get_tdo(td_state->policy->sam_ldb, mem_ctx,
1925 td_state->trusted_domain_dn,
1926 NULL, NULL, NULL, &msgs);
1927 if (!NT_STATUS_IS_OK(nt_status)) {
1928 if (NT_STATUS_EQUAL(nt_status,
1929 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1932 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1935 return setInfoTrustedDomain_base(dce_call, h, mem_ctx,
1936 msgs[0], r->in.level, r->in.info);
1941 lsa_DeleteTrustedDomain
1943 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1944 struct lsa_DeleteTrustedDomain *r)
1947 struct lsa_OpenTrustedDomain opn;
1948 struct lsa_DeleteObject del;
1949 struct dcesrv_handle *h;
1951 opn.in.handle = r->in.handle;
1952 opn.in.sid = r->in.dom_sid;
1953 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1954 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1955 if (!opn.out.trustdom_handle) {
1956 return NT_STATUS_NO_MEMORY;
1958 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1959 if (!NT_STATUS_IS_OK(status)) {
1963 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1964 talloc_steal(mem_ctx, h);
1966 del.in.handle = opn.out.trustdom_handle;
1967 del.out.handle = opn.out.trustdom_handle;
1968 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
1969 if (!NT_STATUS_IS_OK(status)) {
1972 return NT_STATUS_OK;
1975 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1976 struct ldb_message *msg,
1977 struct lsa_TrustDomainInfoInfoEx *info_ex)
1979 info_ex->domain_name.string
1980 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1981 info_ex->netbios_name.string
1982 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1984 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1985 info_ex->trust_direction
1986 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1988 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1989 info_ex->trust_attributes
1990 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1991 return NT_STATUS_OK;
1995 lsa_QueryTrustedDomainInfo
1997 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1998 struct lsa_QueryTrustedDomainInfo *r)
2000 union lsa_TrustedDomainInfo *info = NULL;
2001 struct dcesrv_handle *h;
2002 struct lsa_trusted_domain_state *trusted_domain_state;
2003 struct ldb_message *msg;
2005 struct ldb_message **res;
2006 const char *attrs[] = {
2009 "securityIdentifier",
2013 "msDs-supportedEncryptionTypes",
2017 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
2019 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
2021 /* pull all the user attributes */
2022 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
2023 trusted_domain_state->trusted_domain_dn, &res, attrs);
2025 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2029 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
2031 return NT_STATUS_NO_MEMORY;
2033 *r->out.info = info;
2035 switch (r->in.level) {
2036 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2037 info->name.netbios_name.string
2038 = samdb_result_string(msg, "flatname", NULL);
2040 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2041 info->posix_offset.posix_offset
2042 = samdb_result_uint(msg, "posixOffset", 0);
2044 #if 0 /* Win2k3 doesn't implement this */
2045 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2046 r->out.info->info_basic.netbios_name.string
2047 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2048 r->out.info->info_basic.sid
2049 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
2052 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2053 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
2055 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2056 ZERO_STRUCT(info->full_info);
2057 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
2059 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2060 ZERO_STRUCT(info->full_info2_internal);
2061 info->full_info2_internal.posix_offset.posix_offset
2062 = samdb_result_uint(msg, "posixOffset", 0);
2063 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
2065 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2066 info->enc_types.enc_types
2067 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
2070 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2071 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2072 /* oops, we don't want to return the info after all */
2074 *r->out.info = NULL;
2075 return NT_STATUS_INVALID_PARAMETER;
2077 /* oops, we don't want to return the info after all */
2079 *r->out.info = NULL;
2080 return NT_STATUS_INVALID_INFO_CLASS;
2083 return NT_STATUS_OK;
2088 lsa_QueryTrustedDomainInfoBySid
2090 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2091 struct lsa_QueryTrustedDomainInfoBySid *r)
2094 struct lsa_OpenTrustedDomain opn;
2095 struct lsa_QueryTrustedDomainInfo query;
2096 struct dcesrv_handle *h;
2098 opn.in.handle = r->in.handle;
2099 opn.in.sid = r->in.dom_sid;
2100 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2101 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2102 if (!opn.out.trustdom_handle) {
2103 return NT_STATUS_NO_MEMORY;
2105 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
2106 if (!NT_STATUS_IS_OK(status)) {
2110 /* Ensure this handle goes away at the end of this call */
2111 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2112 talloc_steal(mem_ctx, h);
2114 query.in.trustdom_handle = opn.out.trustdom_handle;
2115 query.in.level = r->in.level;
2116 query.out.info = r->out.info;
2117 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2118 if (!NT_STATUS_IS_OK(status)) {
2122 return NT_STATUS_OK;
2126 lsa_SetTrustedDomainInfoByName
2128 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2129 TALLOC_CTX *mem_ctx,
2130 struct lsa_SetTrustedDomainInfoByName *r)
2132 struct dcesrv_handle *policy_handle;
2133 struct lsa_policy_state *policy_state;
2134 struct ldb_message **msgs;
2137 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2138 policy_state = policy_handle->data;
2140 /* get the trusted domain object */
2141 nt_status = get_tdo(policy_state->sam_ldb, mem_ctx,
2142 policy_state->domain_dn,
2143 r->in.trusted_domain->string,
2144 r->in.trusted_domain->string,
2146 if (!NT_STATUS_IS_OK(nt_status)) {
2147 if (NT_STATUS_EQUAL(nt_status,
2148 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2151 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2154 return setInfoTrustedDomain_base(dce_call, policy_handle, mem_ctx,
2155 msgs[0], r->in.level, r->in.info);
2159 lsa_QueryTrustedDomainInfoByName
2161 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2162 TALLOC_CTX *mem_ctx,
2163 struct lsa_QueryTrustedDomainInfoByName *r)
2166 struct lsa_OpenTrustedDomainByName opn;
2167 struct lsa_QueryTrustedDomainInfo query;
2168 struct dcesrv_handle *h;
2170 opn.in.handle = r->in.handle;
2171 opn.in.name = *r->in.trusted_domain;
2172 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2173 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2174 if (!opn.out.trustdom_handle) {
2175 return NT_STATUS_NO_MEMORY;
2177 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
2178 if (!NT_STATUS_IS_OK(status)) {
2182 /* Ensure this handle goes away at the end of this call */
2183 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2184 talloc_steal(mem_ctx, h);
2186 query.in.trustdom_handle = opn.out.trustdom_handle;
2187 query.in.level = r->in.level;
2188 query.out.info = r->out.info;
2189 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2190 if (!NT_STATUS_IS_OK(status)) {
2194 return NT_STATUS_OK;
2198 lsa_CloseTrustedDomainEx
2200 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
2201 TALLOC_CTX *mem_ctx,
2202 struct lsa_CloseTrustedDomainEx *r)
2204 /* The result of a bad hair day from an IDL programmer? Not
2205 * implmented in Win2k3. You should always just lsa_Close
2207 return NT_STATUS_NOT_IMPLEMENTED;
2212 comparison function for sorting lsa_DomainInformation array
2214 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
2216 return strcasecmp_m(e1->name.string, e2->name.string);
2222 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2223 struct lsa_EnumTrustDom *r)
2225 struct dcesrv_handle *policy_handle;
2226 struct lsa_DomainInfo *entries;
2227 struct lsa_policy_state *policy_state;
2228 struct ldb_message **domains;
2229 const char *attrs[] = {
2231 "securityIdentifier",
2238 *r->out.resume_handle = 0;
2240 r->out.domains->domains = NULL;
2241 r->out.domains->count = 0;
2243 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2245 policy_state = policy_handle->data;
2247 /* search for all users in this domain. This could possibly be cached and
2248 resumed based on resume_key */
2249 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2250 "objectclass=trustedDomain");
2252 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2255 /* convert to lsa_TrustInformation format */
2256 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
2258 return NT_STATUS_NO_MEMORY;
2260 for (i=0;i<count;i++) {
2261 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
2262 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
2265 /* sort the results by name */
2266 TYPESAFE_QSORT(entries, count, compare_DomainInfo);
2268 if (*r->in.resume_handle >= count) {
2269 *r->out.resume_handle = -1;
2271 return NT_STATUS_NO_MORE_ENTRIES;
2274 /* return the rest, limit by max_size. Note that we
2275 use the w2k3 element size value of 60 */
2276 r->out.domains->count = count - *r->in.resume_handle;
2277 r->out.domains->count = MIN(r->out.domains->count,
2278 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
2280 r->out.domains->domains = entries + *r->in.resume_handle;
2281 r->out.domains->count = r->out.domains->count;
2283 if (r->out.domains->count < count - *r->in.resume_handle) {
2284 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2285 return STATUS_MORE_ENTRIES;
2288 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2289 * always be larger than the previous input resume handle, in
2290 * particular when hitting the last query it is vital to set the
2291 * resume handle correctly to avoid infinite client loops, as
2292 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2293 * status is NT_STATUS_OK - gd */
2295 *r->out.resume_handle = (uint32_t)-1;
2297 return NT_STATUS_OK;
2301 comparison function for sorting lsa_DomainInformation array
2303 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
2305 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
2309 lsa_EnumTrustedDomainsEx
2311 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2312 struct lsa_EnumTrustedDomainsEx *r)
2314 struct dcesrv_handle *policy_handle;
2315 struct lsa_TrustDomainInfoInfoEx *entries;
2316 struct lsa_policy_state *policy_state;
2317 struct ldb_message **domains;
2318 const char *attrs[] = {
2321 "securityIdentifier",
2331 *r->out.resume_handle = 0;
2333 r->out.domains->domains = NULL;
2334 r->out.domains->count = 0;
2336 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2338 policy_state = policy_handle->data;
2340 /* search for all users in this domain. This could possibly be cached and
2341 resumed based on resume_key */
2342 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2343 "objectclass=trustedDomain");
2345 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2348 /* convert to lsa_DomainInformation format */
2349 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
2351 return NT_STATUS_NO_MEMORY;
2353 for (i=0;i<count;i++) {
2354 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
2355 if (!NT_STATUS_IS_OK(nt_status)) {
2360 /* sort the results by name */
2361 TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
2363 if (*r->in.resume_handle >= count) {
2364 *r->out.resume_handle = -1;
2366 return NT_STATUS_NO_MORE_ENTRIES;
2369 /* return the rest, limit by max_size. Note that we
2370 use the w2k3 element size value of 60 */
2371 r->out.domains->count = count - *r->in.resume_handle;
2372 r->out.domains->count = MIN(r->out.domains->count,
2373 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
2375 r->out.domains->domains = entries + *r->in.resume_handle;
2376 r->out.domains->count = r->out.domains->count;
2378 if (r->out.domains->count < count - *r->in.resume_handle) {
2379 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2380 return STATUS_MORE_ENTRIES;
2383 return NT_STATUS_OK;
2390 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2391 struct lsa_OpenAccount *r)
2393 struct dcesrv_handle *h, *ah;
2394 struct lsa_policy_state *state;
2395 struct lsa_account_state *astate;
2397 ZERO_STRUCTP(r->out.acct_handle);
2399 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2403 astate = talloc(dce_call->conn, struct lsa_account_state);
2404 if (astate == NULL) {
2405 return NT_STATUS_NO_MEMORY;
2408 astate->account_sid = dom_sid_dup(astate, r->in.sid);
2409 if (astate->account_sid == NULL) {
2410 talloc_free(astate);
2411 return NT_STATUS_NO_MEMORY;
2414 astate->policy = talloc_reference(astate, state);
2415 astate->access_mask = r->in.access_mask;
2417 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
2419 talloc_free(astate);
2420 return NT_STATUS_NO_MEMORY;
2423 ah->data = talloc_steal(ah, astate);
2425 *r->out.acct_handle = ah->wire_handle;
2427 return NT_STATUS_OK;
2432 lsa_EnumPrivsAccount
2434 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
2435 TALLOC_CTX *mem_ctx,
2436 struct lsa_EnumPrivsAccount *r)
2438 struct dcesrv_handle *h;
2439 struct lsa_account_state *astate;
2442 struct ldb_message **res;
2443 const char * const attrs[] = { "privilege", NULL};
2444 struct ldb_message_element *el;
2446 struct lsa_PrivilegeSet *privs;
2448 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2452 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2453 if (privs == NULL) {
2454 return NT_STATUS_NO_MEMORY;
2460 *r->out.privs = privs;
2462 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
2463 if (sidstr == NULL) {
2464 return NT_STATUS_NO_MEMORY;
2467 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
2468 "objectSid=%s", sidstr);
2470 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2473 return NT_STATUS_OK;
2476 el = ldb_msg_find_element(res[0], "privilege");
2477 if (el == NULL || el->num_values == 0) {
2478 return NT_STATUS_OK;
2481 privs->set = talloc_array(privs,
2482 struct lsa_LUIDAttribute, el->num_values);
2483 if (privs->set == NULL) {
2484 return NT_STATUS_NO_MEMORY;
2487 for (i=0;i<el->num_values;i++) {
2488 int id = sec_privilege_id((const char *)el->values[i].data);
2490 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2492 privs->set[i].attribute = 0;
2493 privs->set[i].luid.low = id;
2494 privs->set[i].luid.high = 0;
2497 privs->count = el->num_values;
2499 return NT_STATUS_OK;
2503 lsa_EnumAccountRights
2505 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
2506 TALLOC_CTX *mem_ctx,
2507 struct lsa_EnumAccountRights *r)
2509 struct dcesrv_handle *h;
2510 struct lsa_policy_state *state;
2513 struct ldb_message **res;
2514 const char * const attrs[] = { "privilege", NULL};
2516 struct ldb_message_element *el;
2518 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2522 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
2523 if (sidstr == NULL) {
2524 return NT_STATUS_NO_MEMORY;
2527 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2528 "(&(objectSid=%s)(privilege=*))", sidstr);
2530 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2533 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
2534 dom_sid_string(mem_ctx, r->in.sid),
2535 ldb_errstring(state->pdb)));
2536 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2539 el = ldb_msg_find_element(res[0], "privilege");
2540 if (el == NULL || el->num_values == 0) {
2541 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2544 r->out.rights->count = el->num_values;
2545 r->out.rights->names = talloc_array(r->out.rights,
2546 struct lsa_StringLarge, r->out.rights->count);
2547 if (r->out.rights->names == NULL) {
2548 return NT_STATUS_NO_MEMORY;
2551 for (i=0;i<el->num_values;i++) {
2552 r->out.rights->names[i].string = (const char *)el->values[i].data;
2555 return NT_STATUS_OK;
2561 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
2563 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
2564 TALLOC_CTX *mem_ctx,
2565 struct lsa_policy_state *state,
2567 struct dom_sid *sid,
2568 const struct lsa_RightSet *rights)
2570 const char *sidstr, *sidndrstr;
2571 struct ldb_message *msg;
2572 struct ldb_message_element *el;
2575 struct lsa_EnumAccountRights r2;
2578 if (security_session_user_level(dce_call->conn->auth_state.session_info, NULL) <
2579 SECURITY_ADMINISTRATOR) {
2580 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
2581 return NT_STATUS_ACCESS_DENIED;
2584 msg = ldb_msg_new(mem_ctx);
2586 return NT_STATUS_NO_MEMORY;
2589 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
2590 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg);
2592 sidstr = dom_sid_string(msg, sid);
2593 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg);
2595 dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
2596 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg);
2598 msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
2599 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg);
2601 if (ldb_flag == LDB_FLAG_MOD_ADD) {
2604 r2.in.handle = &state->handle->wire_handle;
2606 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
2608 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2609 if (!NT_STATUS_IS_OK(status)) {
2610 ZERO_STRUCTP(r2.out.rights);
2614 for (i=0;i<rights->count;i++) {
2615 if (sec_privilege_id(rights->names[i].string) == -1) {
2617 return NT_STATUS_NO_SUCH_PRIVILEGE;
2620 if (ldb_flag == LDB_FLAG_MOD_ADD) {
2622 for (j=0;j<r2.out.rights->count;j++) {
2623 if (strcasecmp_m(r2.out.rights->names[j].string,
2624 rights->names[i].string) == 0) {
2628 if (j != r2.out.rights->count) continue;
2631 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2632 if (ret != LDB_SUCCESS) {
2634 return NT_STATUS_NO_MEMORY;
2638 el = ldb_msg_find_element(msg, "privilege");
2641 return NT_STATUS_OK;
2644 el->flags = ldb_flag;
2646 ret = ldb_modify(state->pdb, msg);
2647 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
2648 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
2650 return NT_STATUS_NO_MEMORY;
2652 samdb_msg_add_string(state->pdb, msg, msg, "comment", "added via LSA");
2653 ret = ldb_add(state->pdb, msg);
2655 if (ret != LDB_SUCCESS) {
2656 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2658 return NT_STATUS_OK;
2660 DEBUG(3, ("Could not %s attributes from %s: %s",
2661 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2662 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
2664 return NT_STATUS_UNEXPECTED_IO_ERROR;
2668 return NT_STATUS_OK;
2672 lsa_AddPrivilegesToAccount
2674 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2675 struct lsa_AddPrivilegesToAccount *r)
2677 struct lsa_RightSet rights;
2678 struct dcesrv_handle *h;
2679 struct lsa_account_state *astate;
2682 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2686 rights.count = r->in.privs->count;
2687 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2688 if (rights.names == NULL) {
2689 return NT_STATUS_NO_MEMORY;
2691 for (i=0;i<rights.count;i++) {
2692 int id = r->in.privs->set[i].luid.low;
2693 if (r->in.privs->set[i].luid.high) {
2694 return NT_STATUS_NO_SUCH_PRIVILEGE;
2696 rights.names[i].string = sec_privilege_name(id);
2697 if (rights.names[i].string == NULL) {
2698 return NT_STATUS_NO_SUCH_PRIVILEGE;
2702 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2703 LDB_FLAG_MOD_ADD, astate->account_sid,
2709 lsa_RemovePrivilegesFromAccount
2711 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2712 struct lsa_RemovePrivilegesFromAccount *r)
2714 struct lsa_RightSet *rights;
2715 struct dcesrv_handle *h;
2716 struct lsa_account_state *astate;
2719 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2723 rights = talloc(mem_ctx, struct lsa_RightSet);
2725 if (r->in.remove_all == 1 &&
2726 r->in.privs == NULL) {
2727 struct lsa_EnumAccountRights r2;
2730 r2.in.handle = &astate->policy->handle->wire_handle;
2731 r2.in.sid = astate->account_sid;
2732 r2.out.rights = rights;
2734 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2735 if (!NT_STATUS_IS_OK(status)) {
2739 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2740 LDB_FLAG_MOD_DELETE, astate->account_sid,
2744 if (r->in.remove_all != 0) {
2745 return NT_STATUS_INVALID_PARAMETER;
2748 rights->count = r->in.privs->count;
2749 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2750 if (rights->names == NULL) {
2751 return NT_STATUS_NO_MEMORY;
2753 for (i=0;i<rights->count;i++) {
2754 int id = r->in.privs->set[i].luid.low;
2755 if (r->in.privs->set[i].luid.high) {
2756 return NT_STATUS_NO_SUCH_PRIVILEGE;
2758 rights->names[i].string = sec_privilege_name(id);
2759 if (rights->names[i].string == NULL) {
2760 return NT_STATUS_NO_SUCH_PRIVILEGE;
2764 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2765 LDB_FLAG_MOD_DELETE, astate->account_sid,
2771 lsa_GetQuotasForAccount
2773 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2774 struct lsa_GetQuotasForAccount *r)
2776 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2781 lsa_SetQuotasForAccount
2783 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2784 struct lsa_SetQuotasForAccount *r)
2786 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2791 lsa_GetSystemAccessAccount
2793 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2794 struct lsa_GetSystemAccessAccount *r)
2798 struct lsa_EnumPrivsAccount enumPrivs;
2799 struct lsa_PrivilegeSet *privs;
2801 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2803 return NT_STATUS_NO_MEMORY;
2809 enumPrivs.in.handle = r->in.handle;
2810 enumPrivs.out.privs = &privs;
2812 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2813 if (!NT_STATUS_IS_OK(status)) {
2817 *(r->out.access_mask) = 0x00000000;
2819 for (i = 0; i < privs->count; i++) {
2820 int priv = privs->set[i].luid.low;
2823 case SEC_PRIV_INTERACTIVE_LOGON:
2824 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2826 case SEC_PRIV_NETWORK_LOGON:
2827 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2829 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2830 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2835 return NT_STATUS_OK;
2840 lsa_SetSystemAccessAccount
2842 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2843 struct lsa_SetSystemAccessAccount *r)
2845 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2852 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2853 struct lsa_CreateSecret *r)
2855 struct dcesrv_handle *policy_handle;
2856 struct lsa_policy_state *policy_state;
2857 struct lsa_secret_state *secret_state;
2858 struct dcesrv_handle *handle;
2859 struct ldb_message **msgs, *msg;
2860 const char *attrs[] = {
2868 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2869 ZERO_STRUCTP(r->out.sec_handle);
2871 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
2873 case SECURITY_SYSTEM:
2874 case SECURITY_ADMINISTRATOR:
2877 /* Users and annonymous are not allowed create secrets */
2878 return NT_STATUS_ACCESS_DENIED;
2881 policy_state = policy_handle->data;
2883 if (!r->in.name.string) {
2884 return NT_STATUS_INVALID_PARAMETER;
2887 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2888 if (!secret_state) {
2889 return NT_STATUS_NO_MEMORY;
2891 secret_state->policy = policy_state;
2893 msg = ldb_msg_new(mem_ctx);
2895 return NT_STATUS_NO_MEMORY;
2898 if (strncmp("G$", r->in.name.string, 2) == 0) {
2900 name = &r->in.name.string[2];
2901 /* 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) */
2902 secret_state->sam_ldb = talloc_reference(secret_state,
2903 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
2904 secret_state->global = true;
2906 if (strlen(name) < 1) {
2907 return NT_STATUS_INVALID_PARAMETER;
2910 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2911 /* search for the secret record */
2912 ret = gendb_search(secret_state->sam_ldb,
2913 mem_ctx, policy_state->system_dn, &msgs, attrs,
2914 "(&(cn=%s)(objectclass=secret))",
2917 return NT_STATUS_OBJECT_NAME_COLLISION;
2921 DEBUG(0,("Failure searching for CN=%s: %s\n",
2922 name2, ldb_errstring(secret_state->sam_ldb)));
2923 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2926 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2927 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2928 return NT_STATUS_NO_MEMORY;
2931 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2934 secret_state->global = false;
2936 name = r->in.name.string;
2937 if (strlen(name) < 1) {
2938 return NT_STATUS_INVALID_PARAMETER;
2941 secret_state->sam_ldb = talloc_reference(secret_state,
2942 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2943 /* search for the secret record */
2944 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2945 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2947 "(&(cn=%s)(objectclass=secret))",
2948 ldb_binary_encode_string(mem_ctx, name));
2950 return NT_STATUS_OBJECT_NAME_COLLISION;
2954 DEBUG(0,("Failure searching for CN=%s: %s\n",
2955 name, ldb_errstring(secret_state->sam_ldb)));
2956 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2959 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2960 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2963 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2965 secret_state->secret_dn = talloc_reference(secret_state, msg->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);
2978 return NT_STATUS_NO_MEMORY;
2981 handle->data = talloc_steal(handle, secret_state);
2983 secret_state->access_mask = r->in.access_mask;
2984 secret_state->policy = talloc_reference(secret_state, policy_state);
2986 *r->out.sec_handle = handle->wire_handle;
2988 return NT_STATUS_OK;
2995 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2996 struct lsa_OpenSecret *r)
2998 struct dcesrv_handle *policy_handle;
3000 struct lsa_policy_state *policy_state;
3001 struct lsa_secret_state *secret_state;
3002 struct dcesrv_handle *handle;
3003 struct ldb_message **msgs;
3004 const char *attrs[] = {
3012 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3013 ZERO_STRUCTP(r->out.sec_handle);
3014 policy_state = policy_handle->data;
3016 if (!r->in.name.string) {
3017 return NT_STATUS_INVALID_PARAMETER;
3020 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
3022 case SECURITY_SYSTEM:
3023 case SECURITY_ADMINISTRATOR:
3026 /* Users and annonymous are not allowed to access secrets */
3027 return NT_STATUS_ACCESS_DENIED;
3030 secret_state = talloc(mem_ctx, struct lsa_secret_state);
3031 if (!secret_state) {
3032 return NT_STATUS_NO_MEMORY;
3034 secret_state->policy = policy_state;
3036 if (strncmp("G$", r->in.name.string, 2) == 0) {
3037 name = &r->in.name.string[2];
3038 /* 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) */
3039 secret_state->sam_ldb = talloc_reference(secret_state,
3040 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
3041 secret_state->global = true;
3043 if (strlen(name) < 1) {
3044 return NT_STATUS_INVALID_PARAMETER;
3047 /* search for the secret record */
3048 ret = gendb_search(secret_state->sam_ldb,
3049 mem_ctx, policy_state->system_dn, &msgs, attrs,
3050 "(&(cn=%s Secret)(objectclass=secret))",
3051 ldb_binary_encode_string(mem_ctx, name));
3053 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3057 DEBUG(0,("Found %d records matching DN %s\n", ret,
3058 ldb_dn_get_linearized(policy_state->system_dn)));
3059 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3063 secret_state->global = false;
3064 secret_state->sam_ldb = talloc_reference(secret_state,
3065 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
3067 name = r->in.name.string;
3068 if (strlen(name) < 1) {
3069 return NT_STATUS_INVALID_PARAMETER;
3072 /* search for the secret record */
3073 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
3074 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
3076 "(&(cn=%s)(objectclass=secret))",
3077 ldb_binary_encode_string(mem_ctx, name));
3079 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3083 DEBUG(0,("Found %d records matching CN=%s\n",
3084 ret, ldb_binary_encode_string(mem_ctx, name)));
3085 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3089 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
3091 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
3093 return NT_STATUS_NO_MEMORY;
3096 handle->data = talloc_steal(handle, secret_state);
3098 secret_state->access_mask = r->in.access_mask;
3099 secret_state->policy = talloc_reference(secret_state, policy_state);
3101 *r->out.sec_handle = handle->wire_handle;
3103 return NT_STATUS_OK;
3110 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3111 struct lsa_SetSecret *r)
3114 struct dcesrv_handle *h;
3115 struct lsa_secret_state *secret_state;
3116 struct ldb_message *msg;
3117 DATA_BLOB session_key;
3118 DATA_BLOB crypt_secret, secret;
3121 NTSTATUS status = NT_STATUS_OK;
3123 struct timeval now = timeval_current();
3124 NTTIME nt_now = timeval_to_nttime(&now);
3126 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3128 secret_state = h->data;
3130 msg = ldb_msg_new(mem_ctx);
3132 return NT_STATUS_NO_MEMORY;
3135 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
3137 return NT_STATUS_NO_MEMORY;
3139 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
3140 if (!NT_STATUS_IS_OK(status)) {
3144 if (r->in.old_val) {
3146 crypt_secret.data = r->in.old_val->data;
3147 crypt_secret.length = r->in.old_val->size;
3149 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3150 if (!NT_STATUS_IS_OK(status)) {
3154 val.data = secret.data;
3155 val.length = secret.length;
3158 if (samdb_msg_add_value(secret_state->sam_ldb,
3159 mem_ctx, msg, "priorValue", &val) != LDB_SUCCESS) {
3160 return NT_STATUS_NO_MEMORY;
3163 /* set old value mtime */
3164 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3165 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3166 return NT_STATUS_NO_MEMORY;
3170 /* If the old value is not set, then migrate the
3171 * current value to the old value */
3172 const struct ldb_val *old_val;
3173 NTTIME last_set_time;
3174 struct ldb_message **res;
3175 const char *attrs[] = {
3181 /* search for the secret record */
3182 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
3183 secret_state->secret_dn, &res, attrs);
3185 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3189 DEBUG(0,("Found %d records matching dn=%s\n", ret,
3190 ldb_dn_get_linearized(secret_state->secret_dn)));
3191 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3194 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3195 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3199 if (samdb_msg_add_value(secret_state->sam_ldb,
3200 mem_ctx, msg, "priorValue",
3202 return NT_STATUS_NO_MEMORY;
3205 if (samdb_msg_add_delete(secret_state->sam_ldb,
3206 mem_ctx, msg, "priorValue")) {
3207 return NT_STATUS_NO_MEMORY;
3212 /* set old value mtime */
3213 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
3214 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3215 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
3216 return NT_STATUS_NO_MEMORY;
3219 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3220 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3221 return NT_STATUS_NO_MEMORY;
3226 if (r->in.new_val) {
3228 crypt_secret.data = r->in.new_val->data;
3229 crypt_secret.length = r->in.new_val->size;
3231 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3232 if (!NT_STATUS_IS_OK(status)) {
3236 val.data = secret.data;
3237 val.length = secret.length;
3240 if (samdb_msg_add_value(secret_state->sam_ldb,
3241 mem_ctx, msg, "currentValue", &val) != LDB_SUCCESS) {
3242 return NT_STATUS_NO_MEMORY;
3245 /* set new value mtime */
3246 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3247 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3248 return NT_STATUS_NO_MEMORY;
3252 /* NULL out the NEW value */
3253 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3254 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3255 return NT_STATUS_NO_MEMORY;
3257 if (samdb_msg_add_delete(secret_state->sam_ldb,
3258 mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
3259 return NT_STATUS_NO_MEMORY;
3263 /* modify the samdb record */
3264 ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
3265 if (ret != LDB_SUCCESS) {
3266 /* we really need samdb.c to return NTSTATUS */
3267 return NT_STATUS_UNSUCCESSFUL;
3270 return NT_STATUS_OK;
3277 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3278 struct lsa_QuerySecret *r)
3280 struct dcesrv_handle *h;
3281 struct lsa_secret_state *secret_state;
3282 struct ldb_message *msg;
3283 DATA_BLOB session_key;
3284 DATA_BLOB crypt_secret, secret;
3286 struct ldb_message **res;
3287 const char *attrs[] = {
3297 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3299 /* Ensure user is permitted to read this... */
3300 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
3302 case SECURITY_SYSTEM:
3303 case SECURITY_ADMINISTRATOR:
3306 /* Users and annonymous are not allowed to read secrets */
3307 return NT_STATUS_ACCESS_DENIED;
3310 secret_state = h->data;
3312 /* pull all the user attributes */
3313 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
3314 secret_state->secret_dn, &res, attrs);
3316 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3320 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
3321 if (!NT_STATUS_IS_OK(nt_status)) {
3325 if (r->in.old_val) {
3326 const struct ldb_val *prior_val;
3327 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3328 if (!r->out.old_val) {
3329 return NT_STATUS_NO_MEMORY;
3331 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
3333 if (prior_val && prior_val->length) {
3334 secret.data = prior_val->data;
3335 secret.length = prior_val->length;
3338 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3339 if (!crypt_secret.length) {
3340 return NT_STATUS_NO_MEMORY;
3342 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3343 if (!r->out.old_val->buf) {
3344 return NT_STATUS_NO_MEMORY;
3346 r->out.old_val->buf->size = crypt_secret.length;
3347 r->out.old_val->buf->length = crypt_secret.length;
3348 r->out.old_val->buf->data = crypt_secret.data;
3352 if (r->in.old_mtime) {
3353 r->out.old_mtime = talloc(mem_ctx, NTTIME);
3354 if (!r->out.old_mtime) {
3355 return NT_STATUS_NO_MEMORY;
3357 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
3360 if (r->in.new_val) {
3361 const struct ldb_val *new_val;
3362 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3363 if (!r->out.new_val) {
3364 return NT_STATUS_NO_MEMORY;
3367 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3369 if (new_val && new_val->length) {
3370 secret.data = new_val->data;
3371 secret.length = new_val->length;
3374 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3375 if (!crypt_secret.length) {
3376 return NT_STATUS_NO_MEMORY;
3378 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3379 if (!r->out.new_val->buf) {
3380 return NT_STATUS_NO_MEMORY;
3382 r->out.new_val->buf->length = crypt_secret.length;
3383 r->out.new_val->buf->size = crypt_secret.length;
3384 r->out.new_val->buf->data = crypt_secret.data;
3388 if (r->in.new_mtime) {
3389 r->out.new_mtime = talloc(mem_ctx, NTTIME);
3390 if (!r->out.new_mtime) {
3391 return NT_STATUS_NO_MEMORY;
3393 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3396 return NT_STATUS_OK;
3403 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
3404 TALLOC_CTX *mem_ctx,
3405 struct lsa_LookupPrivValue *r)
3407 struct dcesrv_handle *h;
3408 struct lsa_policy_state *state;
3411 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3415 id = sec_privilege_id(r->in.name->string);
3417 return NT_STATUS_NO_SUCH_PRIVILEGE;
3420 r->out.luid->low = id;
3421 r->out.luid->high = 0;
3423 return NT_STATUS_OK;
3430 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
3431 TALLOC_CTX *mem_ctx,
3432 struct lsa_LookupPrivName *r)
3434 struct dcesrv_handle *h;
3435 struct lsa_policy_state *state;
3436 struct lsa_StringLarge *name;
3437 const char *privname;
3439 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3443 if (r->in.luid->high != 0) {
3444 return NT_STATUS_NO_SUCH_PRIVILEGE;
3447 privname = sec_privilege_name(r->in.luid->low);
3448 if (privname == NULL) {
3449 return NT_STATUS_NO_SUCH_PRIVILEGE;
3452 name = talloc(mem_ctx, struct lsa_StringLarge);
3454 return NT_STATUS_NO_MEMORY;
3457 name->string = privname;
3459 *r->out.name = name;
3461 return NT_STATUS_OK;
3466 lsa_LookupPrivDisplayName
3468 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
3469 TALLOC_CTX *mem_ctx,
3470 struct lsa_LookupPrivDisplayName *r)
3472 struct dcesrv_handle *h;
3473 struct lsa_policy_state *state;
3474 struct lsa_StringLarge *disp_name = NULL;
3477 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3481 id = sec_privilege_id(r->in.name->string);
3483 return NT_STATUS_NO_SUCH_PRIVILEGE;
3486 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
3487 if (disp_name == NULL) {
3488 return NT_STATUS_NO_MEMORY;
3491 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
3492 if (disp_name->string == NULL) {
3493 return NT_STATUS_INTERNAL_ERROR;
3496 *r->out.disp_name = disp_name;
3497 *r->out.returned_language_id = 0;
3499 return NT_STATUS_OK;
3504 lsa_EnumAccountsWithUserRight
3506 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
3507 TALLOC_CTX *mem_ctx,
3508 struct lsa_EnumAccountsWithUserRight *r)
3510 struct dcesrv_handle *h;
3511 struct lsa_policy_state *state;
3513 struct ldb_message **res;
3514 const char * const attrs[] = { "objectSid", NULL};
3515 const char *privname;
3517 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3521 if (r->in.name == NULL) {
3522 return NT_STATUS_NO_SUCH_PRIVILEGE;
3525 privname = r->in.name->string;
3526 if (sec_privilege_id(privname) == -1) {
3527 return NT_STATUS_NO_SUCH_PRIVILEGE;
3530 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
3531 "privilege=%s", privname);
3533 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3536 return NT_STATUS_NO_MORE_ENTRIES;
3539 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
3540 if (r->out.sids->sids == NULL) {
3541 return NT_STATUS_NO_MEMORY;
3543 for (i=0;i<ret;i++) {
3544 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
3545 res[i], "objectSid");
3546 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
3548 r->out.sids->num_sids = ret;
3550 return NT_STATUS_OK;
3555 lsa_AddAccountRights
3557 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
3558 TALLOC_CTX *mem_ctx,
3559 struct lsa_AddAccountRights *r)
3561 struct dcesrv_handle *h;
3562 struct lsa_policy_state *state;
3564 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3568 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3570 r->in.sid, r->in.rights);
3575 lsa_RemoveAccountRights
3577 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
3578 TALLOC_CTX *mem_ctx,
3579 struct lsa_RemoveAccountRights *r)
3581 struct dcesrv_handle *h;
3582 struct lsa_policy_state *state;
3584 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3588 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3589 LDB_FLAG_MOD_DELETE,
3590 r->in.sid, r->in.rights);
3595 lsa_StorePrivateData
3597 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3598 struct lsa_StorePrivateData *r)
3600 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3605 lsa_RetrievePrivateData
3607 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3608 struct lsa_RetrievePrivateData *r)
3610 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3617 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3618 struct lsa_GetUserName *r)
3620 NTSTATUS status = NT_STATUS_OK;
3621 const char *account_name;
3622 const char *authority_name;
3623 struct lsa_String *_account_name;
3624 struct lsa_String *_authority_name = NULL;
3626 /* this is what w2k3 does */
3627 r->out.account_name = r->in.account_name;
3628 r->out.authority_name = r->in.authority_name;
3630 if (r->in.account_name
3631 && *r->in.account_name
3632 /* && *(*r->in.account_name)->string */
3634 return NT_STATUS_INVALID_PARAMETER;
3637 if (r->in.authority_name
3638 && *r->in.authority_name
3639 /* && *(*r->in.authority_name)->string */
3641 return NT_STATUS_INVALID_PARAMETER;
3644 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
3645 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
3647 _account_name = talloc(mem_ctx, struct lsa_String);
3648 NT_STATUS_HAVE_NO_MEMORY(_account_name);
3649 _account_name->string = account_name;
3651 if (r->in.authority_name) {
3652 _authority_name = talloc(mem_ctx, struct lsa_String);
3653 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
3654 _authority_name->string = authority_name;
3657 *r->out.account_name = _account_name;
3658 if (r->out.authority_name) {
3659 *r->out.authority_name = _authority_name;
3668 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
3669 TALLOC_CTX *mem_ctx,
3670 struct lsa_SetInfoPolicy2 *r)
3672 /* need to support these */
3673 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3677 lsa_QueryDomainInformationPolicy
3679 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3680 TALLOC_CTX *mem_ctx,
3681 struct lsa_QueryDomainInformationPolicy *r)
3683 union lsa_DomainInformationPolicy *info;
3685 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
3687 return NT_STATUS_NO_MEMORY;
3690 switch (r->in.level) {
3691 case LSA_DOMAIN_INFO_POLICY_EFS:
3693 *r->out.info = NULL;
3694 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3695 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
3697 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
3698 struct smb_krb5_context *smb_krb5_context;
3699 int ret = smb_krb5_init_context(mem_ctx,
3700 dce_call->event_ctx,
3701 dce_call->conn->dce_ctx->lp_ctx,
3705 *r->out.info = NULL;
3706 return NT_STATUS_INTERNAL_ERROR;
3708 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
3709 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3710 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3711 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
3712 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
3713 talloc_free(smb_krb5_context);
3714 *r->out.info = info;
3715 return NT_STATUS_OK;
3719 *r->out.info = NULL;
3720 return NT_STATUS_INVALID_INFO_CLASS;
3725 lsa_SetDomInfoPolicy
3727 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3728 TALLOC_CTX *mem_ctx,
3729 struct lsa_SetDomainInformationPolicy *r)
3731 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3737 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3738 TALLOC_CTX *mem_ctx,
3739 struct lsa_TestCall *r)
3741 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3747 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3748 struct lsa_CREDRWRITE *r)
3750 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3757 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3758 struct lsa_CREDRREAD *r)
3760 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3767 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3768 struct lsa_CREDRENUMERATE *r)
3770 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3775 lsa_CREDRWRITEDOMAINCREDENTIALS
3777 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3778 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3780 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3785 lsa_CREDRREADDOMAINCREDENTIALS
3787 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3788 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3790 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3797 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3798 struct lsa_CREDRDELETE *r)
3800 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3805 lsa_CREDRGETTARGETINFO
3807 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3808 struct lsa_CREDRGETTARGETINFO *r)
3810 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3815 lsa_CREDRPROFILELOADED
3817 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3818 struct lsa_CREDRPROFILELOADED *r)
3820 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3825 lsa_CREDRGETSESSIONTYPES
3827 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3828 struct lsa_CREDRGETSESSIONTYPES *r)
3830 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3835 lsa_LSARREGISTERAUDITEVENT
3837 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3838 struct lsa_LSARREGISTERAUDITEVENT *r)
3840 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3845 lsa_LSARGENAUDITEVENT
3847 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3848 struct lsa_LSARGENAUDITEVENT *r)
3850 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3855 lsa_LSARUNREGISTERAUDITEVENT
3857 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3858 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3860 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3865 lsa_lsaRQueryForestTrustInformation
3867 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3868 struct lsa_lsaRQueryForestTrustInformation *r)
3870 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3873 #define DNS_CMP_MATCH 0
3874 #define DNS_CMP_FIRST_IS_CHILD 1
3875 #define DNS_CMP_SECOND_IS_CHILD 2
3876 #define DNS_CMP_NO_MATCH 3
3878 /* this function assumes names are well formed DNS names.
3879 * it doesn't validate them */
3880 static int dns_cmp(const char *s1, size_t l1,
3881 const char *s2, size_t l2)
3883 const char *p1, *p2;
3888 if (strcasecmp_m(s1, s2) == 0) {
3889 return DNS_CMP_MATCH;
3891 return DNS_CMP_NO_MATCH;
3899 cret = DNS_CMP_FIRST_IS_CHILD;
3905 cret = DNS_CMP_SECOND_IS_CHILD;
3908 if (p1[t1 - t2 - 1] != '.') {
3909 return DNS_CMP_NO_MATCH;
3912 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
3916 return DNS_CMP_NO_MATCH;
3919 /* decode all TDOs forest trust info blobs */
3920 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3921 struct ldb_message *msg,
3922 struct ForestTrustInfo *info)
3924 const struct ldb_val *ft_blob;
3925 enum ndr_err_code ndr_err;
3927 ft_blob = ldb_msg_find_ldb_val(msg, "msDS-TrustForestTrustInfo");
3928 if (!ft_blob || !ft_blob->data) {
3929 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3931 /* ldb_val is equivalent to DATA_BLOB */
3932 ndr_err = ndr_pull_struct_blob_all(ft_blob, mem_ctx, info,
3933 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3934 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3935 return NT_STATUS_INVALID_DOMAIN_STATE;
3938 return NT_STATUS_OK;
3941 static NTSTATUS own_ft_info(struct lsa_policy_state *ps,
3942 struct ForestTrustInfo *fti)
3944 struct ForestTrustDataDomainInfo *info;
3945 struct ForestTrustInfoRecord *rec;
3949 fti->records = talloc_array(fti,
3950 struct ForestTrustInfoRecordArmor, 2);
3951 if (!fti->records) {
3952 return NT_STATUS_NO_MEMORY;
3956 rec = &fti->records[0].record;
3960 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3962 rec->data.name.string = talloc_strdup(fti, ps->forest_dns);
3963 if (!rec->data.name.string) {
3964 return NT_STATUS_NO_MEMORY;
3966 rec->data.name.size = strlen(rec->data.name.string);
3969 rec = &fti->records[1].record;
3973 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3975 info = &rec->data.info;
3977 info->sid = *ps->domain_sid;
3978 info->dns_name.string = talloc_strdup(fti, ps->domain_dns);
3979 if (!info->dns_name.string) {
3980 return NT_STATUS_NO_MEMORY;
3982 info->dns_name.size = strlen(info->dns_name.string);
3983 info->netbios_name.string = talloc_strdup(fti, ps->domain_name);
3984 if (!info->netbios_name.string) {
3985 return NT_STATUS_NO_MEMORY;
3987 info->netbios_name.size = strlen(info->netbios_name.string);
3989 return NT_STATUS_OK;
3992 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3993 struct lsa_ForestTrustInformation *lfti,
3994 struct ForestTrustInfo *fti)
3996 struct lsa_ForestTrustRecord *lrec;
3997 struct ForestTrustInfoRecord *rec;
3998 struct lsa_StringLarge *tln;
3999 struct lsa_ForestTrustDomainInfo *info;
4003 fti->count = lfti->count;
4004 fti->records = talloc_array(mem_ctx,
4005 struct ForestTrustInfoRecordArmor,
4007 if (!fti->records) {
4008 return NT_STATUS_NO_MEMORY;
4010 for (i = 0; i < fti->count; i++) {
4011 lrec = lfti->entries[i];
4012 rec = &fti->records[i].record;
4014 rec->flags = lrec->flags;
4015 rec->timestamp = lrec->time;
4016 rec->type = lrec->type;
4018 switch (lrec->type) {
4019 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
4020 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4021 tln = &lrec->forest_trust_data.top_level_name;
4022 rec->data.name.string =
4023 talloc_strdup(mem_ctx, tln->string);
4024 if (!rec->data.name.string) {
4025 return NT_STATUS_NO_MEMORY;
4027 rec->data.name.size = strlen(rec->data.name.string);
4029 case LSA_FOREST_TRUST_DOMAIN_INFO:
4030 info = &lrec->forest_trust_data.domain_info;
4031 rec->data.info.sid = *info->domain_sid;
4032 rec->data.info.dns_name.string =
4033 talloc_strdup(mem_ctx,
4034 info->dns_domain_name.string);
4035 if (!rec->data.info.dns_name.string) {
4036 return NT_STATUS_NO_MEMORY;
4038 rec->data.info.dns_name.size =
4039 strlen(rec->data.info.dns_name.string);
4040 rec->data.info.netbios_name.string =
4041 talloc_strdup(mem_ctx,
4042 info->netbios_domain_name.string);
4043 if (!rec->data.info.netbios_name.string) {
4044 return NT_STATUS_NO_MEMORY;
4046 rec->data.info.netbios_name.size =
4047 strlen(rec->data.info.netbios_name.string);
4050 return NT_STATUS_INVALID_DOMAIN_STATE;
4054 return NT_STATUS_OK;
4057 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4058 uint32_t index, uint32_t collision_type,
4059 uint32_t conflict_type, const char *tdo_name);
4061 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4062 const char *tdo_name,
4063 struct ForestTrustInfo *tdo_fti,
4064 struct ForestTrustInfo *new_fti,
4065 struct lsa_ForestTrustCollisionInfo *c_info)
4067 struct ForestTrustInfoRecord *nrec;
4068 struct ForestTrustInfoRecord *trec;
4069 const char *dns_name;
4070 const char *nb_name;
4071 struct dom_sid *sid;
4077 uint32_t new_fti_idx;
4079 /* use always TDO type, until we understand when Xref can be used */
4080 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
4088 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
4090 nrec = &new_fti->records[new_fti_idx].record;
4092 tln_conflict = false;
4093 sid_conflict = false;
4094 nb_conflict = false;
4097 switch (nrec->type) {
4098 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4099 /* exclusions do not conflict by definition */
4102 case FOREST_TRUST_TOP_LEVEL_NAME:
4103 dns_name = nrec->data.name.string;
4104 dns_len = nrec->data.name.size;
4107 case LSA_FOREST_TRUST_DOMAIN_INFO:
4108 dns_name = nrec->data.info.dns_name.string;
4109 dns_len = nrec->data.info.dns_name.size;
4110 nb_name = nrec->data.info.netbios_name.string;
4111 nb_len = nrec->data.info.netbios_name.size;
4112 sid = &nrec->data.info.sid;
4116 if (!dns_name) continue;
4118 /* check if this is already taken and not excluded */
4119 for (i = 0; i < tdo_fti->count; i++) {
4120 trec = &tdo_fti->records[i].record;
4122 switch (trec->type) {
4123 case FOREST_TRUST_TOP_LEVEL_NAME:
4125 tname = trec->data.name.string;
4126 tlen = trec->data.name.size;
4128 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4130 tname = trec->data.name.string;
4131 tlen = trec->data.name.size;
4133 case FOREST_TRUST_DOMAIN_INFO:
4135 tname = trec->data.info.dns_name.string;
4136 tlen = trec->data.info.dns_name.size;
4138 ret = dns_cmp(dns_name, dns_len, tname, tlen);
4141 /* if it matches exclusion,
4142 * it doesn't conflict */
4148 case DNS_CMP_FIRST_IS_CHILD:
4149 case DNS_CMP_SECOND_IS_CHILD:
4150 tln_conflict = true;
4156 /* explicit exclusion, no dns name conflict here */
4158 tln_conflict = false;
4161 if (nrec->type != FOREST_TRUST_DOMAIN_INFO) {
4165 /* also test for domain info */
4166 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
4167 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
4168 sid_conflict = true;
4170 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
4171 strcasecmp_m(trec->data.info.netbios_name.string,
4178 nt_status = add_collision(c_info, new_fti_idx,
4180 LSA_TLN_DISABLED_CONFLICT,
4184 nt_status = add_collision(c_info, new_fti_idx,
4186 LSA_SID_DISABLED_CONFLICT,
4190 nt_status = add_collision(c_info, new_fti_idx,
4192 LSA_NB_DISABLED_CONFLICT,
4197 return NT_STATUS_OK;
4200 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4201 uint32_t idx, uint32_t collision_type,
4202 uint32_t conflict_type, const char *tdo_name)
4204 struct lsa_ForestTrustCollisionRecord **es;
4205 uint32_t i = c_info->count;
4207 es = talloc_realloc(c_info, c_info->entries,
4208 struct lsa_ForestTrustCollisionRecord *, i + 1);
4210 return NT_STATUS_NO_MEMORY;
4212 c_info->entries = es;
4213 c_info->count = i + 1;
4215 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4217 return NT_STATUS_NO_MEMORY;
4221 es[i]->type = collision_type;
4222 es[i]->flags.flags = conflict_type;
4223 es[i]->name.string = talloc_strdup(es[i], tdo_name);
4224 if (!es[i]->name.string) {
4225 return NT_STATUS_NO_MEMORY;
4227 es[i]->name.size = strlen(es[i]->name.string);
4229 return NT_STATUS_OK;
4233 lsa_lsaRSetForestTrustInformation
4235 static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_state *dce_call,
4236 TALLOC_CTX *mem_ctx,
4237 struct lsa_lsaRSetForestTrustInformation *r)
4239 struct dcesrv_handle *h;
4240 struct lsa_policy_state *p_state;
4241 const char *trust_attrs[] = { "trustPartner", "trustAttributes",
4242 "msDS-TrustForestTrustInfo", NULL };
4243 struct ldb_message **dom_res = NULL;
4244 struct ldb_dn *tdo_dn;
4245 struct ldb_message *msg;
4247 const char *td_name;
4248 uint32_t trust_attributes;
4249 struct lsa_ForestTrustCollisionInfo *c_info;
4250 struct ForestTrustInfo *nfti;
4251 struct ForestTrustInfo *fti;
4253 enum ndr_err_code ndr_err;
4258 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4262 if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
4263 return NT_STATUS_INVALID_DOMAIN_STATE;
4266 /* abort if we are not a PDC */
4267 if (!samdb_is_pdc(p_state->sam_ldb)) {
4268 return NT_STATUS_INVALID_DOMAIN_ROLE;
4271 ret = samdb_rodc(p_state->sam_ldb, &am_rodc);
4272 if (ret == LDB_SUCCESS && am_rodc) {
4273 return NT_STATUS_NO_SUCH_DOMAIN;
4276 /* check caller has TRUSTED_SET_AUTH */
4278 /* fetch all trusted domain objects */
4279 num_res = gendb_search(p_state->sam_ldb, mem_ctx,
4281 &dom_res, trust_attrs,
4282 "(objectclass=trustedDomain)");
4284 return NT_STATUS_NO_SUCH_DOMAIN;
4287 for (i = 0; i < num_res; i++) {
4288 td_name = ldb_msg_find_attr_as_string(dom_res[i],
4289 "trustPartner", NULL);
4291 return NT_STATUS_INVALID_DOMAIN_STATE;
4293 if (strcasecmp_m(td_name,
4294 r->in.trusted_domain_name->string) == 0) {
4299 return NT_STATUS_NO_SUCH_DOMAIN;
4302 tdo_dn = dom_res[i]->dn;
4304 trust_attributes = samdb_result_uint(dom_res[i],
4305 "trustAttributes", 0);
4306 if (!(trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4307 return NT_STATUS_INVALID_PARAMETER;
4310 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4311 return NT_STATUS_INVALID_PARAMETER;
4314 nfti = talloc(mem_ctx, struct ForestTrustInfo);
4316 return NT_STATUS_NO_MEMORY;
4319 nt_status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4320 if (!NT_STATUS_IS_OK(nt_status)) {
4324 c_info = talloc_zero(r->out.collision_info,
4325 struct lsa_ForestTrustCollisionInfo);
4327 return NT_STATUS_NO_MEMORY;
4330 /* first check own info, then other domains */
4331 fti = talloc(mem_ctx, struct ForestTrustInfo);
4333 return NT_STATUS_NO_MEMORY;
4336 nt_status = own_ft_info(p_state, fti);
4337 if (!NT_STATUS_IS_OK(nt_status)) {
4341 nt_status = check_ft_info(c_info, p_state->domain_dns,
4343 if (!NT_STATUS_IS_OK(nt_status)) {
4347 for (i = 0; i < num_res; i++) {
4348 fti = talloc(mem_ctx, struct ForestTrustInfo);
4350 return NT_STATUS_NO_MEMORY;
4353 nt_status = get_ft_info(mem_ctx, dom_res[i], fti);
4354 if (!NT_STATUS_IS_OK(nt_status)) {
4355 if (NT_STATUS_EQUAL(nt_status,
4356 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4362 td_name = ldb_msg_find_attr_as_string(dom_res[i],
4363 "trustPartner", NULL);
4365 return NT_STATUS_INVALID_DOMAIN_STATE;
4368 nt_status = check_ft_info(c_info, td_name, fti, nfti, c_info);
4369 if (!NT_STATUS_IS_OK(nt_status)) {
4374 *r->out.collision_info = c_info;
4376 if (r->in.check_only != 0) {
4377 return NT_STATUS_OK;
4380 /* not just a check, write info back */
4382 ndr_err = ndr_push_struct_blob(&ft_blob, mem_ctx, nfti,
4383 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4384 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4385 return NT_STATUS_INVALID_PARAMETER;
4388 msg = ldb_msg_new(mem_ctx);
4390 return NT_STATUS_NO_MEMORY;
4393 msg->dn = ldb_dn_copy(mem_ctx, tdo_dn);
4395 return NT_STATUS_NO_MEMORY;
4398 ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo",
4399 LDB_FLAG_MOD_REPLACE, NULL);
4400 if (ret != LDB_SUCCESS) {
4401 return NT_STATUS_NO_MEMORY;
4403 ret = ldb_msg_add_value(msg, "msDS-TrustForestTrustInfo",
4405 if (ret != LDB_SUCCESS) {
4406 return NT_STATUS_NO_MEMORY;
4409 ret = ldb_modify(p_state->sam_ldb, msg);
4410 if (ret != LDB_SUCCESS) {
4411 DEBUG(0, ("Failed to store Forest Trust Info: %s\n",
4412 ldb_errstring(p_state->sam_ldb)));
4415 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
4416 return NT_STATUS_ACCESS_DENIED;
4418 return NT_STATUS_INTERNAL_DB_CORRUPTION;
4422 return NT_STATUS_OK;
4428 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4429 struct lsa_CREDRRENAME *r)
4431 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4437 lsa_LSAROPENPOLICYSCE
4439 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4440 struct lsa_LSAROPENPOLICYSCE *r)
4442 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4447 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
4449 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4450 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4452 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4457 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
4459 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4460 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4462 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4467 lsa_LSARADTREPORTSECURITYEVENT
4469 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4470 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4472 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4476 /* include the generated boilerplate */
4477 #include "librpc/gen_ndr/ndr_lsa_s.c"
4481 /*****************************************
4482 NOTE! The remaining calls below were
4483 removed in w2k3, so the DCESRV_FAULT()
4484 replies are the correct implementation. Do
4485 not try and fill these in with anything else
4486 ******************************************/
4489 dssetup_DsRoleDnsNameToFlatName
4491 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4492 struct dssetup_DsRoleDnsNameToFlatName *r)
4494 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4499 dssetup_DsRoleDcAsDc
4501 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4502 struct dssetup_DsRoleDcAsDc *r)
4504 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4509 dssetup_DsRoleDcAsReplica
4511 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4512 struct dssetup_DsRoleDcAsReplica *r)
4514 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4519 dssetup_DsRoleDemoteDc
4521 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4522 struct dssetup_DsRoleDemoteDc *r)
4524 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4529 dssetup_DsRoleGetDcOperationProgress
4531 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4532 struct dssetup_DsRoleGetDcOperationProgress *r)
4534 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4539 dssetup_DsRoleGetDcOperationResults
4541 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4542 struct dssetup_DsRoleGetDcOperationResults *r)
4544 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4549 dssetup_DsRoleCancel
4551 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4552 struct dssetup_DsRoleCancel *r)
4554 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4559 dssetup_DsRoleServerSaveStateForUpgrade
4561 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4562 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
4564 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4569 dssetup_DsRoleUpgradeDownlevelServer
4571 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4572 struct dssetup_DsRoleUpgradeDownlevelServer *r)
4574 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4579 dssetup_DsRoleAbortDownlevelServerUpgrade
4581 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4582 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
4584 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4588 /* include the generated boilerplate */
4589 #include "librpc/gen_ndr/ndr_dssetup_s.c"
4591 NTSTATUS dcerpc_server_lsa_init(void)
4595 ret = dcerpc_server_dssetup_init();
4596 if (!NT_STATUS_IS_OK(ret)) {
4599 ret = dcerpc_server_lsarpc_init();
4600 if (!NT_STATUS_IS_OK(ret)) {