1 /* need access mask/acl implementation */
4 Unix SMB/CIFS implementation.
6 endpoint server for the lsarpc pipe
8 Copyright (C) Andrew Tridgell 2004
9 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "rpc_server/lsa/lsa.h"
26 #include "system/kerberos.h"
27 #include "auth/kerberos/kerberos.h"
28 #include "librpc/gen_ndr/ndr_drsblobs.h"
29 #include "librpc/gen_ndr/ndr_lsa.h"
30 #include "../lib/crypto/crypto.h"
31 #include "lib/util/tsort.h"
32 #include "dsdb/common/util.h"
35 this type allows us to distinguish handle types
39 state associated with a lsa_OpenAccount() operation
41 struct lsa_account_state {
42 struct lsa_policy_state *policy;
44 struct dom_sid *account_sid;
49 state associated with a lsa_OpenSecret() operation
51 struct lsa_secret_state {
52 struct lsa_policy_state *policy;
54 struct ldb_dn *secret_dn;
55 struct ldb_context *sam_ldb;
60 state associated with a lsa_OpenTrustedDomain() operation
62 struct lsa_trusted_domain_state {
63 struct lsa_policy_state *policy;
65 struct ldb_dn *trusted_domain_dn;
66 struct ldb_dn *trusted_domain_user_dn;
70 this is based on the samba3 function make_lsa_object_sd()
71 It uses the same logic, but with samba4 helper functions
73 static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
74 struct security_descriptor **sd,
80 struct dom_sid *domain_sid, *domain_admins_sid;
81 const char *domain_admins_sid_str, *sidstr;
82 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
84 status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
85 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
87 domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
88 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid, tmp_ctx);
90 domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
91 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid_str, tmp_ctx);
93 sidstr = dom_sid_string(tmp_ctx, sid);
94 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, tmp_ctx);
96 *sd = security_descriptor_dacl_create(mem_ctx,
100 SEC_ACE_TYPE_ACCESS_ALLOWED,
101 SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,
103 SID_BUILTIN_ADMINISTRATORS,
104 SEC_ACE_TYPE_ACCESS_ALLOWED,
107 SID_BUILTIN_ACCOUNT_OPERATORS,
108 SEC_ACE_TYPE_ACCESS_ALLOWED,
111 domain_admins_sid_str,
112 SEC_ACE_TYPE_ACCESS_ALLOWED,
116 SEC_ACE_TYPE_ACCESS_ALLOWED,
120 talloc_free(tmp_ctx);
122 NT_STATUS_HAVE_NO_MEMORY(*sd);
128 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
130 struct lsa_EnumAccountRights *r);
132 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
134 struct lsa_policy_state *state,
137 const struct lsa_RightSet *rights);
142 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
145 struct dcesrv_handle *h;
147 *r->out.handle = *r->in.handle;
149 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
153 ZERO_STRUCTP(r->out.handle);
162 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
163 struct lsa_Delete *r)
165 return NT_STATUS_NOT_SUPPORTED;
172 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
173 struct lsa_DeleteObject *r)
175 struct dcesrv_handle *h;
178 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
180 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
181 struct lsa_secret_state *secret_state = h->data;
183 /* Ensure user is permitted to delete this... */
184 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
186 case SECURITY_SYSTEM:
187 case SECURITY_ADMINISTRATOR:
190 /* Users and anonymous are not allowed to delete things */
191 return NT_STATUS_ACCESS_DENIED;
194 ret = ldb_delete(secret_state->sam_ldb,
195 secret_state->secret_dn);
196 if (ret != LDB_SUCCESS) {
197 return NT_STATUS_INVALID_HANDLE;
200 ZERO_STRUCTP(r->out.handle);
204 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
205 struct lsa_trusted_domain_state *trusted_domain_state =
206 talloc_get_type(h->data, struct lsa_trusted_domain_state);
207 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
208 if (ret != LDB_SUCCESS) {
209 return NT_STATUS_INTERNAL_DB_CORRUPTION;
212 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
213 trusted_domain_state->trusted_domain_dn);
214 if (ret != LDB_SUCCESS) {
215 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
216 return NT_STATUS_INVALID_HANDLE;
219 if (trusted_domain_state->trusted_domain_user_dn) {
220 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
221 trusted_domain_state->trusted_domain_user_dn);
222 if (ret != LDB_SUCCESS) {
223 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
224 return NT_STATUS_INVALID_HANDLE;
228 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
229 if (ret != LDB_SUCCESS) {
230 return NT_STATUS_INTERNAL_DB_CORRUPTION;
233 ZERO_STRUCTP(r->out.handle);
237 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
238 struct lsa_RightSet *rights;
239 struct lsa_account_state *astate;
240 struct lsa_EnumAccountRights r2;
243 rights = talloc(mem_ctx, struct lsa_RightSet);
245 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
249 r2.in.handle = &astate->policy->handle->wire_handle;
250 r2.in.sid = astate->account_sid;
251 r2.out.rights = rights;
253 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
254 but we have a LSA_HANDLE_ACCOUNT here, so this call
256 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
257 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
261 if (!NT_STATUS_IS_OK(status)) {
265 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
266 LDB_FLAG_MOD_DELETE, astate->account_sid,
268 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
272 if (!NT_STATUS_IS_OK(status)) {
276 ZERO_STRUCTP(r->out.handle);
281 return NT_STATUS_INVALID_HANDLE;
288 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
289 struct lsa_EnumPrivs *r)
291 struct dcesrv_handle *h;
292 struct lsa_policy_state *state;
294 enum sec_privilege priv;
295 const char *privname;
297 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
301 i = *r->in.resume_handle;
303 while (((priv = sec_privilege_from_index(i)) != SEC_PRIV_INVALID) &&
304 r->out.privs->count < r->in.max_count) {
305 struct lsa_PrivEntry *e;
306 privname = sec_privilege_name(priv);
307 r->out.privs->privs = talloc_realloc(r->out.privs,
309 struct lsa_PrivEntry,
310 r->out.privs->count+1);
311 if (r->out.privs->privs == NULL) {
312 return NT_STATUS_NO_MEMORY;
314 e = &r->out.privs->privs[r->out.privs->count];
317 e->name.string = privname;
318 r->out.privs->count++;
322 *r->out.resume_handle = i;
331 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
332 struct lsa_QuerySecurity *r)
334 struct dcesrv_handle *h;
335 struct security_descriptor *sd;
339 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
341 sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
343 if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
344 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid, 0);
345 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
346 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid,
347 LSA_ACCOUNT_ALL_ACCESS);
349 return NT_STATUS_INVALID_HANDLE;
351 NT_STATUS_NOT_OK_RETURN(status);
353 (*r->out.sdbuf) = talloc(mem_ctx, struct sec_desc_buf);
354 NT_STATUS_HAVE_NO_MEMORY(*r->out.sdbuf);
356 (*r->out.sdbuf)->sd = sd;
365 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
366 struct lsa_SetSecObj *r)
368 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
375 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
376 struct lsa_ChangePassword *r)
378 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
382 dssetup_DsRoleGetPrimaryDomainInformation
384 This is not an LSA call, but is the only call left on the DSSETUP
385 pipe (after the pipe was truncated), and needs lsa_get_policy_state
387 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
389 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
391 union dssetup_DsRoleInfo *info;
393 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
394 W_ERROR_HAVE_NO_MEMORY(info);
396 switch (r->in.level) {
397 case DS_ROLE_BASIC_INFORMATION:
399 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
401 const char *domain = NULL;
402 const char *dns_domain = NULL;
403 const char *forest = NULL;
404 struct GUID domain_guid;
405 struct lsa_policy_state *state;
407 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
408 if (!NT_STATUS_IS_OK(status)) {
409 return ntstatus_to_werror(status);
412 ZERO_STRUCT(domain_guid);
414 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
415 case ROLE_STANDALONE:
416 role = DS_ROLE_STANDALONE_SERVER;
418 case ROLE_DOMAIN_MEMBER:
419 role = DS_ROLE_MEMBER_SERVER;
421 case ROLE_DOMAIN_CONTROLLER:
422 if (samdb_is_pdc(state->sam_ldb)) {
423 role = DS_ROLE_PRIMARY_DC;
425 role = DS_ROLE_BACKUP_DC;
430 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
431 case ROLE_STANDALONE:
432 domain = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
433 W_ERROR_HAVE_NO_MEMORY(domain);
435 case ROLE_DOMAIN_MEMBER:
436 domain = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
437 W_ERROR_HAVE_NO_MEMORY(domain);
438 /* TODO: what is with dns_domain and forest and guid? */
440 case ROLE_DOMAIN_CONTROLLER:
441 flags = DS_ROLE_PRIMARY_DS_RUNNING;
443 if (state->mixed_domain == 1) {
444 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
447 domain = state->domain_name;
448 dns_domain = state->domain_dns;
449 forest = state->forest_dns;
451 domain_guid = state->domain_guid;
452 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
456 info->basic.role = role;
457 info->basic.flags = flags;
458 info->basic.domain = domain;
459 info->basic.dns_domain = dns_domain;
460 info->basic.forest = forest;
461 info->basic.domain_guid = domain_guid;
466 case DS_ROLE_UPGRADE_STATUS:
468 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
469 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
474 case DS_ROLE_OP_STATUS:
476 info->opstatus.status = DS_ROLE_OP_IDLE;
482 return WERR_INVALID_PARAM;
487 fill in the AccountDomain info
489 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
490 struct lsa_DomainInfo *info)
492 info->name.string = state->domain_name;
493 info->sid = state->domain_sid;
499 fill in the DNS domain info
501 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
502 struct lsa_DnsDomainInfo *info)
504 info->name.string = state->domain_name;
505 info->sid = state->domain_sid;
506 info->dns_domain.string = state->domain_dns;
507 info->dns_forest.string = state->forest_dns;
508 info->domain_guid = state->domain_guid;
516 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
517 struct lsa_QueryInfoPolicy2 *r)
519 struct lsa_policy_state *state;
520 struct dcesrv_handle *h;
521 union lsa_PolicyInformation *info;
525 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
529 info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
531 return NT_STATUS_NO_MEMORY;
535 switch (r->in.level) {
536 case LSA_POLICY_INFO_AUDIT_LOG:
537 /* we don't need to fill in any of this */
538 ZERO_STRUCT(info->audit_log);
540 case LSA_POLICY_INFO_AUDIT_EVENTS:
541 /* we don't need to fill in any of this */
542 ZERO_STRUCT(info->audit_events);
544 case LSA_POLICY_INFO_PD:
545 /* we don't need to fill in any of this */
546 ZERO_STRUCT(info->pd);
549 case LSA_POLICY_INFO_DOMAIN:
550 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
551 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
552 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
553 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
554 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
556 case LSA_POLICY_INFO_ROLE:
557 info->role.role = LSA_ROLE_PRIMARY;
560 case LSA_POLICY_INFO_DNS:
561 case LSA_POLICY_INFO_DNS_INT:
562 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
564 case LSA_POLICY_INFO_REPLICA:
565 ZERO_STRUCT(info->replica);
568 case LSA_POLICY_INFO_QUOTA:
569 ZERO_STRUCT(info->quota);
572 case LSA_POLICY_INFO_MOD:
573 case LSA_POLICY_INFO_AUDIT_FULL_SET:
574 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
575 /* windows gives INVALID_PARAMETER */
577 return NT_STATUS_INVALID_PARAMETER;
581 return NT_STATUS_INVALID_INFO_CLASS;
587 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
588 struct lsa_QueryInfoPolicy *r)
590 struct lsa_QueryInfoPolicy2 r2;
595 r2.in.handle = r->in.handle;
596 r2.in.level = r->in.level;
597 r2.out.info = r->out.info;
599 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
607 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
608 struct lsa_SetInfoPolicy *r)
610 /* need to support this */
611 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
618 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
619 struct lsa_ClearAuditLog *r)
621 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
628 This call does not seem to have any long-term effects, hence no database operations
630 we need to talk to the MS product group to find out what this account database means!
632 answer is that the lsa database is totally separate from the SAM and
633 ldap databases. We are going to need a separate ldb to store these
634 accounts. The SIDs on this account bear no relation to the SIDs in
637 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
638 struct lsa_CreateAccount *r)
640 struct lsa_account_state *astate;
642 struct lsa_policy_state *state;
643 struct dcesrv_handle *h, *ah;
645 ZERO_STRUCTP(r->out.acct_handle);
647 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
651 astate = talloc(dce_call->conn, struct lsa_account_state);
652 if (astate == NULL) {
653 return NT_STATUS_NO_MEMORY;
656 astate->account_sid = dom_sid_dup(astate, r->in.sid);
657 if (astate->account_sid == NULL) {
659 return NT_STATUS_NO_MEMORY;
662 astate->policy = talloc_reference(astate, state);
663 astate->access_mask = r->in.access_mask;
665 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
668 return NT_STATUS_NO_MEMORY;
671 ah->data = talloc_steal(ah, astate);
673 *r->out.acct_handle = ah->wire_handle;
682 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
683 struct lsa_EnumAccounts *r)
685 struct dcesrv_handle *h;
686 struct lsa_policy_state *state;
688 struct ldb_message **res;
689 const char * const attrs[] = { "objectSid", NULL};
692 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
696 /* NOTE: This call must only return accounts that have at least
699 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
700 "(&(objectSid=*)(privilege=*))");
702 return NT_STATUS_INTERNAL_DB_CORRUPTION;
705 if (*r->in.resume_handle >= ret) {
706 return NT_STATUS_NO_MORE_ENTRIES;
709 count = ret - *r->in.resume_handle;
710 if (count > r->in.num_entries) {
711 count = r->in.num_entries;
715 return NT_STATUS_NO_MORE_ENTRIES;
718 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
719 if (r->out.sids->sids == NULL) {
720 return NT_STATUS_NO_MEMORY;
723 for (i=0;i<count;i++) {
724 r->out.sids->sids[i].sid =
725 samdb_result_dom_sid(r->out.sids->sids,
726 res[i + *r->in.resume_handle],
728 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
731 r->out.sids->num_sids = count;
732 *r->out.resume_handle = count + *r->in.resume_handle;
738 /* This decrypts and returns Trusted Domain Auth Information Internal data */
739 static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
740 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
741 struct trustDomainPasswords *auth_struct)
743 DATA_BLOB session_key = data_blob(NULL, 0);
744 enum ndr_err_code ndr_err;
747 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
748 if (!NT_STATUS_IS_OK(nt_status)) {
752 arcfour_crypt_blob(auth_blob->data, auth_blob->length, &session_key);
753 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
755 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
756 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
757 return NT_STATUS_INVALID_PARAMETER;
763 static NTSTATUS get_trustauth_inout_blob(struct dcesrv_call_state *dce_call,
765 struct trustAuthInOutBlob *iopw,
766 DATA_BLOB *trustauth_blob)
768 enum ndr_err_code ndr_err;
770 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
772 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
773 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
774 return NT_STATUS_INVALID_PARAMETER;
780 static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx,
781 struct ldb_context *sam_ldb,
782 struct ldb_dn *base_dn,
783 const char *netbios_name,
784 struct trustAuthInOutBlob *in,
785 struct ldb_dn **user_dn)
787 struct ldb_message *msg;
792 dn = ldb_dn_copy(mem_ctx, base_dn);
794 return NT_STATUS_NO_MEMORY;
796 if (!ldb_dn_add_child_fmt(dn, "cn=%s$,cn=users", netbios_name)) {
797 return NT_STATUS_NO_MEMORY;
800 msg = ldb_msg_new(mem_ctx);
802 return NT_STATUS_NO_MEMORY;
806 ret = ldb_msg_add_string(msg, "objectClass", "user");
807 if (ret != LDB_SUCCESS) {
808 return NT_STATUS_NO_MEMORY;
811 ret = ldb_msg_add_fmt(msg, "samAccountName", "%s$", netbios_name);
812 if (ret != LDB_SUCCESS) {
813 return NT_STATUS_NO_MEMORY;
816 ret = ldb_msg_add_fmt(msg, "userAccountControl", "%u",
817 UF_INTERDOMAIN_TRUST_ACCOUNT);
818 if (ret != LDB_SUCCESS) {
819 return NT_STATUS_NO_MEMORY;
822 for (i = 0; i < in->count; i++) {
823 const char *attribute;
825 switch (in->current.array[i].AuthType) {
826 case TRUST_AUTH_TYPE_NT4OWF:
827 attribute = "unicodePwd";
828 v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
831 case TRUST_AUTH_TYPE_CLEAR:
832 attribute = "clearTextPassword";
833 v.data = in->current.array[i].AuthInfo.clear.password;
834 v.length = in->current.array[i].AuthInfo.clear.size;
840 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
841 if (ret != LDB_SUCCESS) {
842 return NT_STATUS_NO_MEMORY;
846 /* create the trusted_domain user account */
847 ret = ldb_add(sam_ldb, msg);
848 if (ret != LDB_SUCCESS) {
849 DEBUG(0,("Failed to create user record %s: %s\n",
850 ldb_dn_get_linearized(msg->dn),
851 ldb_errstring(sam_ldb)));
854 case LDB_ERR_ENTRY_ALREADY_EXISTS:
855 return NT_STATUS_DOMAIN_EXISTS;
856 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
857 return NT_STATUS_ACCESS_DENIED;
859 return NT_STATUS_INTERNAL_DB_CORRUPTION;
870 lsa_CreateTrustedDomainEx2
872 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
874 struct lsa_CreateTrustedDomainEx2 *r,
877 struct dcesrv_handle *policy_handle;
878 struct lsa_policy_state *policy_state;
879 struct lsa_trusted_domain_state *trusted_domain_state;
880 struct dcesrv_handle *handle;
881 struct ldb_message **msgs, *msg;
882 const char *attrs[] = {
885 const char *netbios_name;
886 const char *dns_name;
888 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
889 struct trustDomainPasswords auth_struct;
892 struct ldb_context *sam_ldb;
894 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
895 ZERO_STRUCTP(r->out.trustdom_handle);
897 policy_state = policy_handle->data;
898 sam_ldb = policy_state->sam_ldb;
900 netbios_name = r->in.info->netbios_name.string;
902 return NT_STATUS_INVALID_PARAMETER;
905 dns_name = r->in.info->domain_name.string;
907 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
908 if (!trusted_domain_state) {
909 return NT_STATUS_NO_MEMORY;
911 trusted_domain_state->policy = policy_state;
913 if (strcasecmp(netbios_name, "BUILTIN") == 0
914 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
915 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
916 return NT_STATUS_INVALID_PARAMETER;
919 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
920 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
921 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
922 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
923 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
924 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
927 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
928 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
929 /* No secrets are created at this time, for this function */
930 auth_struct.outgoing.count = 0;
931 auth_struct.incoming.count = 0;
933 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data,
934 r->in.auth_info->auth_blob.size);
935 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
936 &auth_blob, &auth_struct);
937 if (!NT_STATUS_IS_OK(nt_status)) {
941 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
942 if (auth_struct.incoming.count > 1) {
943 return NT_STATUS_INVALID_PARAMETER;
948 if (auth_struct.incoming.count) {
949 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
950 &auth_struct.incoming,
952 if (!NT_STATUS_IS_OK(nt_status)) {
956 trustAuthIncoming = data_blob(NULL, 0);
959 if (auth_struct.outgoing.count) {
960 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
961 &auth_struct.outgoing,
963 if (!NT_STATUS_IS_OK(nt_status)) {
967 trustAuthOutgoing = data_blob(NULL, 0);
970 ret = ldb_transaction_start(sam_ldb);
971 if (ret != LDB_SUCCESS) {
972 return NT_STATUS_INTERNAL_DB_CORRUPTION;
976 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
977 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
978 /* search for the trusted_domain record */
979 ret = gendb_search(sam_ldb,
980 mem_ctx, policy_state->system_dn, &msgs, attrs,
981 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
982 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
984 ldb_transaction_cancel(sam_ldb);
985 return NT_STATUS_OBJECT_NAME_COLLISION;
988 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
989 /* search for the trusted_domain record */
990 ret = gendb_search(sam_ldb,
991 mem_ctx, policy_state->system_dn, &msgs, attrs,
992 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
993 netbios_encoded, netbios_encoded, netbios_encoded);
995 ldb_transaction_cancel(sam_ldb);
996 return NT_STATUS_OBJECT_NAME_COLLISION;
1001 ldb_transaction_cancel(sam_ldb);
1002 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1005 name = dns_name ? dns_name : netbios_name;
1007 msg = ldb_msg_new(mem_ctx);
1009 return NT_STATUS_NO_MEMORY;
1012 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1013 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
1014 ldb_transaction_cancel(sam_ldb);
1015 return NT_STATUS_NO_MEMORY;
1018 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "flatname", netbios_name);
1020 if (r->in.info->sid) {
1021 ret = samdb_msg_add_dom_sid(sam_ldb, mem_ctx, msg, "securityIdentifier", r->in.info->sid);
1022 if (ret != LDB_SUCCESS) {
1023 ldb_transaction_cancel(sam_ldb);
1024 return NT_STATUS_INVALID_PARAMETER;
1028 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
1030 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
1032 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
1034 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
1037 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
1040 if (trustAuthIncoming.data) {
1041 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
1042 if (ret != LDB_SUCCESS) {
1043 ldb_transaction_cancel(sam_ldb);
1044 return NT_STATUS_NO_MEMORY;
1047 if (trustAuthOutgoing.data) {
1048 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
1049 if (ret != LDB_SUCCESS) {
1050 ldb_transaction_cancel(sam_ldb);
1051 return NT_STATUS_NO_MEMORY;
1055 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
1057 /* create the trusted_domain */
1058 ret = dsdb_add(sam_ldb, msg, DSDB_MODIFY_RELAX);
1062 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1063 ldb_transaction_cancel(sam_ldb);
1064 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1065 ldb_dn_get_linearized(msg->dn),
1066 ldb_errstring(sam_ldb)));
1067 return NT_STATUS_DOMAIN_EXISTS;
1068 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1069 ldb_transaction_cancel(sam_ldb);
1070 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1071 ldb_dn_get_linearized(msg->dn),
1072 ldb_errstring(sam_ldb)));
1073 return NT_STATUS_ACCESS_DENIED;
1075 ldb_transaction_cancel(sam_ldb);
1076 DEBUG(0,("Failed to create user record %s: %s\n",
1077 ldb_dn_get_linearized(msg->dn),
1078 ldb_errstring(sam_ldb)));
1079 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1082 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1083 struct ldb_dn *user_dn;
1084 /* Inbound trusts must also create a cn=users object to match */
1085 nt_status = add_trust_user(mem_ctx, sam_ldb,
1086 policy_state->domain_dn,
1088 &auth_struct.incoming,
1090 if (!NT_STATUS_IS_OK(nt_status)) {
1091 ldb_transaction_cancel(sam_ldb);
1095 /* save the trust user dn */
1096 trusted_domain_state->trusted_domain_user_dn
1097 = talloc_steal(trusted_domain_state, user_dn);
1100 ret = ldb_transaction_commit(sam_ldb);
1101 if (ret != LDB_SUCCESS) {
1102 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1105 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1107 return NT_STATUS_NO_MEMORY;
1110 handle->data = talloc_steal(handle, trusted_domain_state);
1112 trusted_domain_state->access_mask = r->in.access_mask;
1113 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1115 *r->out.trustdom_handle = handle->wire_handle;
1117 return NT_STATUS_OK;
1121 lsa_CreateTrustedDomainEx2
1123 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1124 TALLOC_CTX *mem_ctx,
1125 struct lsa_CreateTrustedDomainEx2 *r)
1127 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
1130 lsa_CreateTrustedDomainEx
1132 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1133 TALLOC_CTX *mem_ctx,
1134 struct lsa_CreateTrustedDomainEx *r)
1136 struct lsa_CreateTrustedDomainEx2 r2;
1138 r2.in.policy_handle = r->in.policy_handle;
1139 r2.in.info = r->in.info;
1140 r2.in.auth_info = r->in.auth_info;
1141 r2.out.trustdom_handle = r->out.trustdom_handle;
1142 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
1146 lsa_CreateTrustedDomain
1148 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1149 struct lsa_CreateTrustedDomain *r)
1151 struct lsa_CreateTrustedDomainEx2 r2;
1153 r2.in.policy_handle = r->in.policy_handle;
1154 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1156 return NT_STATUS_NO_MEMORY;
1159 r2.in.info->domain_name.string = NULL;
1160 r2.in.info->netbios_name = r->in.info->name;
1161 r2.in.info->sid = r->in.info->sid;
1162 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1163 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1164 r2.in.info->trust_attributes = 0;
1166 r2.in.access_mask = r->in.access_mask;
1167 r2.out.trustdom_handle = r->out.trustdom_handle;
1169 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1174 lsa_OpenTrustedDomain
1176 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1177 struct lsa_OpenTrustedDomain *r)
1179 struct dcesrv_handle *policy_handle;
1181 struct lsa_policy_state *policy_state;
1182 struct lsa_trusted_domain_state *trusted_domain_state;
1183 struct dcesrv_handle *handle;
1184 struct ldb_message **msgs;
1185 const char *attrs[] = {
1191 const char *sid_string;
1194 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1195 ZERO_STRUCTP(r->out.trustdom_handle);
1196 policy_state = policy_handle->data;
1198 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1199 if (!trusted_domain_state) {
1200 return NT_STATUS_NO_MEMORY;
1202 trusted_domain_state->policy = policy_state;
1204 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1206 return NT_STATUS_NO_MEMORY;
1209 /* search for the trusted_domain record */
1210 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1211 mem_ctx, policy_state->system_dn, &msgs, attrs,
1212 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
1215 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1219 DEBUG(0,("Found %d records matching DN %s\n", ret,
1220 ldb_dn_get_linearized(policy_state->system_dn)));
1221 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1224 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1226 trusted_domain_state->trusted_domain_user_dn = NULL;
1228 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1229 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1230 /* search for the trusted_domain record */
1231 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1232 mem_ctx, policy_state->domain_dn, &msgs, attrs,
1233 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%d))",
1234 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1236 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1239 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1241 return NT_STATUS_NO_MEMORY;
1244 handle->data = talloc_steal(handle, trusted_domain_state);
1246 trusted_domain_state->access_mask = r->in.access_mask;
1247 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1249 *r->out.trustdom_handle = handle->wire_handle;
1251 return NT_STATUS_OK;
1256 lsa_OpenTrustedDomainByName
1258 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1259 TALLOC_CTX *mem_ctx,
1260 struct lsa_OpenTrustedDomainByName *r)
1262 struct dcesrv_handle *policy_handle;
1264 struct lsa_policy_state *policy_state;
1265 struct lsa_trusted_domain_state *trusted_domain_state;
1266 struct dcesrv_handle *handle;
1267 struct ldb_message **msgs;
1268 const char *attrs[] = {
1274 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1275 ZERO_STRUCTP(r->out.trustdom_handle);
1276 policy_state = policy_handle->data;
1278 if (!r->in.name.string) {
1279 return NT_STATUS_INVALID_PARAMETER;
1282 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1283 if (!trusted_domain_state) {
1284 return NT_STATUS_NO_MEMORY;
1286 trusted_domain_state->policy = policy_state;
1288 /* search for the trusted_domain record */
1289 td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string);
1290 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1291 mem_ctx, policy_state->system_dn, &msgs, attrs,
1292 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))"
1293 "(objectclass=trustedDomain))",
1294 td_name, td_name, td_name);
1296 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1300 DEBUG(0,("Found %d records matching DN %s\n", ret,
1301 ldb_dn_get_linearized(policy_state->system_dn)));
1302 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1305 /* TODO: perform access checks */
1307 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1309 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1311 return NT_STATUS_NO_MEMORY;
1314 handle->data = talloc_steal(handle, trusted_domain_state);
1316 trusted_domain_state->access_mask = r->in.access_mask;
1317 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1319 *r->out.trustdom_handle = handle->wire_handle;
1321 return NT_STATUS_OK;
1327 lsa_SetTrustedDomainInfo
1329 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1330 struct lsa_SetTrustedDomainInfo *r)
1332 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1337 /* parameters 4 to 6 are optional if the dn is a dn of a TDO object,
1338 * otherwise at least one must be provided */
1339 static NTSTATUS get_tdo(struct ldb_context *sam, TALLOC_CTX *mem_ctx,
1340 struct ldb_dn *basedn, const char *dns_domain,
1341 const char *netbios, struct dom_sid2 *sid,
1342 struct ldb_message ***msgs)
1344 const char *attrs[] = { "flatname", "trustPartner",
1345 "securityIdentifier", "trustDirection",
1346 "trustType", "trustAttributes",
1348 "msDs-supportedEncryptionTypes", NULL };
1351 char *sidstr = NULL;
1356 if (dns_domain || netbios || sid) {
1357 filter = talloc_strdup(mem_ctx,
1358 "(&(objectclass=trustedDomain)(|");
1360 filter = talloc_strdup(mem_ctx,
1361 "(objectclass=trustedDomain)");
1364 return NT_STATUS_NO_MEMORY;
1368 dns = ldb_binary_encode_string(mem_ctx, dns_domain);
1370 return NT_STATUS_NO_MEMORY;
1372 filter = talloc_asprintf_append(filter,
1373 "(trustPartner=%s)", dns);
1375 return NT_STATUS_NO_MEMORY;
1379 nbn = ldb_binary_encode_string(mem_ctx, netbios);
1381 return NT_STATUS_NO_MEMORY;
1383 filter = talloc_asprintf_append(filter,
1384 "(flatname=%s)", nbn);
1386 return NT_STATUS_NO_MEMORY;
1390 sidstr = dom_sid_string(mem_ctx, sid);
1392 return NT_STATUS_INVALID_PARAMETER;
1394 filter = talloc_asprintf_append(filter,
1395 "(securityIdentifier=%s)",
1398 return NT_STATUS_NO_MEMORY;
1401 if (dns_domain || netbios || sid) {
1402 filter = talloc_asprintf_append(filter, "))");
1404 return NT_STATUS_NO_MEMORY;
1408 ret = gendb_search(sam, mem_ctx, basedn, msgs, attrs, "%s", filter);
1410 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1414 return NT_STATUS_OBJECT_NAME_COLLISION;
1417 return NT_STATUS_OK;
1420 static NTSTATUS update_uint32_t_value(TALLOC_CTX *mem_ctx,
1421 struct ldb_message *orig,
1422 struct ldb_message *dest,
1423 const char *attribute,
1425 uint32_t *orig_value)
1427 const struct ldb_val *orig_val;
1428 uint32_t orig_uint = 0;
1433 orig_val = ldb_msg_find_ldb_val(orig, attribute);
1434 if (!orig_val || !orig_val->data) {
1435 /* add new attribute */
1436 flags = LDB_FLAG_MOD_ADD;
1440 orig_uint = strtoul((const char *)orig_val->data, NULL, 0);
1441 if (errno != 0 || orig_uint != value) {
1442 /* replace also if can't get value */
1443 flags = LDB_FLAG_MOD_REPLACE;
1448 /* stored value is identical, nothing to change */
1452 ret = ldb_msg_add_empty(dest, attribute, flags, NULL);
1453 if (ret != LDB_SUCCESS) {
1454 return NT_STATUS_NO_MEMORY;
1457 str_val = talloc_asprintf(mem_ctx, "%u", value);
1459 return NT_STATUS_NO_MEMORY;
1461 ret = ldb_msg_add_steal_string(dest, attribute, str_val);
1462 if (ret != LDB_SUCCESS) {
1463 return NT_STATUS_NO_MEMORY;
1468 *orig_value = orig_uint;
1470 return NT_STATUS_OK;
1473 static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx,
1474 struct ldb_context *sam_ldb,
1475 struct ldb_dn *base_dn,
1477 const char *netbios_name,
1478 struct trustAuthInOutBlob *in)
1480 const char *attrs[] = { "userAccountControl", NULL };
1481 struct ldb_message **msgs;
1482 struct ldb_message *msg;
1487 ret = gendb_search(sam_ldb, mem_ctx,
1488 base_dn, &msgs, attrs,
1489 "samAccountName=%s$", netbios_name);
1491 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1496 return NT_STATUS_OK;
1499 /* ok no existing user, add it from scratch */
1500 return add_trust_user(mem_ctx, sam_ldb, base_dn,
1501 netbios_name, in, NULL);
1504 /* check user is what we are looking for */
1505 uac = ldb_msg_find_attr_as_uint(msgs[0],
1506 "userAccountControl", 0);
1507 if (!(uac & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
1508 return NT_STATUS_OBJECT_NAME_COLLISION;
1512 ret = ldb_delete(sam_ldb, msgs[0]->dn);
1515 return NT_STATUS_OK;
1516 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1517 return NT_STATUS_ACCESS_DENIED;
1519 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1523 /* entry exists, just modify secret if any */
1524 if (in->count == 0) {
1525 return NT_STATUS_OK;
1528 msg = ldb_msg_new(mem_ctx);
1530 return NT_STATUS_NO_MEMORY;
1532 msg->dn = msgs[0]->dn;
1534 for (i = 0; i < in->count; i++) {
1535 const char *attribute;
1537 switch (in->current.array[i].AuthType) {
1538 case TRUST_AUTH_TYPE_NT4OWF:
1539 attribute = "unicodePwd";
1540 v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
1543 case TRUST_AUTH_TYPE_CLEAR:
1544 attribute = "clearTextPassword";
1545 v.data = in->current.array[i].AuthInfo.clear.password;
1546 v.length = in->current.array[i].AuthInfo.clear.size;
1552 ret = ldb_msg_add_empty(msg, attribute,
1553 LDB_FLAG_MOD_REPLACE, NULL);
1554 if (ret != LDB_SUCCESS) {
1555 return NT_STATUS_NO_MEMORY;
1558 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
1559 if (ret != LDB_SUCCESS) {
1560 return NT_STATUS_NO_MEMORY;
1564 /* create the trusted_domain user account */
1565 ret = ldb_modify(sam_ldb, msg);
1566 if (ret != LDB_SUCCESS) {
1567 DEBUG(0,("Failed to create user record %s: %s\n",
1568 ldb_dn_get_linearized(msg->dn),
1569 ldb_errstring(sam_ldb)));
1572 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1573 return NT_STATUS_DOMAIN_EXISTS;
1574 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1575 return NT_STATUS_ACCESS_DENIED;
1577 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1581 return NT_STATUS_OK;
1585 static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call,
1586 struct dcesrv_handle *p_handle,
1587 TALLOC_CTX *mem_ctx,
1588 struct ldb_message *dom_msg,
1589 enum lsa_TrustDomInfoEnum level,
1590 union lsa_TrustedDomainInfo *info)
1592 struct lsa_policy_state *p_state = p_handle->data;
1593 uint32_t *posix_offset = NULL;
1594 struct lsa_TrustDomainInfoInfoEx *info_ex = NULL;
1595 struct lsa_TrustDomainInfoAuthInfo *auth_info = NULL;
1596 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
1597 uint32_t *enc_types = NULL;
1598 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
1599 struct trustDomainPasswords auth_struct;
1601 struct ldb_message **msgs;
1602 struct ldb_message *msg;
1603 bool add_outgoing = false;
1604 bool add_incoming = false;
1605 bool del_outgoing = false;
1606 bool del_incoming = false;
1607 bool in_transaction = false;
1612 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1613 posix_offset = &info->posix_offset.posix_offset;
1615 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1616 info_ex = &info->info_ex;
1618 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1619 auth_info = &info->auth_info;
1621 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1622 posix_offset = &info->full_info.posix_offset.posix_offset;
1623 info_ex = &info->full_info.info_ex;
1624 auth_info = &info->full_info.auth_info;
1626 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1627 auth_info_int = &info->auth_info_internal;
1629 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1630 posix_offset = &info->full_info_internal.posix_offset.posix_offset;
1631 info_ex = &info->full_info_internal.info_ex;
1632 auth_info_int = &info->full_info_internal.auth_info;
1634 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1635 enc_types = &info->enc_types.enc_types;
1638 return NT_STATUS_INVALID_PARAMETER;
1642 /* FIXME: not handled yet */
1643 return NT_STATUS_INVALID_PARAMETER;
1646 /* decode auth_info_int if set */
1647 if (auth_info_int) {
1649 /* now decrypt blob */
1650 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
1651 auth_info_int->auth_blob.size);
1653 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
1654 &auth_blob, &auth_struct);
1655 if (!NT_STATUS_IS_OK(nt_status)) {
1661 /* verify data matches */
1662 if (info_ex->trust_attributes &
1663 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1664 /* TODO: check what behavior level we have */
1665 if (strcasecmp_m(p_state->domain_dns,
1666 p_state->forest_dns) != 0) {
1667 return NT_STATUS_INVALID_DOMAIN_STATE;
1671 ret = samdb_rodc(p_state->sam_ldb, &am_rodc);
1672 if (ret == LDB_SUCCESS && am_rodc) {
1673 return NT_STATUS_NO_SUCH_DOMAIN;
1676 /* verify only one object matches the dns/netbios/sid
1677 * triplet and that this is the one we already have */
1678 nt_status = get_tdo(p_state->sam_ldb, mem_ctx,
1680 info_ex->domain_name.string,
1681 info_ex->netbios_name.string,
1682 info_ex->sid, &msgs);
1683 if (!NT_STATUS_IS_OK(nt_status)) {
1686 if (ldb_dn_compare(dom_msg->dn, msgs[0]->dn) != 0) {
1687 return NT_STATUS_OBJECT_NAME_COLLISION;
1692 /* TODO: should we fetch previous values from the existing entry
1693 * and append them ? */
1694 if (auth_struct.incoming.count) {
1695 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1696 &auth_struct.incoming,
1697 &trustAuthIncoming);
1698 if (!NT_STATUS_IS_OK(nt_status)) {
1702 trustAuthIncoming = data_blob(NULL, 0);
1705 if (auth_struct.outgoing.count) {
1706 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1707 &auth_struct.outgoing,
1708 &trustAuthOutgoing);
1709 if (!NT_STATUS_IS_OK(nt_status)) {
1713 trustAuthOutgoing = data_blob(NULL, 0);
1716 msg = ldb_msg_new(mem_ctx);
1718 return NT_STATUS_NO_MEMORY;
1720 msg->dn = dom_msg->dn;
1723 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1725 *posix_offset, NULL);
1726 if (!NT_STATUS_IS_OK(nt_status)) {
1737 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1739 info_ex->trust_direction,
1741 if (!NT_STATUS_IS_OK(nt_status)) {
1745 tmp = info_ex->trust_direction ^ origdir;
1746 if (tmp & LSA_TRUST_DIRECTION_INBOUND) {
1747 if (origdir & LSA_TRUST_DIRECTION_INBOUND) {
1748 del_incoming = true;
1750 add_incoming = true;
1753 if (tmp & LSA_TRUST_DIRECTION_OUTBOUND) {
1754 if (origdir & LSA_TRUST_DIRECTION_OUTBOUND) {
1755 del_outgoing = true;
1757 add_outgoing = true;
1761 origtype = ldb_msg_find_attr_as_int(dom_msg, "trustType", -1);
1762 if (origtype == -1 || origtype != info_ex->trust_type) {
1763 DEBUG(1, ("Attempted to change trust type! "
1764 "Operation not handled\n"));
1765 return NT_STATUS_INVALID_PARAMETER;
1768 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1770 info_ex->trust_attributes,
1772 if (!NT_STATUS_IS_OK(nt_status)) {
1775 /* TODO: check forestFunctionality from ldb opaque */
1776 /* TODO: check what is set makes sense */
1777 /* for now refuse changes */
1778 if (origattrs == -1 ||
1779 origattrs != info_ex->trust_attributes) {
1780 DEBUG(1, ("Attempted to change trust attributes! "
1781 "Operation not handled\n"));
1782 return NT_STATUS_INVALID_PARAMETER;
1787 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1788 "msDS-SupportedEncryptionTypes",
1790 if (!NT_STATUS_IS_OK(nt_status)) {
1795 if (add_incoming && trustAuthIncoming.data) {
1796 ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
1797 LDB_FLAG_MOD_REPLACE, NULL);
1798 if (ret != LDB_SUCCESS) {
1799 return NT_STATUS_NO_MEMORY;
1801 ret = ldb_msg_add_value(msg, "trustAuthIncoming",
1802 &trustAuthIncoming, NULL);
1803 if (ret != LDB_SUCCESS) {
1804 return NT_STATUS_NO_MEMORY;
1807 if (add_outgoing && trustAuthOutgoing.data) {
1808 ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
1809 LDB_FLAG_MOD_REPLACE, NULL);
1810 if (ret != LDB_SUCCESS) {
1811 return NT_STATUS_NO_MEMORY;
1813 ret = ldb_msg_add_value(msg, "trustAuthOutgoing",
1814 &trustAuthOutgoing, NULL);
1815 if (ret != LDB_SUCCESS) {
1816 return NT_STATUS_NO_MEMORY;
1820 /* start transaction */
1821 ret = ldb_transaction_start(p_state->sam_ldb);
1822 if (ret != LDB_SUCCESS) {
1823 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1825 in_transaction = true;
1827 ret = ldb_modify(p_state->sam_ldb, msg);
1828 if (ret != LDB_SUCCESS) {
1829 DEBUG(1,("Failed to modify trusted domain record %s: %s\n",
1830 ldb_dn_get_linearized(msg->dn),
1831 ldb_errstring(p_state->sam_ldb)));
1832 if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
1833 nt_status = NT_STATUS_ACCESS_DENIED;
1835 nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1840 if (add_incoming || del_incoming) {
1841 const char *netbios_name;
1843 netbios_name = ldb_msg_find_attr_as_string(dom_msg,
1845 if (!netbios_name) {
1846 nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
1850 nt_status = update_trust_user(mem_ctx,
1855 &auth_struct.incoming);
1856 if (!NT_STATUS_IS_OK(nt_status)) {
1861 /* ok, all fine, commit transaction and return */
1862 ret = ldb_transaction_commit(p_state->sam_ldb);
1863 if (ret != LDB_SUCCESS) {
1864 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1866 in_transaction = false;
1868 nt_status = NT_STATUS_OK;
1871 if (in_transaction) {
1872 ldb_transaction_cancel(p_state->sam_ldb);
1878 lsa_SetInfomrationTrustedDomain
1880 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(
1881 struct dcesrv_call_state *dce_call,
1882 TALLOC_CTX *mem_ctx,
1883 struct lsa_SetInformationTrustedDomain *r)
1885 struct dcesrv_handle *h;
1886 struct lsa_trusted_domain_state *td_state;
1887 struct ldb_message **msgs;
1890 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle,
1891 LSA_HANDLE_TRUSTED_DOMAIN);
1893 td_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1895 /* get the trusted domain object */
1896 nt_status = get_tdo(td_state->policy->sam_ldb, mem_ctx,
1897 td_state->trusted_domain_dn,
1898 NULL, NULL, NULL, &msgs);
1899 if (!NT_STATUS_IS_OK(nt_status)) {
1900 if (NT_STATUS_EQUAL(nt_status,
1901 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1904 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1907 return setInfoTrustedDomain_base(dce_call, h, mem_ctx,
1908 msgs[0], r->in.level, r->in.info);
1913 lsa_DeleteTrustedDomain
1915 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1916 struct lsa_DeleteTrustedDomain *r)
1919 struct lsa_OpenTrustedDomain opn;
1920 struct lsa_DeleteObject del;
1921 struct dcesrv_handle *h;
1923 opn.in.handle = r->in.handle;
1924 opn.in.sid = r->in.dom_sid;
1925 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1926 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1927 if (!opn.out.trustdom_handle) {
1928 return NT_STATUS_NO_MEMORY;
1930 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1931 if (!NT_STATUS_IS_OK(status)) {
1935 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1936 talloc_steal(mem_ctx, h);
1938 del.in.handle = opn.out.trustdom_handle;
1939 del.out.handle = opn.out.trustdom_handle;
1940 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
1941 if (!NT_STATUS_IS_OK(status)) {
1944 return NT_STATUS_OK;
1947 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1948 struct ldb_message *msg,
1949 struct lsa_TrustDomainInfoInfoEx *info_ex)
1951 info_ex->domain_name.string
1952 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1953 info_ex->netbios_name.string
1954 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1956 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1957 info_ex->trust_direction
1958 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1960 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1961 info_ex->trust_attributes
1962 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1963 return NT_STATUS_OK;
1967 lsa_QueryTrustedDomainInfo
1969 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1970 struct lsa_QueryTrustedDomainInfo *r)
1972 union lsa_TrustedDomainInfo *info = NULL;
1973 struct dcesrv_handle *h;
1974 struct lsa_trusted_domain_state *trusted_domain_state;
1975 struct ldb_message *msg;
1977 struct ldb_message **res;
1978 const char *attrs[] = {
1981 "securityIdentifier",
1985 "msDs-supportedEncryptionTypes",
1989 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1991 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1993 /* pull all the user attributes */
1994 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1995 trusted_domain_state->trusted_domain_dn, &res, attrs);
1997 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2001 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
2003 return NT_STATUS_NO_MEMORY;
2005 *r->out.info = info;
2007 switch (r->in.level) {
2008 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2009 info->name.netbios_name.string
2010 = samdb_result_string(msg, "flatname", NULL);
2012 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2013 info->posix_offset.posix_offset
2014 = samdb_result_uint(msg, "posixOffset", 0);
2016 #if 0 /* Win2k3 doesn't implement this */
2017 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2018 r->out.info->info_basic.netbios_name.string
2019 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2020 r->out.info->info_basic.sid
2021 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
2024 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2025 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
2027 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2028 ZERO_STRUCT(info->full_info);
2029 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
2031 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2032 ZERO_STRUCT(info->full_info2_internal);
2033 info->full_info2_internal.posix_offset.posix_offset
2034 = samdb_result_uint(msg, "posixOffset", 0);
2035 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
2037 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2038 info->enc_types.enc_types
2039 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
2042 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2043 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2044 /* oops, we don't want to return the info after all */
2046 *r->out.info = NULL;
2047 return NT_STATUS_INVALID_PARAMETER;
2049 /* oops, we don't want to return the info after all */
2051 *r->out.info = NULL;
2052 return NT_STATUS_INVALID_INFO_CLASS;
2055 return NT_STATUS_OK;
2060 lsa_QueryTrustedDomainInfoBySid
2062 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2063 struct lsa_QueryTrustedDomainInfoBySid *r)
2066 struct lsa_OpenTrustedDomain opn;
2067 struct lsa_QueryTrustedDomainInfo query;
2068 struct dcesrv_handle *h;
2070 opn.in.handle = r->in.handle;
2071 opn.in.sid = r->in.dom_sid;
2072 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2073 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2074 if (!opn.out.trustdom_handle) {
2075 return NT_STATUS_NO_MEMORY;
2077 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
2078 if (!NT_STATUS_IS_OK(status)) {
2082 /* Ensure this handle goes away at the end of this call */
2083 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2084 talloc_steal(mem_ctx, h);
2086 query.in.trustdom_handle = opn.out.trustdom_handle;
2087 query.in.level = r->in.level;
2088 query.out.info = r->out.info;
2089 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2090 if (!NT_STATUS_IS_OK(status)) {
2094 return NT_STATUS_OK;
2098 lsa_SetTrustedDomainInfoByName
2100 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2101 TALLOC_CTX *mem_ctx,
2102 struct lsa_SetTrustedDomainInfoByName *r)
2104 struct dcesrv_handle *policy_handle;
2105 struct lsa_policy_state *policy_state;
2106 struct ldb_message **msgs;
2109 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2110 policy_state = policy_handle->data;
2112 /* get the trusted domain object */
2113 nt_status = get_tdo(policy_state->sam_ldb, mem_ctx,
2114 policy_state->domain_dn,
2115 r->in.trusted_domain->string,
2116 r->in.trusted_domain->string,
2118 if (!NT_STATUS_IS_OK(nt_status)) {
2119 if (NT_STATUS_EQUAL(nt_status,
2120 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2123 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2126 return setInfoTrustedDomain_base(dce_call, policy_handle, mem_ctx,
2127 msgs[0], r->in.level, r->in.info);
2131 lsa_QueryTrustedDomainInfoByName
2133 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2134 TALLOC_CTX *mem_ctx,
2135 struct lsa_QueryTrustedDomainInfoByName *r)
2138 struct lsa_OpenTrustedDomainByName opn;
2139 struct lsa_QueryTrustedDomainInfo query;
2140 struct dcesrv_handle *h;
2142 opn.in.handle = r->in.handle;
2143 opn.in.name = *r->in.trusted_domain;
2144 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2145 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2146 if (!opn.out.trustdom_handle) {
2147 return NT_STATUS_NO_MEMORY;
2149 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
2150 if (!NT_STATUS_IS_OK(status)) {
2154 /* Ensure this handle goes away at the end of this call */
2155 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2156 talloc_steal(mem_ctx, h);
2158 query.in.trustdom_handle = opn.out.trustdom_handle;
2159 query.in.level = r->in.level;
2160 query.out.info = r->out.info;
2161 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2162 if (!NT_STATUS_IS_OK(status)) {
2166 return NT_STATUS_OK;
2170 lsa_CloseTrustedDomainEx
2172 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
2173 TALLOC_CTX *mem_ctx,
2174 struct lsa_CloseTrustedDomainEx *r)
2176 /* The result of a bad hair day from an IDL programmer? Not
2177 * implmented in Win2k3. You should always just lsa_Close
2179 return NT_STATUS_NOT_IMPLEMENTED;
2184 comparison function for sorting lsa_DomainInformation array
2186 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
2188 return strcasecmp_m(e1->name.string, e2->name.string);
2194 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2195 struct lsa_EnumTrustDom *r)
2197 struct dcesrv_handle *policy_handle;
2198 struct lsa_DomainInfo *entries;
2199 struct lsa_policy_state *policy_state;
2200 struct ldb_message **domains;
2201 const char *attrs[] = {
2203 "securityIdentifier",
2210 *r->out.resume_handle = 0;
2212 r->out.domains->domains = NULL;
2213 r->out.domains->count = 0;
2215 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2217 policy_state = policy_handle->data;
2219 /* search for all users in this domain. This could possibly be cached and
2220 resumed based on resume_key */
2221 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2222 "objectclass=trustedDomain");
2224 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2227 /* convert to lsa_TrustInformation format */
2228 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
2230 return NT_STATUS_NO_MEMORY;
2232 for (i=0;i<count;i++) {
2233 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
2234 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
2237 /* sort the results by name */
2238 TYPESAFE_QSORT(entries, count, compare_DomainInfo);
2240 if (*r->in.resume_handle >= count) {
2241 *r->out.resume_handle = -1;
2243 return NT_STATUS_NO_MORE_ENTRIES;
2246 /* return the rest, limit by max_size. Note that we
2247 use the w2k3 element size value of 60 */
2248 r->out.domains->count = count - *r->in.resume_handle;
2249 r->out.domains->count = MIN(r->out.domains->count,
2250 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
2252 r->out.domains->domains = entries + *r->in.resume_handle;
2253 r->out.domains->count = r->out.domains->count;
2255 if (r->out.domains->count < count - *r->in.resume_handle) {
2256 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2257 return STATUS_MORE_ENTRIES;
2260 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2261 * always be larger than the previous input resume handle, in
2262 * particular when hitting the last query it is vital to set the
2263 * resume handle correctly to avoid infinite client loops, as
2264 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2265 * status is NT_STATUS_OK - gd */
2267 *r->out.resume_handle = (uint32_t)-1;
2269 return NT_STATUS_OK;
2273 comparison function for sorting lsa_DomainInformation array
2275 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
2277 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
2281 lsa_EnumTrustedDomainsEx
2283 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2284 struct lsa_EnumTrustedDomainsEx *r)
2286 struct dcesrv_handle *policy_handle;
2287 struct lsa_TrustDomainInfoInfoEx *entries;
2288 struct lsa_policy_state *policy_state;
2289 struct ldb_message **domains;
2290 const char *attrs[] = {
2293 "securityIdentifier",
2303 *r->out.resume_handle = 0;
2305 r->out.domains->domains = NULL;
2306 r->out.domains->count = 0;
2308 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2310 policy_state = policy_handle->data;
2312 /* search for all users in this domain. This could possibly be cached and
2313 resumed based on resume_key */
2314 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2315 "objectclass=trustedDomain");
2317 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2320 /* convert to lsa_DomainInformation format */
2321 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
2323 return NT_STATUS_NO_MEMORY;
2325 for (i=0;i<count;i++) {
2326 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
2327 if (!NT_STATUS_IS_OK(nt_status)) {
2332 /* sort the results by name */
2333 TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
2335 if (*r->in.resume_handle >= count) {
2336 *r->out.resume_handle = -1;
2338 return NT_STATUS_NO_MORE_ENTRIES;
2341 /* return the rest, limit by max_size. Note that we
2342 use the w2k3 element size value of 60 */
2343 r->out.domains->count = count - *r->in.resume_handle;
2344 r->out.domains->count = MIN(r->out.domains->count,
2345 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
2347 r->out.domains->domains = entries + *r->in.resume_handle;
2348 r->out.domains->count = r->out.domains->count;
2350 if (r->out.domains->count < count - *r->in.resume_handle) {
2351 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2352 return STATUS_MORE_ENTRIES;
2355 return NT_STATUS_OK;
2362 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2363 struct lsa_OpenAccount *r)
2365 struct dcesrv_handle *h, *ah;
2366 struct lsa_policy_state *state;
2367 struct lsa_account_state *astate;
2369 ZERO_STRUCTP(r->out.acct_handle);
2371 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2375 astate = talloc(dce_call->conn, struct lsa_account_state);
2376 if (astate == NULL) {
2377 return NT_STATUS_NO_MEMORY;
2380 astate->account_sid = dom_sid_dup(astate, r->in.sid);
2381 if (astate->account_sid == NULL) {
2382 talloc_free(astate);
2383 return NT_STATUS_NO_MEMORY;
2386 astate->policy = talloc_reference(astate, state);
2387 astate->access_mask = r->in.access_mask;
2389 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
2391 talloc_free(astate);
2392 return NT_STATUS_NO_MEMORY;
2395 ah->data = talloc_steal(ah, astate);
2397 *r->out.acct_handle = ah->wire_handle;
2399 return NT_STATUS_OK;
2404 lsa_EnumPrivsAccount
2406 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
2407 TALLOC_CTX *mem_ctx,
2408 struct lsa_EnumPrivsAccount *r)
2410 struct dcesrv_handle *h;
2411 struct lsa_account_state *astate;
2414 struct ldb_message **res;
2415 const char * const attrs[] = { "privilege", NULL};
2416 struct ldb_message_element *el;
2418 struct lsa_PrivilegeSet *privs;
2420 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2424 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2425 if (privs == NULL) {
2426 return NT_STATUS_NO_MEMORY;
2432 *r->out.privs = privs;
2434 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
2435 if (sidstr == NULL) {
2436 return NT_STATUS_NO_MEMORY;
2439 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
2440 "objectSid=%s", sidstr);
2442 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2445 return NT_STATUS_OK;
2448 el = ldb_msg_find_element(res[0], "privilege");
2449 if (el == NULL || el->num_values == 0) {
2450 return NT_STATUS_OK;
2453 privs->set = talloc_array(privs,
2454 struct lsa_LUIDAttribute, el->num_values);
2455 if (privs->set == NULL) {
2456 return NT_STATUS_NO_MEMORY;
2460 for (i=0;i<el->num_values;i++) {
2461 int id = sec_privilege_id((const char *)el->values[i].data);
2462 if (id == SEC_PRIV_INVALID) {
2463 /* Perhaps an account right, not a privilege */
2466 privs->set[j].attribute = 0;
2467 privs->set[j].luid.low = id;
2468 privs->set[j].luid.high = 0;
2474 return NT_STATUS_OK;
2478 lsa_EnumAccountRights
2480 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
2481 TALLOC_CTX *mem_ctx,
2482 struct lsa_EnumAccountRights *r)
2484 struct dcesrv_handle *h;
2485 struct lsa_policy_state *state;
2488 struct ldb_message **res;
2489 const char * const attrs[] = { "privilege", NULL};
2491 struct ldb_message_element *el;
2493 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2497 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
2498 if (sidstr == NULL) {
2499 return NT_STATUS_NO_MEMORY;
2502 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2503 "(&(objectSid=%s)(privilege=*))", sidstr);
2505 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2508 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
2509 dom_sid_string(mem_ctx, r->in.sid),
2510 ldb_errstring(state->pdb)));
2511 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2514 el = ldb_msg_find_element(res[0], "privilege");
2515 if (el == NULL || el->num_values == 0) {
2516 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2519 r->out.rights->count = el->num_values;
2520 r->out.rights->names = talloc_array(r->out.rights,
2521 struct lsa_StringLarge, r->out.rights->count);
2522 if (r->out.rights->names == NULL) {
2523 return NT_STATUS_NO_MEMORY;
2526 for (i=0;i<el->num_values;i++) {
2527 r->out.rights->names[i].string = (const char *)el->values[i].data;
2530 return NT_STATUS_OK;
2536 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
2538 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
2539 TALLOC_CTX *mem_ctx,
2540 struct lsa_policy_state *state,
2542 struct dom_sid *sid,
2543 const struct lsa_RightSet *rights)
2545 const char *sidstr, *sidndrstr;
2546 struct ldb_message *msg;
2547 struct ldb_message_element *el;
2550 struct lsa_EnumAccountRights r2;
2553 if (security_session_user_level(dce_call->conn->auth_state.session_info, NULL) <
2554 SECURITY_ADMINISTRATOR) {
2555 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
2556 return NT_STATUS_ACCESS_DENIED;
2559 msg = ldb_msg_new(mem_ctx);
2561 return NT_STATUS_NO_MEMORY;
2564 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
2565 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg);
2567 sidstr = dom_sid_string(msg, sid);
2568 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg);
2570 dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
2571 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg);
2573 msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
2574 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg);
2576 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
2579 r2.in.handle = &state->handle->wire_handle;
2581 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
2583 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2584 if (!NT_STATUS_IS_OK(status)) {
2585 ZERO_STRUCTP(r2.out.rights);
2589 for (i=0;i<rights->count;i++) {
2590 if (sec_privilege_id(rights->names[i].string) == SEC_PRIV_INVALID) {
2591 if (sec_right_bit(rights->names[i].string) == 0) {
2593 return NT_STATUS_NO_SUCH_PRIVILEGE;
2597 return NT_STATUS_NO_SUCH_PRIVILEGE;
2600 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
2602 for (j=0;j<r2.out.rights->count;j++) {
2603 if (strcasecmp_m(r2.out.rights->names[j].string,
2604 rights->names[i].string) == 0) {
2608 if (j != r2.out.rights->count) continue;
2611 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2612 if (ret != LDB_SUCCESS) {
2614 return NT_STATUS_NO_MEMORY;
2618 el = ldb_msg_find_element(msg, "privilege");
2621 return NT_STATUS_OK;
2624 el->flags = ldb_flag;
2626 ret = ldb_modify(state->pdb, msg);
2627 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
2628 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
2630 return NT_STATUS_NO_MEMORY;
2632 samdb_msg_add_string(state->pdb, msg, msg, "comment", "added via LSA");
2633 ret = ldb_add(state->pdb, msg);
2635 if (ret != LDB_SUCCESS) {
2636 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2638 return NT_STATUS_OK;
2640 DEBUG(3, ("Could not %s attributes from %s: %s",
2641 LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2642 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
2644 return NT_STATUS_UNEXPECTED_IO_ERROR;
2648 return NT_STATUS_OK;
2652 lsa_AddPrivilegesToAccount
2654 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2655 struct lsa_AddPrivilegesToAccount *r)
2657 struct lsa_RightSet rights;
2658 struct dcesrv_handle *h;
2659 struct lsa_account_state *astate;
2662 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2666 rights.count = r->in.privs->count;
2667 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2668 if (rights.names == NULL) {
2669 return NT_STATUS_NO_MEMORY;
2671 for (i=0;i<rights.count;i++) {
2672 int id = r->in.privs->set[i].luid.low;
2673 if (r->in.privs->set[i].luid.high) {
2674 return NT_STATUS_NO_SUCH_PRIVILEGE;
2676 rights.names[i].string = sec_privilege_name(id);
2677 if (rights.names[i].string == NULL) {
2678 return NT_STATUS_NO_SUCH_PRIVILEGE;
2682 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2683 LDB_FLAG_MOD_ADD, astate->account_sid,
2689 lsa_RemovePrivilegesFromAccount
2691 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2692 struct lsa_RemovePrivilegesFromAccount *r)
2694 struct lsa_RightSet *rights;
2695 struct dcesrv_handle *h;
2696 struct lsa_account_state *astate;
2699 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2703 rights = talloc(mem_ctx, struct lsa_RightSet);
2705 if (r->in.remove_all == 1 &&
2706 r->in.privs == NULL) {
2707 struct lsa_EnumAccountRights r2;
2710 r2.in.handle = &astate->policy->handle->wire_handle;
2711 r2.in.sid = astate->account_sid;
2712 r2.out.rights = rights;
2714 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2715 if (!NT_STATUS_IS_OK(status)) {
2719 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2720 LDB_FLAG_MOD_DELETE, astate->account_sid,
2724 if (r->in.remove_all != 0) {
2725 return NT_STATUS_INVALID_PARAMETER;
2728 rights->count = r->in.privs->count;
2729 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2730 if (rights->names == NULL) {
2731 return NT_STATUS_NO_MEMORY;
2733 for (i=0;i<rights->count;i++) {
2734 int id = r->in.privs->set[i].luid.low;
2735 if (r->in.privs->set[i].luid.high) {
2736 return NT_STATUS_NO_SUCH_PRIVILEGE;
2738 rights->names[i].string = sec_privilege_name(id);
2739 if (rights->names[i].string == NULL) {
2740 return NT_STATUS_NO_SUCH_PRIVILEGE;
2744 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2745 LDB_FLAG_MOD_DELETE, astate->account_sid,
2751 lsa_GetQuotasForAccount
2753 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2754 struct lsa_GetQuotasForAccount *r)
2756 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2761 lsa_SetQuotasForAccount
2763 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2764 struct lsa_SetQuotasForAccount *r)
2766 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2771 lsa_GetSystemAccessAccount
2773 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2774 struct lsa_GetSystemAccessAccount *r)
2776 struct dcesrv_handle *h;
2777 struct lsa_account_state *astate;
2780 struct ldb_message **res;
2781 const char * const attrs[] = { "privilege", NULL};
2782 struct ldb_message_element *el;
2785 *(r->out.access_mask) = 0x00000000;
2787 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2791 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
2792 if (sidstr == NULL) {
2793 return NT_STATUS_NO_MEMORY;
2796 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
2797 "objectSid=%s", sidstr);
2799 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2802 return NT_STATUS_OK;
2805 el = ldb_msg_find_element(res[0], "privilege");
2806 if (el == NULL || el->num_values == 0) {
2807 return NT_STATUS_OK;
2810 for (i=0;i<el->num_values;i++) {
2811 uint32_t right_bit = sec_right_bit((const char *)el->values[i].data);
2812 if (right_bit == 0) {
2813 /* Perhaps an privilege, not a right */
2816 *(r->out.access_mask) |= right_bit;
2819 return NT_STATUS_OK;
2824 lsa_SetSystemAccessAccount
2826 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2827 struct lsa_SetSystemAccessAccount *r)
2829 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2836 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2837 struct lsa_CreateSecret *r)
2839 struct dcesrv_handle *policy_handle;
2840 struct lsa_policy_state *policy_state;
2841 struct lsa_secret_state *secret_state;
2842 struct dcesrv_handle *handle;
2843 struct ldb_message **msgs, *msg;
2844 const char *attrs[] = {
2852 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2853 ZERO_STRUCTP(r->out.sec_handle);
2855 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
2857 case SECURITY_SYSTEM:
2858 case SECURITY_ADMINISTRATOR:
2861 /* Users and annonymous are not allowed create secrets */
2862 return NT_STATUS_ACCESS_DENIED;
2865 policy_state = policy_handle->data;
2867 if (!r->in.name.string) {
2868 return NT_STATUS_INVALID_PARAMETER;
2871 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2872 if (!secret_state) {
2873 return NT_STATUS_NO_MEMORY;
2875 secret_state->policy = policy_state;
2877 msg = ldb_msg_new(mem_ctx);
2879 return NT_STATUS_NO_MEMORY;
2882 if (strncmp("G$", r->in.name.string, 2) == 0) {
2884 name = &r->in.name.string[2];
2885 /* 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) */
2886 secret_state->sam_ldb = talloc_reference(secret_state,
2887 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
2888 secret_state->global = true;
2890 if (strlen(name) < 1) {
2891 return NT_STATUS_INVALID_PARAMETER;
2894 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2895 /* search for the secret record */
2896 ret = gendb_search(secret_state->sam_ldb,
2897 mem_ctx, policy_state->system_dn, &msgs, attrs,
2898 "(&(cn=%s)(objectclass=secret))",
2901 return NT_STATUS_OBJECT_NAME_COLLISION;
2905 DEBUG(0,("Failure searching for CN=%s: %s\n",
2906 name2, ldb_errstring(secret_state->sam_ldb)));
2907 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2910 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2911 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2912 return NT_STATUS_NO_MEMORY;
2915 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2918 secret_state->global = false;
2920 name = r->in.name.string;
2921 if (strlen(name) < 1) {
2922 return NT_STATUS_INVALID_PARAMETER;
2925 secret_state->sam_ldb = talloc_reference(secret_state,
2926 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2927 /* search for the secret record */
2928 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2929 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2931 "(&(cn=%s)(objectclass=secret))",
2932 ldb_binary_encode_string(mem_ctx, name));
2934 return NT_STATUS_OBJECT_NAME_COLLISION;
2938 DEBUG(0,("Failure searching for CN=%s: %s\n",
2939 name, ldb_errstring(secret_state->sam_ldb)));
2940 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2943 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2944 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2947 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2949 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2951 /* create the secret */
2952 ret = dsdb_add(secret_state->sam_ldb, msg, DSDB_MODIFY_RELAX);
2953 if (ret != LDB_SUCCESS) {
2954 DEBUG(0,("Failed to create secret record %s: %s\n",
2955 ldb_dn_get_linearized(msg->dn),
2956 ldb_errstring(secret_state->sam_ldb)));
2957 return NT_STATUS_ACCESS_DENIED;
2960 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2962 return NT_STATUS_NO_MEMORY;
2965 handle->data = talloc_steal(handle, secret_state);
2967 secret_state->access_mask = r->in.access_mask;
2968 secret_state->policy = talloc_reference(secret_state, policy_state);
2970 *r->out.sec_handle = handle->wire_handle;
2972 return NT_STATUS_OK;
2979 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2980 struct lsa_OpenSecret *r)
2982 struct dcesrv_handle *policy_handle;
2984 struct lsa_policy_state *policy_state;
2985 struct lsa_secret_state *secret_state;
2986 struct dcesrv_handle *handle;
2987 struct ldb_message **msgs;
2988 const char *attrs[] = {
2996 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2997 ZERO_STRUCTP(r->out.sec_handle);
2998 policy_state = policy_handle->data;
3000 if (!r->in.name.string) {
3001 return NT_STATUS_INVALID_PARAMETER;
3004 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
3006 case SECURITY_SYSTEM:
3007 case SECURITY_ADMINISTRATOR:
3010 /* Users and annonymous are not allowed to access secrets */
3011 return NT_STATUS_ACCESS_DENIED;
3014 secret_state = talloc(mem_ctx, struct lsa_secret_state);
3015 if (!secret_state) {
3016 return NT_STATUS_NO_MEMORY;
3018 secret_state->policy = policy_state;
3020 if (strncmp("G$", r->in.name.string, 2) == 0) {
3021 name = &r->in.name.string[2];
3022 /* 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) */
3023 secret_state->sam_ldb = talloc_reference(secret_state,
3024 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
3025 secret_state->global = true;
3027 if (strlen(name) < 1) {
3028 return NT_STATUS_INVALID_PARAMETER;
3031 /* search for the secret record */
3032 ret = gendb_search(secret_state->sam_ldb,
3033 mem_ctx, policy_state->system_dn, &msgs, attrs,
3034 "(&(cn=%s Secret)(objectclass=secret))",
3035 ldb_binary_encode_string(mem_ctx, name));
3037 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3041 DEBUG(0,("Found %d records matching DN %s\n", ret,
3042 ldb_dn_get_linearized(policy_state->system_dn)));
3043 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3047 secret_state->global = false;
3048 secret_state->sam_ldb = talloc_reference(secret_state,
3049 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
3051 name = r->in.name.string;
3052 if (strlen(name) < 1) {
3053 return NT_STATUS_INVALID_PARAMETER;
3056 /* search for the secret record */
3057 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
3058 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
3060 "(&(cn=%s)(objectclass=secret))",
3061 ldb_binary_encode_string(mem_ctx, name));
3063 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3067 DEBUG(0,("Found %d records matching CN=%s\n",
3068 ret, ldb_binary_encode_string(mem_ctx, name)));
3069 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3073 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
3075 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
3077 return NT_STATUS_NO_MEMORY;
3080 handle->data = talloc_steal(handle, secret_state);
3082 secret_state->access_mask = r->in.access_mask;
3083 secret_state->policy = talloc_reference(secret_state, policy_state);
3085 *r->out.sec_handle = handle->wire_handle;
3087 return NT_STATUS_OK;
3094 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3095 struct lsa_SetSecret *r)
3098 struct dcesrv_handle *h;
3099 struct lsa_secret_state *secret_state;
3100 struct ldb_message *msg;
3101 DATA_BLOB session_key;
3102 DATA_BLOB crypt_secret, secret;
3105 NTSTATUS status = NT_STATUS_OK;
3107 struct timeval now = timeval_current();
3108 NTTIME nt_now = timeval_to_nttime(&now);
3110 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3112 secret_state = h->data;
3114 msg = ldb_msg_new(mem_ctx);
3116 return NT_STATUS_NO_MEMORY;
3119 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
3121 return NT_STATUS_NO_MEMORY;
3123 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
3124 if (!NT_STATUS_IS_OK(status)) {
3128 if (r->in.old_val) {
3130 crypt_secret.data = r->in.old_val->data;
3131 crypt_secret.length = r->in.old_val->size;
3133 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3134 if (!NT_STATUS_IS_OK(status)) {
3138 val.data = secret.data;
3139 val.length = secret.length;
3142 if (samdb_msg_add_value(secret_state->sam_ldb,
3143 mem_ctx, msg, "priorValue", &val) != LDB_SUCCESS) {
3144 return NT_STATUS_NO_MEMORY;
3147 /* set old value mtime */
3148 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3149 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3150 return NT_STATUS_NO_MEMORY;
3154 /* If the old value is not set, then migrate the
3155 * current value to the old value */
3156 const struct ldb_val *old_val;
3157 NTTIME last_set_time;
3158 struct ldb_message **res;
3159 const char *attrs[] = {
3165 /* search for the secret record */
3166 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
3167 secret_state->secret_dn, &res, attrs);
3169 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3173 DEBUG(0,("Found %d records matching dn=%s\n", ret,
3174 ldb_dn_get_linearized(secret_state->secret_dn)));
3175 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3178 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3179 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3183 if (samdb_msg_add_value(secret_state->sam_ldb,
3184 mem_ctx, msg, "priorValue",
3186 return NT_STATUS_NO_MEMORY;
3189 if (samdb_msg_add_delete(secret_state->sam_ldb,
3190 mem_ctx, msg, "priorValue")) {
3191 return NT_STATUS_NO_MEMORY;
3196 /* set old value mtime */
3197 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
3198 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3199 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
3200 return NT_STATUS_NO_MEMORY;
3203 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3204 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3205 return NT_STATUS_NO_MEMORY;
3210 if (r->in.new_val) {
3212 crypt_secret.data = r->in.new_val->data;
3213 crypt_secret.length = r->in.new_val->size;
3215 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3216 if (!NT_STATUS_IS_OK(status)) {
3220 val.data = secret.data;
3221 val.length = secret.length;
3224 if (samdb_msg_add_value(secret_state->sam_ldb,
3225 mem_ctx, msg, "currentValue", &val) != LDB_SUCCESS) {
3226 return NT_STATUS_NO_MEMORY;
3229 /* set new value mtime */
3230 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3231 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3232 return NT_STATUS_NO_MEMORY;
3236 /* NULL out the NEW value */
3237 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3238 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3239 return NT_STATUS_NO_MEMORY;
3241 if (samdb_msg_add_delete(secret_state->sam_ldb,
3242 mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
3243 return NT_STATUS_NO_MEMORY;
3247 /* modify the samdb record */
3248 ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
3249 if (ret != LDB_SUCCESS) {
3250 /* we really need samdb.c to return NTSTATUS */
3251 return NT_STATUS_UNSUCCESSFUL;
3254 return NT_STATUS_OK;
3261 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3262 struct lsa_QuerySecret *r)
3264 struct dcesrv_handle *h;
3265 struct lsa_secret_state *secret_state;
3266 struct ldb_message *msg;
3267 DATA_BLOB session_key;
3268 DATA_BLOB crypt_secret, secret;
3270 struct ldb_message **res;
3271 const char *attrs[] = {
3281 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3283 /* Ensure user is permitted to read this... */
3284 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
3286 case SECURITY_SYSTEM:
3287 case SECURITY_ADMINISTRATOR:
3290 /* Users and annonymous are not allowed to read secrets */
3291 return NT_STATUS_ACCESS_DENIED;
3294 secret_state = h->data;
3296 /* pull all the user attributes */
3297 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
3298 secret_state->secret_dn, &res, attrs);
3300 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3304 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
3305 if (!NT_STATUS_IS_OK(nt_status)) {
3309 if (r->in.old_val) {
3310 const struct ldb_val *prior_val;
3311 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3312 if (!r->out.old_val) {
3313 return NT_STATUS_NO_MEMORY;
3315 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
3317 if (prior_val && prior_val->length) {
3318 secret.data = prior_val->data;
3319 secret.length = prior_val->length;
3322 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3323 if (!crypt_secret.length) {
3324 return NT_STATUS_NO_MEMORY;
3326 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3327 if (!r->out.old_val->buf) {
3328 return NT_STATUS_NO_MEMORY;
3330 r->out.old_val->buf->size = crypt_secret.length;
3331 r->out.old_val->buf->length = crypt_secret.length;
3332 r->out.old_val->buf->data = crypt_secret.data;
3336 if (r->in.old_mtime) {
3337 r->out.old_mtime = talloc(mem_ctx, NTTIME);
3338 if (!r->out.old_mtime) {
3339 return NT_STATUS_NO_MEMORY;
3341 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
3344 if (r->in.new_val) {
3345 const struct ldb_val *new_val;
3346 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3347 if (!r->out.new_val) {
3348 return NT_STATUS_NO_MEMORY;
3351 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3353 if (new_val && new_val->length) {
3354 secret.data = new_val->data;
3355 secret.length = new_val->length;
3358 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3359 if (!crypt_secret.length) {
3360 return NT_STATUS_NO_MEMORY;
3362 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3363 if (!r->out.new_val->buf) {
3364 return NT_STATUS_NO_MEMORY;
3366 r->out.new_val->buf->length = crypt_secret.length;
3367 r->out.new_val->buf->size = crypt_secret.length;
3368 r->out.new_val->buf->data = crypt_secret.data;
3372 if (r->in.new_mtime) {
3373 r->out.new_mtime = talloc(mem_ctx, NTTIME);
3374 if (!r->out.new_mtime) {
3375 return NT_STATUS_NO_MEMORY;
3377 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3380 return NT_STATUS_OK;
3387 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
3388 TALLOC_CTX *mem_ctx,
3389 struct lsa_LookupPrivValue *r)
3391 struct dcesrv_handle *h;
3392 struct lsa_policy_state *state;
3395 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3399 id = sec_privilege_id(r->in.name->string);
3400 if (id == SEC_PRIV_INVALID) {
3401 return NT_STATUS_NO_SUCH_PRIVILEGE;
3404 r->out.luid->low = id;
3405 r->out.luid->high = 0;
3407 return NT_STATUS_OK;
3414 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
3415 TALLOC_CTX *mem_ctx,
3416 struct lsa_LookupPrivName *r)
3418 struct dcesrv_handle *h;
3419 struct lsa_policy_state *state;
3420 struct lsa_StringLarge *name;
3421 const char *privname;
3423 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3427 if (r->in.luid->high != 0) {
3428 return NT_STATUS_NO_SUCH_PRIVILEGE;
3431 privname = sec_privilege_name(r->in.luid->low);
3432 if (privname == NULL) {
3433 return NT_STATUS_NO_SUCH_PRIVILEGE;
3436 name = talloc(mem_ctx, struct lsa_StringLarge);
3438 return NT_STATUS_NO_MEMORY;
3441 name->string = privname;
3443 *r->out.name = name;
3445 return NT_STATUS_OK;
3450 lsa_LookupPrivDisplayName
3452 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
3453 TALLOC_CTX *mem_ctx,
3454 struct lsa_LookupPrivDisplayName *r)
3456 struct dcesrv_handle *h;
3457 struct lsa_policy_state *state;
3458 struct lsa_StringLarge *disp_name = NULL;
3459 enum sec_privilege id;
3461 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3465 id = sec_privilege_id(r->in.name->string);
3466 if (id == SEC_PRIV_INVALID) {
3467 return NT_STATUS_NO_SUCH_PRIVILEGE;
3470 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
3471 if (disp_name == NULL) {
3472 return NT_STATUS_NO_MEMORY;
3475 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
3476 if (disp_name->string == NULL) {
3477 return NT_STATUS_INTERNAL_ERROR;
3480 *r->out.disp_name = disp_name;
3481 *r->out.returned_language_id = 0;
3483 return NT_STATUS_OK;
3488 lsa_EnumAccountsWithUserRight
3490 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
3491 TALLOC_CTX *mem_ctx,
3492 struct lsa_EnumAccountsWithUserRight *r)
3494 struct dcesrv_handle *h;
3495 struct lsa_policy_state *state;
3497 struct ldb_message **res;
3498 const char * const attrs[] = { "objectSid", NULL};
3499 const char *privname;
3501 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3505 if (r->in.name == NULL) {
3506 return NT_STATUS_NO_SUCH_PRIVILEGE;
3509 privname = r->in.name->string;
3510 if (sec_privilege_id(privname) == SEC_PRIV_INVALID && sec_right_bit(privname) == 0) {
3511 return NT_STATUS_NO_SUCH_PRIVILEGE;
3514 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
3515 "privilege=%s", privname);
3517 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3520 return NT_STATUS_NO_MORE_ENTRIES;
3523 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
3524 if (r->out.sids->sids == NULL) {
3525 return NT_STATUS_NO_MEMORY;
3527 for (i=0;i<ret;i++) {
3528 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
3529 res[i], "objectSid");
3530 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
3532 r->out.sids->num_sids = ret;
3534 return NT_STATUS_OK;
3539 lsa_AddAccountRights
3541 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
3542 TALLOC_CTX *mem_ctx,
3543 struct lsa_AddAccountRights *r)
3545 struct dcesrv_handle *h;
3546 struct lsa_policy_state *state;
3548 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3552 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3554 r->in.sid, r->in.rights);
3559 lsa_RemoveAccountRights
3561 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
3562 TALLOC_CTX *mem_ctx,
3563 struct lsa_RemoveAccountRights *r)
3565 struct dcesrv_handle *h;
3566 struct lsa_policy_state *state;
3568 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3572 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3573 LDB_FLAG_MOD_DELETE,
3574 r->in.sid, r->in.rights);
3579 lsa_StorePrivateData
3581 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3582 struct lsa_StorePrivateData *r)
3584 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3589 lsa_RetrievePrivateData
3591 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3592 struct lsa_RetrievePrivateData *r)
3594 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3601 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3602 struct lsa_GetUserName *r)
3604 NTSTATUS status = NT_STATUS_OK;
3605 const char *account_name;
3606 const char *authority_name;
3607 struct lsa_String *_account_name;
3608 struct lsa_String *_authority_name = NULL;
3610 /* this is what w2k3 does */
3611 r->out.account_name = r->in.account_name;
3612 r->out.authority_name = r->in.authority_name;
3614 if (r->in.account_name
3615 && *r->in.account_name
3616 /* && *(*r->in.account_name)->string */
3618 return NT_STATUS_INVALID_PARAMETER;
3621 if (r->in.authority_name
3622 && *r->in.authority_name
3623 /* && *(*r->in.authority_name)->string */
3625 return NT_STATUS_INVALID_PARAMETER;
3628 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
3629 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
3631 _account_name = talloc(mem_ctx, struct lsa_String);
3632 NT_STATUS_HAVE_NO_MEMORY(_account_name);
3633 _account_name->string = account_name;
3635 if (r->in.authority_name) {
3636 _authority_name = talloc(mem_ctx, struct lsa_String);
3637 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
3638 _authority_name->string = authority_name;
3641 *r->out.account_name = _account_name;
3642 if (r->out.authority_name) {
3643 *r->out.authority_name = _authority_name;
3652 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
3653 TALLOC_CTX *mem_ctx,
3654 struct lsa_SetInfoPolicy2 *r)
3656 /* need to support these */
3657 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3661 lsa_QueryDomainInformationPolicy
3663 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3664 TALLOC_CTX *mem_ctx,
3665 struct lsa_QueryDomainInformationPolicy *r)
3667 union lsa_DomainInformationPolicy *info;
3669 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
3671 return NT_STATUS_NO_MEMORY;
3674 switch (r->in.level) {
3675 case LSA_DOMAIN_INFO_POLICY_EFS:
3677 *r->out.info = NULL;
3678 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3679 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
3681 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
3682 struct smb_krb5_context *smb_krb5_context;
3683 int ret = smb_krb5_init_context(mem_ctx,
3684 dce_call->event_ctx,
3685 dce_call->conn->dce_ctx->lp_ctx,
3689 *r->out.info = NULL;
3690 return NT_STATUS_INTERNAL_ERROR;
3692 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
3693 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3694 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3695 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
3696 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
3697 talloc_free(smb_krb5_context);
3698 *r->out.info = info;
3699 return NT_STATUS_OK;
3703 *r->out.info = NULL;
3704 return NT_STATUS_INVALID_INFO_CLASS;
3709 lsa_SetDomInfoPolicy
3711 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3712 TALLOC_CTX *mem_ctx,
3713 struct lsa_SetDomainInformationPolicy *r)
3715 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3721 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3722 TALLOC_CTX *mem_ctx,
3723 struct lsa_TestCall *r)
3725 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3731 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3732 struct lsa_CREDRWRITE *r)
3734 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3741 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3742 struct lsa_CREDRREAD *r)
3744 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3751 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3752 struct lsa_CREDRENUMERATE *r)
3754 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3759 lsa_CREDRWRITEDOMAINCREDENTIALS
3761 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3762 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3764 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3769 lsa_CREDRREADDOMAINCREDENTIALS
3771 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3772 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3774 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3781 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3782 struct lsa_CREDRDELETE *r)
3784 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3789 lsa_CREDRGETTARGETINFO
3791 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3792 struct lsa_CREDRGETTARGETINFO *r)
3794 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3799 lsa_CREDRPROFILELOADED
3801 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3802 struct lsa_CREDRPROFILELOADED *r)
3804 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3809 lsa_CREDRGETSESSIONTYPES
3811 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3812 struct lsa_CREDRGETSESSIONTYPES *r)
3814 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3819 lsa_LSARREGISTERAUDITEVENT
3821 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3822 struct lsa_LSARREGISTERAUDITEVENT *r)
3824 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3829 lsa_LSARGENAUDITEVENT
3831 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3832 struct lsa_LSARGENAUDITEVENT *r)
3834 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3839 lsa_LSARUNREGISTERAUDITEVENT
3841 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3842 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3844 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3849 lsa_lsaRQueryForestTrustInformation
3851 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3852 struct lsa_lsaRQueryForestTrustInformation *r)
3854 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3857 #define DNS_CMP_MATCH 0
3858 #define DNS_CMP_FIRST_IS_CHILD 1
3859 #define DNS_CMP_SECOND_IS_CHILD 2
3860 #define DNS_CMP_NO_MATCH 3
3862 /* this function assumes names are well formed DNS names.
3863 * it doesn't validate them */
3864 static int dns_cmp(const char *s1, size_t l1,
3865 const char *s2, size_t l2)
3867 const char *p1, *p2;
3872 if (strcasecmp_m(s1, s2) == 0) {
3873 return DNS_CMP_MATCH;
3875 return DNS_CMP_NO_MATCH;
3883 cret = DNS_CMP_FIRST_IS_CHILD;
3889 cret = DNS_CMP_SECOND_IS_CHILD;
3892 if (p1[t1 - t2 - 1] != '.') {
3893 return DNS_CMP_NO_MATCH;
3896 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
3900 return DNS_CMP_NO_MATCH;
3903 /* decode all TDOs forest trust info blobs */
3904 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3905 struct ldb_message *msg,
3906 struct ForestTrustInfo *info)
3908 const struct ldb_val *ft_blob;
3909 enum ndr_err_code ndr_err;
3911 ft_blob = ldb_msg_find_ldb_val(msg, "msDS-TrustForestTrustInfo");
3912 if (!ft_blob || !ft_blob->data) {
3913 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3915 /* ldb_val is equivalent to DATA_BLOB */
3916 ndr_err = ndr_pull_struct_blob_all(ft_blob, mem_ctx, info,
3917 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3918 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3919 return NT_STATUS_INVALID_DOMAIN_STATE;
3922 return NT_STATUS_OK;
3925 static NTSTATUS own_ft_info(struct lsa_policy_state *ps,
3926 struct ForestTrustInfo *fti)
3928 struct ForestTrustDataDomainInfo *info;
3929 struct ForestTrustInfoRecord *rec;
3933 fti->records = talloc_array(fti,
3934 struct ForestTrustInfoRecordArmor, 2);
3935 if (!fti->records) {
3936 return NT_STATUS_NO_MEMORY;
3940 rec = &fti->records[0].record;
3944 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3946 rec->data.name.string = talloc_strdup(fti, ps->forest_dns);
3947 if (!rec->data.name.string) {
3948 return NT_STATUS_NO_MEMORY;
3950 rec->data.name.size = strlen(rec->data.name.string);
3953 rec = &fti->records[1].record;
3957 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3959 info = &rec->data.info;
3961 info->sid = *ps->domain_sid;
3962 info->dns_name.string = talloc_strdup(fti, ps->domain_dns);
3963 if (!info->dns_name.string) {
3964 return NT_STATUS_NO_MEMORY;
3966 info->dns_name.size = strlen(info->dns_name.string);
3967 info->netbios_name.string = talloc_strdup(fti, ps->domain_name);
3968 if (!info->netbios_name.string) {
3969 return NT_STATUS_NO_MEMORY;
3971 info->netbios_name.size = strlen(info->netbios_name.string);
3973 return NT_STATUS_OK;
3976 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3977 struct lsa_ForestTrustInformation *lfti,
3978 struct ForestTrustInfo *fti)
3980 struct lsa_ForestTrustRecord *lrec;
3981 struct ForestTrustInfoRecord *rec;
3982 struct lsa_StringLarge *tln;
3983 struct lsa_ForestTrustDomainInfo *info;
3987 fti->count = lfti->count;
3988 fti->records = talloc_array(mem_ctx,
3989 struct ForestTrustInfoRecordArmor,
3991 if (!fti->records) {
3992 return NT_STATUS_NO_MEMORY;
3994 for (i = 0; i < fti->count; i++) {
3995 lrec = lfti->entries[i];
3996 rec = &fti->records[i].record;
3998 rec->flags = lrec->flags;
3999 rec->timestamp = lrec->time;
4000 rec->type = lrec->type;
4002 switch (lrec->type) {
4003 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
4004 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4005 tln = &lrec->forest_trust_data.top_level_name;
4006 rec->data.name.string =
4007 talloc_strdup(mem_ctx, tln->string);
4008 if (!rec->data.name.string) {
4009 return NT_STATUS_NO_MEMORY;
4011 rec->data.name.size = strlen(rec->data.name.string);
4013 case LSA_FOREST_TRUST_DOMAIN_INFO:
4014 info = &lrec->forest_trust_data.domain_info;
4015 rec->data.info.sid = *info->domain_sid;
4016 rec->data.info.dns_name.string =
4017 talloc_strdup(mem_ctx,
4018 info->dns_domain_name.string);
4019 if (!rec->data.info.dns_name.string) {
4020 return NT_STATUS_NO_MEMORY;
4022 rec->data.info.dns_name.size =
4023 strlen(rec->data.info.dns_name.string);
4024 rec->data.info.netbios_name.string =
4025 talloc_strdup(mem_ctx,
4026 info->netbios_domain_name.string);
4027 if (!rec->data.info.netbios_name.string) {
4028 return NT_STATUS_NO_MEMORY;
4030 rec->data.info.netbios_name.size =
4031 strlen(rec->data.info.netbios_name.string);
4034 return NT_STATUS_INVALID_DOMAIN_STATE;
4038 return NT_STATUS_OK;
4041 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4042 uint32_t index, uint32_t collision_type,
4043 uint32_t conflict_type, const char *tdo_name);
4045 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4046 const char *tdo_name,
4047 struct ForestTrustInfo *tdo_fti,
4048 struct ForestTrustInfo *new_fti,
4049 struct lsa_ForestTrustCollisionInfo *c_info)
4051 struct ForestTrustInfoRecord *nrec;
4052 struct ForestTrustInfoRecord *trec;
4053 const char *dns_name;
4054 const char *nb_name;
4055 struct dom_sid *sid;
4061 uint32_t new_fti_idx;
4063 /* use always TDO type, until we understand when Xref can be used */
4064 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
4072 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
4074 nrec = &new_fti->records[new_fti_idx].record;
4076 tln_conflict = false;
4077 sid_conflict = false;
4078 nb_conflict = false;
4081 switch (nrec->type) {
4082 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4083 /* exclusions do not conflict by definition */
4086 case FOREST_TRUST_TOP_LEVEL_NAME:
4087 dns_name = nrec->data.name.string;
4088 dns_len = nrec->data.name.size;
4091 case LSA_FOREST_TRUST_DOMAIN_INFO:
4092 dns_name = nrec->data.info.dns_name.string;
4093 dns_len = nrec->data.info.dns_name.size;
4094 nb_name = nrec->data.info.netbios_name.string;
4095 nb_len = nrec->data.info.netbios_name.size;
4096 sid = &nrec->data.info.sid;
4100 if (!dns_name) continue;
4102 /* check if this is already taken and not excluded */
4103 for (i = 0; i < tdo_fti->count; i++) {
4104 trec = &tdo_fti->records[i].record;
4106 switch (trec->type) {
4107 case FOREST_TRUST_TOP_LEVEL_NAME:
4109 tname = trec->data.name.string;
4110 tlen = trec->data.name.size;
4112 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4114 tname = trec->data.name.string;
4115 tlen = trec->data.name.size;
4117 case FOREST_TRUST_DOMAIN_INFO:
4119 tname = trec->data.info.dns_name.string;
4120 tlen = trec->data.info.dns_name.size;
4122 ret = dns_cmp(dns_name, dns_len, tname, tlen);
4125 /* if it matches exclusion,
4126 * it doesn't conflict */
4132 case DNS_CMP_FIRST_IS_CHILD:
4133 case DNS_CMP_SECOND_IS_CHILD:
4134 tln_conflict = true;
4140 /* explicit exclusion, no dns name conflict here */
4142 tln_conflict = false;
4145 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
4149 /* also test for domain info */
4150 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
4151 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
4152 sid_conflict = true;
4154 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
4155 strcasecmp_m(trec->data.info.netbios_name.string,
4162 nt_status = add_collision(c_info, new_fti_idx,
4164 LSA_TLN_DISABLED_CONFLICT,
4168 nt_status = add_collision(c_info, new_fti_idx,
4170 LSA_SID_DISABLED_CONFLICT,
4174 nt_status = add_collision(c_info, new_fti_idx,
4176 LSA_NB_DISABLED_CONFLICT,
4181 return NT_STATUS_OK;
4184 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4185 uint32_t idx, uint32_t collision_type,
4186 uint32_t conflict_type, const char *tdo_name)
4188 struct lsa_ForestTrustCollisionRecord **es;
4189 uint32_t i = c_info->count;
4191 es = talloc_realloc(c_info, c_info->entries,
4192 struct lsa_ForestTrustCollisionRecord *, i + 1);
4194 return NT_STATUS_NO_MEMORY;
4196 c_info->entries = es;
4197 c_info->count = i + 1;
4199 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4201 return NT_STATUS_NO_MEMORY;
4205 es[i]->type = collision_type;
4206 es[i]->flags.flags = conflict_type;
4207 es[i]->name.string = talloc_strdup(es[i], tdo_name);
4208 if (!es[i]->name.string) {
4209 return NT_STATUS_NO_MEMORY;
4211 es[i]->name.size = strlen(es[i]->name.string);
4213 return NT_STATUS_OK;
4217 lsa_lsaRSetForestTrustInformation
4219 static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_state *dce_call,
4220 TALLOC_CTX *mem_ctx,
4221 struct lsa_lsaRSetForestTrustInformation *r)
4223 struct dcesrv_handle *h;
4224 struct lsa_policy_state *p_state;
4225 const char *trust_attrs[] = { "trustPartner", "trustAttributes",
4226 "msDS-TrustForestTrustInfo", NULL };
4227 struct ldb_message **dom_res = NULL;
4228 struct ldb_dn *tdo_dn;
4229 struct ldb_message *msg;
4231 const char *td_name;
4232 uint32_t trust_attributes;
4233 struct lsa_ForestTrustCollisionInfo *c_info;
4234 struct ForestTrustInfo *nfti;
4235 struct ForestTrustInfo *fti;
4237 enum ndr_err_code ndr_err;
4242 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4246 if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
4247 return NT_STATUS_INVALID_DOMAIN_STATE;
4250 /* abort if we are not a PDC */
4251 if (!samdb_is_pdc(p_state->sam_ldb)) {
4252 return NT_STATUS_INVALID_DOMAIN_ROLE;
4255 ret = samdb_rodc(p_state->sam_ldb, &am_rodc);
4256 if (ret == LDB_SUCCESS && am_rodc) {
4257 return NT_STATUS_NO_SUCH_DOMAIN;
4260 /* check caller has TRUSTED_SET_AUTH */
4262 /* fetch all trusted domain objects */
4263 num_res = gendb_search(p_state->sam_ldb, mem_ctx,
4265 &dom_res, trust_attrs,
4266 "(objectclass=trustedDomain)");
4268 return NT_STATUS_NO_SUCH_DOMAIN;
4271 for (i = 0; i < num_res; i++) {
4272 td_name = ldb_msg_find_attr_as_string(dom_res[i],
4273 "trustPartner", NULL);
4275 return NT_STATUS_INVALID_DOMAIN_STATE;
4277 if (strcasecmp_m(td_name,
4278 r->in.trusted_domain_name->string) == 0) {
4283 return NT_STATUS_NO_SUCH_DOMAIN;
4286 tdo_dn = dom_res[i]->dn;
4288 trust_attributes = samdb_result_uint(dom_res[i],
4289 "trustAttributes", 0);
4290 if (!(trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4291 return NT_STATUS_INVALID_PARAMETER;
4294 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4295 return NT_STATUS_INVALID_PARAMETER;
4298 nfti = talloc(mem_ctx, struct ForestTrustInfo);
4300 return NT_STATUS_NO_MEMORY;
4303 nt_status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4304 if (!NT_STATUS_IS_OK(nt_status)) {
4308 c_info = talloc_zero(r->out.collision_info,
4309 struct lsa_ForestTrustCollisionInfo);
4311 return NT_STATUS_NO_MEMORY;
4314 /* first check own info, then other domains */
4315 fti = talloc(mem_ctx, struct ForestTrustInfo);
4317 return NT_STATUS_NO_MEMORY;
4320 nt_status = own_ft_info(p_state, fti);
4321 if (!NT_STATUS_IS_OK(nt_status)) {
4325 nt_status = check_ft_info(c_info, p_state->domain_dns,
4327 if (!NT_STATUS_IS_OK(nt_status)) {
4331 for (i = 0; i < num_res; i++) {
4332 fti = talloc(mem_ctx, struct ForestTrustInfo);
4334 return NT_STATUS_NO_MEMORY;
4337 nt_status = get_ft_info(mem_ctx, dom_res[i], fti);
4338 if (!NT_STATUS_IS_OK(nt_status)) {
4339 if (NT_STATUS_EQUAL(nt_status,
4340 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4346 td_name = ldb_msg_find_attr_as_string(dom_res[i],
4347 "trustPartner", NULL);
4349 return NT_STATUS_INVALID_DOMAIN_STATE;
4352 nt_status = check_ft_info(c_info, td_name, fti, nfti, c_info);
4353 if (!NT_STATUS_IS_OK(nt_status)) {
4358 *r->out.collision_info = c_info;
4360 if (r->in.check_only != 0) {
4361 return NT_STATUS_OK;
4364 /* not just a check, write info back */
4366 ndr_err = ndr_push_struct_blob(&ft_blob, mem_ctx, nfti,
4367 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4368 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4369 return NT_STATUS_INVALID_PARAMETER;
4372 msg = ldb_msg_new(mem_ctx);
4374 return NT_STATUS_NO_MEMORY;
4377 msg->dn = ldb_dn_copy(mem_ctx, tdo_dn);
4379 return NT_STATUS_NO_MEMORY;
4382 ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo",
4383 LDB_FLAG_MOD_REPLACE, NULL);
4384 if (ret != LDB_SUCCESS) {
4385 return NT_STATUS_NO_MEMORY;
4387 ret = ldb_msg_add_value(msg, "msDS-TrustForestTrustInfo",
4389 if (ret != LDB_SUCCESS) {
4390 return NT_STATUS_NO_MEMORY;
4393 ret = ldb_modify(p_state->sam_ldb, msg);
4394 if (ret != LDB_SUCCESS) {
4395 DEBUG(0, ("Failed to store Forest Trust Info: %s\n",
4396 ldb_errstring(p_state->sam_ldb)));
4399 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
4400 return NT_STATUS_ACCESS_DENIED;
4402 return NT_STATUS_INTERNAL_DB_CORRUPTION;
4406 return NT_STATUS_OK;
4412 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4413 struct lsa_CREDRRENAME *r)
4415 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4421 lsa_LSAROPENPOLICYSCE
4423 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4424 struct lsa_LSAROPENPOLICYSCE *r)
4426 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4431 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
4433 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4434 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4436 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4441 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
4443 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4444 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4446 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4451 lsa_LSARADTREPORTSECURITYEVENT
4453 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4454 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4456 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4460 /* include the generated boilerplate */
4461 #include "librpc/gen_ndr/ndr_lsa_s.c"
4465 /*****************************************
4466 NOTE! The remaining calls below were
4467 removed in w2k3, so the DCESRV_FAULT()
4468 replies are the correct implementation. Do
4469 not try and fill these in with anything else
4470 ******************************************/
4473 dssetup_DsRoleDnsNameToFlatName
4475 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4476 struct dssetup_DsRoleDnsNameToFlatName *r)
4478 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4483 dssetup_DsRoleDcAsDc
4485 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4486 struct dssetup_DsRoleDcAsDc *r)
4488 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4493 dssetup_DsRoleDcAsReplica
4495 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4496 struct dssetup_DsRoleDcAsReplica *r)
4498 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4503 dssetup_DsRoleDemoteDc
4505 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4506 struct dssetup_DsRoleDemoteDc *r)
4508 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4513 dssetup_DsRoleGetDcOperationProgress
4515 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4516 struct dssetup_DsRoleGetDcOperationProgress *r)
4518 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4523 dssetup_DsRoleGetDcOperationResults
4525 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4526 struct dssetup_DsRoleGetDcOperationResults *r)
4528 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4533 dssetup_DsRoleCancel
4535 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4536 struct dssetup_DsRoleCancel *r)
4538 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4543 dssetup_DsRoleServerSaveStateForUpgrade
4545 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4546 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
4548 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4553 dssetup_DsRoleUpgradeDownlevelServer
4555 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4556 struct dssetup_DsRoleUpgradeDownlevelServer *r)
4558 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4563 dssetup_DsRoleAbortDownlevelServerUpgrade
4565 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4566 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
4568 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4572 /* include the generated boilerplate */
4573 #include "librpc/gen_ndr/ndr_dssetup_s.c"
4575 NTSTATUS dcerpc_server_lsa_init(void)
4579 ret = dcerpc_server_dssetup_init();
4580 if (!NT_STATUS_IS_OK(ret)) {
4583 ret = dcerpc_server_lsarpc_init();
4584 if (!NT_STATUS_IS_OK(ret)) {