1 /* need access mask/acl implementation */
4 Unix SMB/CIFS implementation.
6 endpoint server for the lsarpc pipe
8 Copyright (C) Andrew Tridgell 2004
9 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "rpc_server/lsa/lsa.h"
26 #include "system/kerberos.h"
27 #include "auth/kerberos/kerberos.h"
28 #include "librpc/gen_ndr/ndr_drsblobs.h"
29 #include "librpc/gen_ndr/ndr_lsa.h"
30 #include "../lib/crypto/crypto.h"
31 #include "lib/util/tsort.h"
32 #include "dsdb/common/util.h"
33 #include "libcli/security/session.h"
36 this type allows us to distinguish handle types
40 state associated with a lsa_OpenAccount() operation
42 struct lsa_account_state {
43 struct lsa_policy_state *policy;
45 struct dom_sid *account_sid;
50 state associated with a lsa_OpenSecret() operation
52 struct lsa_secret_state {
53 struct lsa_policy_state *policy;
55 struct ldb_dn *secret_dn;
56 struct ldb_context *sam_ldb;
61 state associated with a lsa_OpenTrustedDomain() operation
63 struct lsa_trusted_domain_state {
64 struct lsa_policy_state *policy;
66 struct ldb_dn *trusted_domain_dn;
67 struct ldb_dn *trusted_domain_user_dn;
71 this is based on the samba3 function make_lsa_object_sd()
72 It uses the same logic, but with samba4 helper functions
74 static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
75 struct security_descriptor **sd,
81 struct dom_sid *domain_sid, *domain_admins_sid;
82 const char *domain_admins_sid_str, *sidstr;
83 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
85 status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
86 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
88 domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
89 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid, tmp_ctx);
91 domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
92 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid_str, tmp_ctx);
94 sidstr = dom_sid_string(tmp_ctx, sid);
95 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, tmp_ctx);
97 *sd = security_descriptor_dacl_create(mem_ctx,
101 SEC_ACE_TYPE_ACCESS_ALLOWED,
102 SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,
104 SID_BUILTIN_ADMINISTRATORS,
105 SEC_ACE_TYPE_ACCESS_ALLOWED,
108 SID_BUILTIN_ACCOUNT_OPERATORS,
109 SEC_ACE_TYPE_ACCESS_ALLOWED,
112 domain_admins_sid_str,
113 SEC_ACE_TYPE_ACCESS_ALLOWED,
117 SEC_ACE_TYPE_ACCESS_ALLOWED,
121 talloc_free(tmp_ctx);
123 NT_STATUS_HAVE_NO_MEMORY(*sd);
129 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
131 struct lsa_EnumAccountRights *r);
133 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
135 struct lsa_policy_state *state,
138 const struct lsa_RightSet *rights);
143 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
146 struct dcesrv_handle *h;
148 *r->out.handle = *r->in.handle;
150 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
154 ZERO_STRUCTP(r->out.handle);
163 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
164 struct lsa_Delete *r)
166 return NT_STATUS_NOT_SUPPORTED;
173 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
174 struct lsa_DeleteObject *r)
176 struct dcesrv_handle *h;
179 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
181 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
182 struct lsa_secret_state *secret_state = h->data;
184 /* Ensure user is permitted to delete this... */
185 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
187 case SECURITY_SYSTEM:
188 case SECURITY_ADMINISTRATOR:
191 /* Users and anonymous are not allowed to delete things */
192 return NT_STATUS_ACCESS_DENIED;
195 ret = ldb_delete(secret_state->sam_ldb,
196 secret_state->secret_dn);
197 if (ret != LDB_SUCCESS) {
198 return NT_STATUS_INVALID_HANDLE;
201 ZERO_STRUCTP(r->out.handle);
205 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
206 struct lsa_trusted_domain_state *trusted_domain_state =
207 talloc_get_type(h->data, struct lsa_trusted_domain_state);
208 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
209 if (ret != LDB_SUCCESS) {
210 return NT_STATUS_INTERNAL_DB_CORRUPTION;
213 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
214 trusted_domain_state->trusted_domain_dn);
215 if (ret != LDB_SUCCESS) {
216 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
217 return NT_STATUS_INVALID_HANDLE;
220 if (trusted_domain_state->trusted_domain_user_dn) {
221 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
222 trusted_domain_state->trusted_domain_user_dn);
223 if (ret != LDB_SUCCESS) {
224 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
225 return NT_STATUS_INVALID_HANDLE;
229 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
230 if (ret != LDB_SUCCESS) {
231 return NT_STATUS_INTERNAL_DB_CORRUPTION;
234 ZERO_STRUCTP(r->out.handle);
238 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
239 struct lsa_RightSet *rights;
240 struct lsa_account_state *astate;
241 struct lsa_EnumAccountRights r2;
244 rights = talloc(mem_ctx, struct lsa_RightSet);
246 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
250 r2.in.handle = &astate->policy->handle->wire_handle;
251 r2.in.sid = astate->account_sid;
252 r2.out.rights = rights;
254 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
255 but we have a LSA_HANDLE_ACCOUNT here, so this call
257 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
258 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
262 if (!NT_STATUS_IS_OK(status)) {
266 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
267 LDB_FLAG_MOD_DELETE, astate->account_sid,
269 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
273 if (!NT_STATUS_IS_OK(status)) {
277 ZERO_STRUCTP(r->out.handle);
282 return NT_STATUS_INVALID_HANDLE;
289 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
290 struct lsa_EnumPrivs *r)
292 struct dcesrv_handle *h;
293 struct lsa_policy_state *state;
295 enum sec_privilege priv;
296 const char *privname;
298 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
302 i = *r->in.resume_handle;
304 while (((priv = sec_privilege_from_index(i)) != SEC_PRIV_INVALID) &&
305 r->out.privs->count < r->in.max_count) {
306 struct lsa_PrivEntry *e;
307 privname = sec_privilege_name(priv);
308 r->out.privs->privs = talloc_realloc(r->out.privs,
310 struct lsa_PrivEntry,
311 r->out.privs->count+1);
312 if (r->out.privs->privs == NULL) {
313 return NT_STATUS_NO_MEMORY;
315 e = &r->out.privs->privs[r->out.privs->count];
318 e->name.string = privname;
319 r->out.privs->count++;
323 *r->out.resume_handle = i;
332 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
333 struct lsa_QuerySecurity *r)
335 struct dcesrv_handle *h;
336 struct security_descriptor *sd;
340 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
342 sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
344 if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
345 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid, 0);
346 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
347 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid,
348 LSA_ACCOUNT_ALL_ACCESS);
350 return NT_STATUS_INVALID_HANDLE;
352 NT_STATUS_NOT_OK_RETURN(status);
354 (*r->out.sdbuf) = talloc(mem_ctx, struct sec_desc_buf);
355 NT_STATUS_HAVE_NO_MEMORY(*r->out.sdbuf);
357 (*r->out.sdbuf)->sd = sd;
366 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
367 struct lsa_SetSecObj *r)
369 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
376 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
377 struct lsa_ChangePassword *r)
379 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
383 dssetup_DsRoleGetPrimaryDomainInformation
385 This is not an LSA call, but is the only call left on the DSSETUP
386 pipe (after the pipe was truncated), and needs lsa_get_policy_state
388 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
390 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
392 union dssetup_DsRoleInfo *info;
394 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
395 W_ERROR_HAVE_NO_MEMORY(info);
397 switch (r->in.level) {
398 case DS_ROLE_BASIC_INFORMATION:
400 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
402 const char *domain = NULL;
403 const char *dns_domain = NULL;
404 const char *forest = NULL;
405 struct GUID domain_guid;
406 struct lsa_policy_state *state;
408 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
409 if (!NT_STATUS_IS_OK(status)) {
410 return ntstatus_to_werror(status);
413 ZERO_STRUCT(domain_guid);
415 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
416 case ROLE_STANDALONE:
417 role = DS_ROLE_STANDALONE_SERVER;
419 case ROLE_DOMAIN_MEMBER:
420 role = DS_ROLE_MEMBER_SERVER;
422 case ROLE_DOMAIN_CONTROLLER:
423 if (samdb_is_pdc(state->sam_ldb)) {
424 role = DS_ROLE_PRIMARY_DC;
426 role = DS_ROLE_BACKUP_DC;
431 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
432 case ROLE_STANDALONE:
433 domain = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
434 W_ERROR_HAVE_NO_MEMORY(domain);
436 case ROLE_DOMAIN_MEMBER:
437 domain = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
438 W_ERROR_HAVE_NO_MEMORY(domain);
439 /* TODO: what is with dns_domain and forest and guid? */
441 case ROLE_DOMAIN_CONTROLLER:
442 flags = DS_ROLE_PRIMARY_DS_RUNNING;
444 if (state->mixed_domain == 1) {
445 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
448 domain = state->domain_name;
449 dns_domain = state->domain_dns;
450 forest = state->forest_dns;
452 domain_guid = state->domain_guid;
453 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
457 info->basic.role = role;
458 info->basic.flags = flags;
459 info->basic.domain = domain;
460 info->basic.dns_domain = dns_domain;
461 info->basic.forest = forest;
462 info->basic.domain_guid = domain_guid;
467 case DS_ROLE_UPGRADE_STATUS:
469 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
470 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
475 case DS_ROLE_OP_STATUS:
477 info->opstatus.status = DS_ROLE_OP_IDLE;
483 return WERR_INVALID_PARAM;
488 fill in the AccountDomain info
490 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
491 struct lsa_DomainInfo *info)
493 info->name.string = state->domain_name;
494 info->sid = state->domain_sid;
500 fill in the DNS domain info
502 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
503 struct lsa_DnsDomainInfo *info)
505 info->name.string = state->domain_name;
506 info->sid = state->domain_sid;
507 info->dns_domain.string = state->domain_dns;
508 info->dns_forest.string = state->forest_dns;
509 info->domain_guid = state->domain_guid;
517 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
518 struct lsa_QueryInfoPolicy2 *r)
520 struct lsa_policy_state *state;
521 struct dcesrv_handle *h;
522 union lsa_PolicyInformation *info;
526 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
530 info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
532 return NT_STATUS_NO_MEMORY;
536 switch (r->in.level) {
537 case LSA_POLICY_INFO_AUDIT_LOG:
538 /* we don't need to fill in any of this */
539 ZERO_STRUCT(info->audit_log);
541 case LSA_POLICY_INFO_AUDIT_EVENTS:
542 /* we don't need to fill in any of this */
543 ZERO_STRUCT(info->audit_events);
545 case LSA_POLICY_INFO_PD:
546 /* we don't need to fill in any of this */
547 ZERO_STRUCT(info->pd);
550 case LSA_POLICY_INFO_DOMAIN:
551 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
552 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
553 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
554 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
555 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
557 case LSA_POLICY_INFO_ROLE:
558 info->role.role = LSA_ROLE_PRIMARY;
561 case LSA_POLICY_INFO_DNS:
562 case LSA_POLICY_INFO_DNS_INT:
563 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
565 case LSA_POLICY_INFO_REPLICA:
566 ZERO_STRUCT(info->replica);
569 case LSA_POLICY_INFO_QUOTA:
570 ZERO_STRUCT(info->quota);
573 case LSA_POLICY_INFO_MOD:
574 case LSA_POLICY_INFO_AUDIT_FULL_SET:
575 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
576 /* windows gives INVALID_PARAMETER */
578 return NT_STATUS_INVALID_PARAMETER;
582 return NT_STATUS_INVALID_INFO_CLASS;
588 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
589 struct lsa_QueryInfoPolicy *r)
591 struct lsa_QueryInfoPolicy2 r2;
596 r2.in.handle = r->in.handle;
597 r2.in.level = r->in.level;
598 r2.out.info = r->out.info;
600 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
608 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
609 struct lsa_SetInfoPolicy *r)
611 /* need to support this */
612 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
619 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
620 struct lsa_ClearAuditLog *r)
622 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
629 This call does not seem to have any long-term effects, hence no database operations
631 we need to talk to the MS product group to find out what this account database means!
633 answer is that the lsa database is totally separate from the SAM and
634 ldap databases. We are going to need a separate ldb to store these
635 accounts. The SIDs on this account bear no relation to the SIDs in
638 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
639 struct lsa_CreateAccount *r)
641 struct lsa_account_state *astate;
643 struct lsa_policy_state *state;
644 struct dcesrv_handle *h, *ah;
646 ZERO_STRUCTP(r->out.acct_handle);
648 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
652 astate = talloc(dce_call->conn, struct lsa_account_state);
653 if (astate == NULL) {
654 return NT_STATUS_NO_MEMORY;
657 astate->account_sid = dom_sid_dup(astate, r->in.sid);
658 if (astate->account_sid == NULL) {
660 return NT_STATUS_NO_MEMORY;
663 astate->policy = talloc_reference(astate, state);
664 astate->access_mask = r->in.access_mask;
666 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
669 return NT_STATUS_NO_MEMORY;
672 ah->data = talloc_steal(ah, astate);
674 *r->out.acct_handle = ah->wire_handle;
683 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
684 struct lsa_EnumAccounts *r)
686 struct dcesrv_handle *h;
687 struct lsa_policy_state *state;
689 struct ldb_message **res;
690 const char * const attrs[] = { "objectSid", NULL};
693 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
697 /* NOTE: This call must only return accounts that have at least
700 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
701 "(&(objectSid=*)(privilege=*))");
703 return NT_STATUS_INTERNAL_DB_CORRUPTION;
706 if (*r->in.resume_handle >= ret) {
707 return NT_STATUS_NO_MORE_ENTRIES;
710 count = ret - *r->in.resume_handle;
711 if (count > r->in.num_entries) {
712 count = r->in.num_entries;
716 return NT_STATUS_NO_MORE_ENTRIES;
719 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
720 if (r->out.sids->sids == NULL) {
721 return NT_STATUS_NO_MEMORY;
724 for (i=0;i<count;i++) {
725 r->out.sids->sids[i].sid =
726 samdb_result_dom_sid(r->out.sids->sids,
727 res[i + *r->in.resume_handle],
729 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
732 r->out.sids->num_sids = count;
733 *r->out.resume_handle = count + *r->in.resume_handle;
739 /* This decrypts and returns Trusted Domain Auth Information Internal data */
740 static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
741 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
742 struct trustDomainPasswords *auth_struct)
744 DATA_BLOB session_key = data_blob(NULL, 0);
745 enum ndr_err_code ndr_err;
748 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
749 if (!NT_STATUS_IS_OK(nt_status)) {
753 arcfour_crypt_blob(auth_blob->data, auth_blob->length, &session_key);
754 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
756 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
757 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
758 return NT_STATUS_INVALID_PARAMETER;
764 static NTSTATUS get_trustauth_inout_blob(struct dcesrv_call_state *dce_call,
766 struct trustAuthInOutBlob *iopw,
767 DATA_BLOB *trustauth_blob)
769 enum ndr_err_code ndr_err;
771 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
773 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
774 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
775 return NT_STATUS_INVALID_PARAMETER;
781 static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx,
782 struct ldb_context *sam_ldb,
783 struct ldb_dn *base_dn,
784 const char *netbios_name,
785 struct trustAuthInOutBlob *in,
786 struct ldb_dn **user_dn)
788 struct ldb_message *msg;
793 dn = ldb_dn_copy(mem_ctx, base_dn);
795 return NT_STATUS_NO_MEMORY;
797 if (!ldb_dn_add_child_fmt(dn, "cn=%s$,cn=users", netbios_name)) {
798 return NT_STATUS_NO_MEMORY;
801 msg = ldb_msg_new(mem_ctx);
803 return NT_STATUS_NO_MEMORY;
807 ret = ldb_msg_add_string(msg, "objectClass", "user");
808 if (ret != LDB_SUCCESS) {
809 return NT_STATUS_NO_MEMORY;
812 ret = ldb_msg_add_fmt(msg, "samAccountName", "%s$", netbios_name);
813 if (ret != LDB_SUCCESS) {
814 return NT_STATUS_NO_MEMORY;
817 ret = ldb_msg_add_fmt(msg, "userAccountControl", "%u",
818 UF_INTERDOMAIN_TRUST_ACCOUNT);
819 if (ret != LDB_SUCCESS) {
820 return NT_STATUS_NO_MEMORY;
823 for (i = 0; i < in->count; i++) {
824 const char *attribute;
826 switch (in->current.array[i].AuthType) {
827 case TRUST_AUTH_TYPE_NT4OWF:
828 attribute = "unicodePwd";
829 v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
832 case TRUST_AUTH_TYPE_CLEAR:
833 attribute = "clearTextPassword";
834 v.data = in->current.array[i].AuthInfo.clear.password;
835 v.length = in->current.array[i].AuthInfo.clear.size;
841 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
842 if (ret != LDB_SUCCESS) {
843 return NT_STATUS_NO_MEMORY;
847 /* create the trusted_domain user account */
848 ret = ldb_add(sam_ldb, msg);
849 if (ret != LDB_SUCCESS) {
850 DEBUG(0,("Failed to create user record %s: %s\n",
851 ldb_dn_get_linearized(msg->dn),
852 ldb_errstring(sam_ldb)));
855 case LDB_ERR_ENTRY_ALREADY_EXISTS:
856 return NT_STATUS_DOMAIN_EXISTS;
857 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
858 return NT_STATUS_ACCESS_DENIED;
860 return NT_STATUS_INTERNAL_DB_CORRUPTION;
871 lsa_CreateTrustedDomainEx2
873 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
875 struct lsa_CreateTrustedDomainEx2 *r,
878 struct dcesrv_handle *policy_handle;
879 struct lsa_policy_state *policy_state;
880 struct lsa_trusted_domain_state *trusted_domain_state;
881 struct dcesrv_handle *handle;
882 struct ldb_message **msgs, *msg;
883 const char *attrs[] = {
886 const char *netbios_name;
887 const char *dns_name;
889 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
890 struct trustDomainPasswords auth_struct;
893 struct ldb_context *sam_ldb;
895 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
896 ZERO_STRUCTP(r->out.trustdom_handle);
898 policy_state = policy_handle->data;
899 sam_ldb = policy_state->sam_ldb;
901 netbios_name = r->in.info->netbios_name.string;
903 return NT_STATUS_INVALID_PARAMETER;
906 dns_name = r->in.info->domain_name.string;
908 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
909 if (!trusted_domain_state) {
910 return NT_STATUS_NO_MEMORY;
912 trusted_domain_state->policy = policy_state;
914 if (strcasecmp(netbios_name, "BUILTIN") == 0
915 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
916 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
917 return NT_STATUS_INVALID_PARAMETER;
920 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
921 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
922 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
923 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
924 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
925 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
928 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
929 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
930 /* No secrets are created at this time, for this function */
931 auth_struct.outgoing.count = 0;
932 auth_struct.incoming.count = 0;
934 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data,
935 r->in.auth_info->auth_blob.size);
936 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
937 &auth_blob, &auth_struct);
938 if (!NT_STATUS_IS_OK(nt_status)) {
942 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
943 if (auth_struct.incoming.count > 1) {
944 return NT_STATUS_INVALID_PARAMETER;
949 if (auth_struct.incoming.count) {
950 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
951 &auth_struct.incoming,
953 if (!NT_STATUS_IS_OK(nt_status)) {
957 trustAuthIncoming = data_blob(NULL, 0);
960 if (auth_struct.outgoing.count) {
961 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
962 &auth_struct.outgoing,
964 if (!NT_STATUS_IS_OK(nt_status)) {
968 trustAuthOutgoing = data_blob(NULL, 0);
971 ret = ldb_transaction_start(sam_ldb);
972 if (ret != LDB_SUCCESS) {
973 return NT_STATUS_INTERNAL_DB_CORRUPTION;
977 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
978 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
979 /* search for the trusted_domain record */
980 ret = gendb_search(sam_ldb,
981 mem_ctx, policy_state->system_dn, &msgs, attrs,
982 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
983 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
985 ldb_transaction_cancel(sam_ldb);
986 return NT_STATUS_OBJECT_NAME_COLLISION;
989 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
990 /* search for the trusted_domain record */
991 ret = gendb_search(sam_ldb,
992 mem_ctx, policy_state->system_dn, &msgs, attrs,
993 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
994 netbios_encoded, netbios_encoded, netbios_encoded);
996 ldb_transaction_cancel(sam_ldb);
997 return NT_STATUS_OBJECT_NAME_COLLISION;
1002 ldb_transaction_cancel(sam_ldb);
1003 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1006 name = dns_name ? dns_name : netbios_name;
1008 msg = ldb_msg_new(mem_ctx);
1010 return NT_STATUS_NO_MEMORY;
1013 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1014 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
1015 ldb_transaction_cancel(sam_ldb);
1016 return NT_STATUS_NO_MEMORY;
1019 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "flatname", netbios_name);
1021 if (r->in.info->sid) {
1022 ret = samdb_msg_add_dom_sid(sam_ldb, mem_ctx, msg, "securityIdentifier", r->in.info->sid);
1023 if (ret != LDB_SUCCESS) {
1024 ldb_transaction_cancel(sam_ldb);
1025 return NT_STATUS_INVALID_PARAMETER;
1029 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
1031 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
1033 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
1035 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
1038 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
1041 if (trustAuthIncoming.data) {
1042 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
1043 if (ret != LDB_SUCCESS) {
1044 ldb_transaction_cancel(sam_ldb);
1045 return NT_STATUS_NO_MEMORY;
1048 if (trustAuthOutgoing.data) {
1049 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
1050 if (ret != LDB_SUCCESS) {
1051 ldb_transaction_cancel(sam_ldb);
1052 return NT_STATUS_NO_MEMORY;
1056 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
1058 /* create the trusted_domain */
1059 ret = dsdb_add(sam_ldb, msg, DSDB_MODIFY_RELAX);
1063 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1064 ldb_transaction_cancel(sam_ldb);
1065 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1066 ldb_dn_get_linearized(msg->dn),
1067 ldb_errstring(sam_ldb)));
1068 return NT_STATUS_DOMAIN_EXISTS;
1069 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1070 ldb_transaction_cancel(sam_ldb);
1071 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1072 ldb_dn_get_linearized(msg->dn),
1073 ldb_errstring(sam_ldb)));
1074 return NT_STATUS_ACCESS_DENIED;
1076 ldb_transaction_cancel(sam_ldb);
1077 DEBUG(0,("Failed to create user record %s: %s\n",
1078 ldb_dn_get_linearized(msg->dn),
1079 ldb_errstring(sam_ldb)));
1080 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1083 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1084 struct ldb_dn *user_dn;
1085 /* Inbound trusts must also create a cn=users object to match */
1086 nt_status = add_trust_user(mem_ctx, sam_ldb,
1087 policy_state->domain_dn,
1089 &auth_struct.incoming,
1091 if (!NT_STATUS_IS_OK(nt_status)) {
1092 ldb_transaction_cancel(sam_ldb);
1096 /* save the trust user dn */
1097 trusted_domain_state->trusted_domain_user_dn
1098 = talloc_steal(trusted_domain_state, user_dn);
1101 ret = ldb_transaction_commit(sam_ldb);
1102 if (ret != LDB_SUCCESS) {
1103 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1106 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1108 return NT_STATUS_NO_MEMORY;
1111 handle->data = talloc_steal(handle, trusted_domain_state);
1113 trusted_domain_state->access_mask = r->in.access_mask;
1114 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1116 *r->out.trustdom_handle = handle->wire_handle;
1118 return NT_STATUS_OK;
1122 lsa_CreateTrustedDomainEx2
1124 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1125 TALLOC_CTX *mem_ctx,
1126 struct lsa_CreateTrustedDomainEx2 *r)
1128 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
1131 lsa_CreateTrustedDomainEx
1133 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1134 TALLOC_CTX *mem_ctx,
1135 struct lsa_CreateTrustedDomainEx *r)
1137 struct lsa_CreateTrustedDomainEx2 r2;
1139 r2.in.policy_handle = r->in.policy_handle;
1140 r2.in.info = r->in.info;
1141 r2.in.auth_info = r->in.auth_info;
1142 r2.out.trustdom_handle = r->out.trustdom_handle;
1143 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
1147 lsa_CreateTrustedDomain
1149 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1150 struct lsa_CreateTrustedDomain *r)
1152 struct lsa_CreateTrustedDomainEx2 r2;
1154 r2.in.policy_handle = r->in.policy_handle;
1155 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1157 return NT_STATUS_NO_MEMORY;
1160 r2.in.info->domain_name.string = NULL;
1161 r2.in.info->netbios_name = r->in.info->name;
1162 r2.in.info->sid = r->in.info->sid;
1163 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1164 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1165 r2.in.info->trust_attributes = 0;
1167 r2.in.access_mask = r->in.access_mask;
1168 r2.out.trustdom_handle = r->out.trustdom_handle;
1170 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1175 lsa_OpenTrustedDomain
1177 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1178 struct lsa_OpenTrustedDomain *r)
1180 struct dcesrv_handle *policy_handle;
1182 struct lsa_policy_state *policy_state;
1183 struct lsa_trusted_domain_state *trusted_domain_state;
1184 struct dcesrv_handle *handle;
1185 struct ldb_message **msgs;
1186 const char *attrs[] = {
1192 const char *sid_string;
1195 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1196 ZERO_STRUCTP(r->out.trustdom_handle);
1197 policy_state = policy_handle->data;
1199 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1200 if (!trusted_domain_state) {
1201 return NT_STATUS_NO_MEMORY;
1203 trusted_domain_state->policy = policy_state;
1205 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1207 return NT_STATUS_NO_MEMORY;
1210 /* search for the trusted_domain record */
1211 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1212 mem_ctx, policy_state->system_dn, &msgs, attrs,
1213 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
1216 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1220 DEBUG(0,("Found %d records matching DN %s\n", ret,
1221 ldb_dn_get_linearized(policy_state->system_dn)));
1222 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1225 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1227 trusted_domain_state->trusted_domain_user_dn = NULL;
1229 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1230 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1231 /* search for the trusted_domain record */
1232 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1233 mem_ctx, policy_state->domain_dn, &msgs, attrs,
1234 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%u))",
1235 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1237 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1240 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1242 return NT_STATUS_NO_MEMORY;
1245 handle->data = talloc_steal(handle, trusted_domain_state);
1247 trusted_domain_state->access_mask = r->in.access_mask;
1248 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1250 *r->out.trustdom_handle = handle->wire_handle;
1252 return NT_STATUS_OK;
1257 lsa_OpenTrustedDomainByName
1259 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1260 TALLOC_CTX *mem_ctx,
1261 struct lsa_OpenTrustedDomainByName *r)
1263 struct dcesrv_handle *policy_handle;
1265 struct lsa_policy_state *policy_state;
1266 struct lsa_trusted_domain_state *trusted_domain_state;
1267 struct dcesrv_handle *handle;
1268 struct ldb_message **msgs;
1269 const char *attrs[] = {
1275 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1276 ZERO_STRUCTP(r->out.trustdom_handle);
1277 policy_state = policy_handle->data;
1279 if (!r->in.name.string) {
1280 return NT_STATUS_INVALID_PARAMETER;
1283 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1284 if (!trusted_domain_state) {
1285 return NT_STATUS_NO_MEMORY;
1287 trusted_domain_state->policy = policy_state;
1289 /* search for the trusted_domain record */
1290 td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string);
1291 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1292 mem_ctx, policy_state->system_dn, &msgs, attrs,
1293 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))"
1294 "(objectclass=trustedDomain))",
1295 td_name, td_name, td_name);
1297 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1301 DEBUG(0,("Found %d records matching DN %s\n", ret,
1302 ldb_dn_get_linearized(policy_state->system_dn)));
1303 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1306 /* TODO: perform access checks */
1308 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1310 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1312 return NT_STATUS_NO_MEMORY;
1315 handle->data = talloc_steal(handle, trusted_domain_state);
1317 trusted_domain_state->access_mask = r->in.access_mask;
1318 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1320 *r->out.trustdom_handle = handle->wire_handle;
1322 return NT_STATUS_OK;
1328 lsa_SetTrustedDomainInfo
1330 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1331 struct lsa_SetTrustedDomainInfo *r)
1333 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1338 /* parameters 4 to 6 are optional if the dn is a dn of a TDO object,
1339 * otherwise at least one must be provided */
1340 static NTSTATUS get_tdo(struct ldb_context *sam, TALLOC_CTX *mem_ctx,
1341 struct ldb_dn *basedn, const char *dns_domain,
1342 const char *netbios, struct dom_sid2 *sid,
1343 struct ldb_message ***msgs)
1345 const char *attrs[] = { "flatname", "trustPartner",
1346 "securityIdentifier", "trustDirection",
1347 "trustType", "trustAttributes",
1349 "msDs-supportedEncryptionTypes", NULL };
1352 char *sidstr = NULL;
1357 if (dns_domain || netbios || sid) {
1358 filter = talloc_strdup(mem_ctx,
1359 "(&(objectclass=trustedDomain)(|");
1361 filter = talloc_strdup(mem_ctx,
1362 "(objectclass=trustedDomain)");
1365 return NT_STATUS_NO_MEMORY;
1369 dns = ldb_binary_encode_string(mem_ctx, dns_domain);
1371 return NT_STATUS_NO_MEMORY;
1373 filter = talloc_asprintf_append(filter,
1374 "(trustPartner=%s)", dns);
1376 return NT_STATUS_NO_MEMORY;
1380 nbn = ldb_binary_encode_string(mem_ctx, netbios);
1382 return NT_STATUS_NO_MEMORY;
1384 filter = talloc_asprintf_append(filter,
1385 "(flatname=%s)", nbn);
1387 return NT_STATUS_NO_MEMORY;
1391 sidstr = dom_sid_string(mem_ctx, sid);
1393 return NT_STATUS_INVALID_PARAMETER;
1395 filter = talloc_asprintf_append(filter,
1396 "(securityIdentifier=%s)",
1399 return NT_STATUS_NO_MEMORY;
1402 if (dns_domain || netbios || sid) {
1403 filter = talloc_asprintf_append(filter, "))");
1405 return NT_STATUS_NO_MEMORY;
1409 ret = gendb_search(sam, mem_ctx, basedn, msgs, attrs, "%s", filter);
1411 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1415 return NT_STATUS_OBJECT_NAME_COLLISION;
1418 return NT_STATUS_OK;
1421 static NTSTATUS update_uint32_t_value(TALLOC_CTX *mem_ctx,
1422 struct ldb_message *orig,
1423 struct ldb_message *dest,
1424 const char *attribute,
1426 uint32_t *orig_value)
1428 const struct ldb_val *orig_val;
1429 uint32_t orig_uint = 0;
1434 orig_val = ldb_msg_find_ldb_val(orig, attribute);
1435 if (!orig_val || !orig_val->data) {
1436 /* add new attribute */
1437 flags = LDB_FLAG_MOD_ADD;
1441 orig_uint = strtoul((const char *)orig_val->data, NULL, 0);
1442 if (errno != 0 || orig_uint != value) {
1443 /* replace also if can't get value */
1444 flags = LDB_FLAG_MOD_REPLACE;
1449 /* stored value is identical, nothing to change */
1453 ret = ldb_msg_add_empty(dest, attribute, flags, NULL);
1454 if (ret != LDB_SUCCESS) {
1455 return NT_STATUS_NO_MEMORY;
1458 str_val = talloc_asprintf(mem_ctx, "%u", value);
1460 return NT_STATUS_NO_MEMORY;
1462 ret = ldb_msg_add_steal_string(dest, attribute, str_val);
1463 if (ret != LDB_SUCCESS) {
1464 return NT_STATUS_NO_MEMORY;
1469 *orig_value = orig_uint;
1471 return NT_STATUS_OK;
1474 static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx,
1475 struct ldb_context *sam_ldb,
1476 struct ldb_dn *base_dn,
1478 const char *netbios_name,
1479 struct trustAuthInOutBlob *in)
1481 const char *attrs[] = { "userAccountControl", NULL };
1482 struct ldb_message **msgs;
1483 struct ldb_message *msg;
1488 ret = gendb_search(sam_ldb, mem_ctx,
1489 base_dn, &msgs, attrs,
1490 "samAccountName=%s$", netbios_name);
1492 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1497 return NT_STATUS_OK;
1500 /* ok no existing user, add it from scratch */
1501 return add_trust_user(mem_ctx, sam_ldb, base_dn,
1502 netbios_name, in, NULL);
1505 /* check user is what we are looking for */
1506 uac = ldb_msg_find_attr_as_uint(msgs[0],
1507 "userAccountControl", 0);
1508 if (!(uac & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
1509 return NT_STATUS_OBJECT_NAME_COLLISION;
1513 ret = ldb_delete(sam_ldb, msgs[0]->dn);
1516 return NT_STATUS_OK;
1517 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1518 return NT_STATUS_ACCESS_DENIED;
1520 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1524 /* entry exists, just modify secret if any */
1525 if (in->count == 0) {
1526 return NT_STATUS_OK;
1529 msg = ldb_msg_new(mem_ctx);
1531 return NT_STATUS_NO_MEMORY;
1533 msg->dn = msgs[0]->dn;
1535 for (i = 0; i < in->count; i++) {
1536 const char *attribute;
1538 switch (in->current.array[i].AuthType) {
1539 case TRUST_AUTH_TYPE_NT4OWF:
1540 attribute = "unicodePwd";
1541 v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
1544 case TRUST_AUTH_TYPE_CLEAR:
1545 attribute = "clearTextPassword";
1546 v.data = in->current.array[i].AuthInfo.clear.password;
1547 v.length = in->current.array[i].AuthInfo.clear.size;
1553 ret = ldb_msg_add_empty(msg, attribute,
1554 LDB_FLAG_MOD_REPLACE, NULL);
1555 if (ret != LDB_SUCCESS) {
1556 return NT_STATUS_NO_MEMORY;
1559 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
1560 if (ret != LDB_SUCCESS) {
1561 return NT_STATUS_NO_MEMORY;
1565 /* create the trusted_domain user account */
1566 ret = ldb_modify(sam_ldb, msg);
1567 if (ret != LDB_SUCCESS) {
1568 DEBUG(0,("Failed to create user record %s: %s\n",
1569 ldb_dn_get_linearized(msg->dn),
1570 ldb_errstring(sam_ldb)));
1573 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1574 return NT_STATUS_DOMAIN_EXISTS;
1575 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1576 return NT_STATUS_ACCESS_DENIED;
1578 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1582 return NT_STATUS_OK;
1586 static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call,
1587 struct dcesrv_handle *p_handle,
1588 TALLOC_CTX *mem_ctx,
1589 struct ldb_message *dom_msg,
1590 enum lsa_TrustDomInfoEnum level,
1591 union lsa_TrustedDomainInfo *info)
1593 struct lsa_policy_state *p_state = p_handle->data;
1594 uint32_t *posix_offset = NULL;
1595 struct lsa_TrustDomainInfoInfoEx *info_ex = NULL;
1596 struct lsa_TrustDomainInfoAuthInfo *auth_info = NULL;
1597 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
1598 uint32_t *enc_types = NULL;
1599 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
1600 struct trustDomainPasswords auth_struct;
1602 struct ldb_message **msgs;
1603 struct ldb_message *msg;
1604 bool add_outgoing = false;
1605 bool add_incoming = false;
1606 bool del_outgoing = false;
1607 bool del_incoming = false;
1608 bool in_transaction = false;
1613 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1614 posix_offset = &info->posix_offset.posix_offset;
1616 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1617 info_ex = &info->info_ex;
1619 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1620 auth_info = &info->auth_info;
1622 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1623 posix_offset = &info->full_info.posix_offset.posix_offset;
1624 info_ex = &info->full_info.info_ex;
1625 auth_info = &info->full_info.auth_info;
1627 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1628 auth_info_int = &info->auth_info_internal;
1630 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1631 posix_offset = &info->full_info_internal.posix_offset.posix_offset;
1632 info_ex = &info->full_info_internal.info_ex;
1633 auth_info_int = &info->full_info_internal.auth_info;
1635 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1636 enc_types = &info->enc_types.enc_types;
1639 return NT_STATUS_INVALID_PARAMETER;
1643 /* FIXME: not handled yet */
1644 return NT_STATUS_INVALID_PARAMETER;
1647 /* decode auth_info_int if set */
1648 if (auth_info_int) {
1650 /* now decrypt blob */
1651 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
1652 auth_info_int->auth_blob.size);
1654 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
1655 &auth_blob, &auth_struct);
1656 if (!NT_STATUS_IS_OK(nt_status)) {
1662 /* verify data matches */
1663 if (info_ex->trust_attributes &
1664 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1665 /* TODO: check what behavior level we have */
1666 if (strcasecmp_m(p_state->domain_dns,
1667 p_state->forest_dns) != 0) {
1668 return NT_STATUS_INVALID_DOMAIN_STATE;
1672 ret = samdb_rodc(p_state->sam_ldb, &am_rodc);
1673 if (ret == LDB_SUCCESS && am_rodc) {
1674 return NT_STATUS_NO_SUCH_DOMAIN;
1677 /* verify only one object matches the dns/netbios/sid
1678 * triplet and that this is the one we already have */
1679 nt_status = get_tdo(p_state->sam_ldb, mem_ctx,
1681 info_ex->domain_name.string,
1682 info_ex->netbios_name.string,
1683 info_ex->sid, &msgs);
1684 if (!NT_STATUS_IS_OK(nt_status)) {
1687 if (ldb_dn_compare(dom_msg->dn, msgs[0]->dn) != 0) {
1688 return NT_STATUS_OBJECT_NAME_COLLISION;
1693 /* TODO: should we fetch previous values from the existing entry
1694 * and append them ? */
1695 if (auth_struct.incoming.count) {
1696 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1697 &auth_struct.incoming,
1698 &trustAuthIncoming);
1699 if (!NT_STATUS_IS_OK(nt_status)) {
1703 trustAuthIncoming = data_blob(NULL, 0);
1706 if (auth_struct.outgoing.count) {
1707 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1708 &auth_struct.outgoing,
1709 &trustAuthOutgoing);
1710 if (!NT_STATUS_IS_OK(nt_status)) {
1714 trustAuthOutgoing = data_blob(NULL, 0);
1717 msg = ldb_msg_new(mem_ctx);
1719 return NT_STATUS_NO_MEMORY;
1721 msg->dn = dom_msg->dn;
1724 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1726 *posix_offset, NULL);
1727 if (!NT_STATUS_IS_OK(nt_status)) {
1738 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1740 info_ex->trust_direction,
1742 if (!NT_STATUS_IS_OK(nt_status)) {
1746 tmp = info_ex->trust_direction ^ origdir;
1747 if (tmp & LSA_TRUST_DIRECTION_INBOUND) {
1748 if (origdir & LSA_TRUST_DIRECTION_INBOUND) {
1749 del_incoming = true;
1751 add_incoming = true;
1754 if (tmp & LSA_TRUST_DIRECTION_OUTBOUND) {
1755 if (origdir & LSA_TRUST_DIRECTION_OUTBOUND) {
1756 del_outgoing = true;
1758 add_outgoing = true;
1762 origtype = ldb_msg_find_attr_as_int(dom_msg, "trustType", -1);
1763 if (origtype == -1 || origtype != info_ex->trust_type) {
1764 DEBUG(1, ("Attempted to change trust type! "
1765 "Operation not handled\n"));
1766 return NT_STATUS_INVALID_PARAMETER;
1769 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1771 info_ex->trust_attributes,
1773 if (!NT_STATUS_IS_OK(nt_status)) {
1776 /* TODO: check forestFunctionality from ldb opaque */
1777 /* TODO: check what is set makes sense */
1778 /* for now refuse changes */
1779 if (origattrs == -1 ||
1780 origattrs != info_ex->trust_attributes) {
1781 DEBUG(1, ("Attempted to change trust attributes! "
1782 "Operation not handled\n"));
1783 return NT_STATUS_INVALID_PARAMETER;
1788 nt_status = update_uint32_t_value(mem_ctx, dom_msg, msg,
1789 "msDS-SupportedEncryptionTypes",
1791 if (!NT_STATUS_IS_OK(nt_status)) {
1796 if (add_incoming && trustAuthIncoming.data) {
1797 ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
1798 LDB_FLAG_MOD_REPLACE, NULL);
1799 if (ret != LDB_SUCCESS) {
1800 return NT_STATUS_NO_MEMORY;
1802 ret = ldb_msg_add_value(msg, "trustAuthIncoming",
1803 &trustAuthIncoming, NULL);
1804 if (ret != LDB_SUCCESS) {
1805 return NT_STATUS_NO_MEMORY;
1808 if (add_outgoing && trustAuthOutgoing.data) {
1809 ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
1810 LDB_FLAG_MOD_REPLACE, NULL);
1811 if (ret != LDB_SUCCESS) {
1812 return NT_STATUS_NO_MEMORY;
1814 ret = ldb_msg_add_value(msg, "trustAuthOutgoing",
1815 &trustAuthOutgoing, NULL);
1816 if (ret != LDB_SUCCESS) {
1817 return NT_STATUS_NO_MEMORY;
1821 /* start transaction */
1822 ret = ldb_transaction_start(p_state->sam_ldb);
1823 if (ret != LDB_SUCCESS) {
1824 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1826 in_transaction = true;
1828 ret = ldb_modify(p_state->sam_ldb, msg);
1829 if (ret != LDB_SUCCESS) {
1830 DEBUG(1,("Failed to modify trusted domain record %s: %s\n",
1831 ldb_dn_get_linearized(msg->dn),
1832 ldb_errstring(p_state->sam_ldb)));
1833 if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
1834 nt_status = NT_STATUS_ACCESS_DENIED;
1836 nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1841 if (add_incoming || del_incoming) {
1842 const char *netbios_name;
1844 netbios_name = ldb_msg_find_attr_as_string(dom_msg,
1846 if (!netbios_name) {
1847 nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
1851 nt_status = update_trust_user(mem_ctx,
1856 &auth_struct.incoming);
1857 if (!NT_STATUS_IS_OK(nt_status)) {
1862 /* ok, all fine, commit transaction and return */
1863 ret = ldb_transaction_commit(p_state->sam_ldb);
1864 if (ret != LDB_SUCCESS) {
1865 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1867 in_transaction = false;
1869 nt_status = NT_STATUS_OK;
1872 if (in_transaction) {
1873 ldb_transaction_cancel(p_state->sam_ldb);
1879 lsa_SetInfomrationTrustedDomain
1881 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(
1882 struct dcesrv_call_state *dce_call,
1883 TALLOC_CTX *mem_ctx,
1884 struct lsa_SetInformationTrustedDomain *r)
1886 struct dcesrv_handle *h;
1887 struct lsa_trusted_domain_state *td_state;
1888 struct ldb_message **msgs;
1891 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle,
1892 LSA_HANDLE_TRUSTED_DOMAIN);
1894 td_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1896 /* get the trusted domain object */
1897 nt_status = get_tdo(td_state->policy->sam_ldb, mem_ctx,
1898 td_state->trusted_domain_dn,
1899 NULL, NULL, NULL, &msgs);
1900 if (!NT_STATUS_IS_OK(nt_status)) {
1901 if (NT_STATUS_EQUAL(nt_status,
1902 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1905 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1908 return setInfoTrustedDomain_base(dce_call, h, mem_ctx,
1909 msgs[0], r->in.level, r->in.info);
1914 lsa_DeleteTrustedDomain
1916 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1917 struct lsa_DeleteTrustedDomain *r)
1920 struct lsa_OpenTrustedDomain opn;
1921 struct lsa_DeleteObject del;
1922 struct dcesrv_handle *h;
1924 opn.in.handle = r->in.handle;
1925 opn.in.sid = r->in.dom_sid;
1926 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1927 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1928 if (!opn.out.trustdom_handle) {
1929 return NT_STATUS_NO_MEMORY;
1931 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1932 if (!NT_STATUS_IS_OK(status)) {
1936 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1937 talloc_steal(mem_ctx, h);
1939 del.in.handle = opn.out.trustdom_handle;
1940 del.out.handle = opn.out.trustdom_handle;
1941 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
1942 if (!NT_STATUS_IS_OK(status)) {
1945 return NT_STATUS_OK;
1948 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1949 struct ldb_message *msg,
1950 struct lsa_TrustDomainInfoInfoEx *info_ex)
1952 info_ex->domain_name.string
1953 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1954 info_ex->netbios_name.string
1955 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1957 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1958 info_ex->trust_direction
1959 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1961 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1962 info_ex->trust_attributes
1963 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1964 return NT_STATUS_OK;
1968 lsa_QueryTrustedDomainInfo
1970 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1971 struct lsa_QueryTrustedDomainInfo *r)
1973 union lsa_TrustedDomainInfo *info = NULL;
1974 struct dcesrv_handle *h;
1975 struct lsa_trusted_domain_state *trusted_domain_state;
1976 struct ldb_message *msg;
1978 struct ldb_message **res;
1979 const char *attrs[] = {
1982 "securityIdentifier",
1986 "msDs-supportedEncryptionTypes",
1990 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1992 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1994 /* pull all the user attributes */
1995 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1996 trusted_domain_state->trusted_domain_dn, &res, attrs);
1998 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2002 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
2004 return NT_STATUS_NO_MEMORY;
2006 *r->out.info = info;
2008 switch (r->in.level) {
2009 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2010 info->name.netbios_name.string
2011 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2013 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2014 info->posix_offset.posix_offset
2015 = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
2017 #if 0 /* Win2k3 doesn't implement this */
2018 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2019 r->out.info->info_basic.netbios_name.string
2020 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2021 r->out.info->info_basic.sid
2022 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
2025 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2026 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
2028 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2029 ZERO_STRUCT(info->full_info);
2030 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 = ldb_msg_find_attr_as_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 = ldb_msg_find_attr_as_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 = ldb_msg_find_attr_as_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), 0));
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->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), 0));
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->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 (ldb_msg_add_value(msg, "priorValue", &val, NULL) != LDB_SUCCESS) {
3143 return NT_STATUS_NO_MEMORY;
3146 /* set old value mtime */
3147 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3148 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3149 return NT_STATUS_NO_MEMORY;
3153 /* If the old value is not set, then migrate the
3154 * current value to the old value */
3155 const struct ldb_val *old_val;
3156 NTTIME last_set_time;
3157 struct ldb_message **res;
3158 const char *attrs[] = {
3164 /* search for the secret record */
3165 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
3166 secret_state->secret_dn, &res, attrs);
3168 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3172 DEBUG(0,("Found %d records matching dn=%s\n", ret,
3173 ldb_dn_get_linearized(secret_state->secret_dn)));
3174 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3177 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3178 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3182 if (ldb_msg_add_value(msg, "priorValue",
3183 old_val, NULL) != LDB_SUCCESS) {
3184 return NT_STATUS_NO_MEMORY;
3187 if (samdb_msg_add_delete(secret_state->sam_ldb,
3188 mem_ctx, msg, "priorValue")) {
3189 return NT_STATUS_NO_MEMORY;
3194 /* set old value mtime */
3195 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
3196 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3197 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
3198 return NT_STATUS_NO_MEMORY;
3201 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3202 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3203 return NT_STATUS_NO_MEMORY;
3208 if (r->in.new_val) {
3210 crypt_secret.data = r->in.new_val->data;
3211 crypt_secret.length = r->in.new_val->size;
3213 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3214 if (!NT_STATUS_IS_OK(status)) {
3218 val.data = secret.data;
3219 val.length = secret.length;
3222 if (ldb_msg_add_value(msg, "currentValue", &val, NULL) != LDB_SUCCESS) {
3223 return NT_STATUS_NO_MEMORY;
3226 /* set new value mtime */
3227 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3228 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3229 return NT_STATUS_NO_MEMORY;
3233 /* NULL out the NEW value */
3234 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3235 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3236 return NT_STATUS_NO_MEMORY;
3238 if (samdb_msg_add_delete(secret_state->sam_ldb,
3239 mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
3240 return NT_STATUS_NO_MEMORY;
3244 /* modify the samdb record */
3245 ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
3246 if (ret != LDB_SUCCESS) {
3247 /* we really need samdb.c to return NTSTATUS */
3248 return NT_STATUS_UNSUCCESSFUL;
3251 return NT_STATUS_OK;
3258 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3259 struct lsa_QuerySecret *r)
3261 struct dcesrv_handle *h;
3262 struct lsa_secret_state *secret_state;
3263 struct ldb_message *msg;
3264 DATA_BLOB session_key;
3265 DATA_BLOB crypt_secret, secret;
3267 struct ldb_message **res;
3268 const char *attrs[] = {
3278 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3280 /* Ensure user is permitted to read this... */
3281 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
3283 case SECURITY_SYSTEM:
3284 case SECURITY_ADMINISTRATOR:
3287 /* Users and annonymous are not allowed to read secrets */
3288 return NT_STATUS_ACCESS_DENIED;
3291 secret_state = h->data;
3293 /* pull all the user attributes */
3294 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
3295 secret_state->secret_dn, &res, attrs);
3297 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3301 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
3302 if (!NT_STATUS_IS_OK(nt_status)) {
3306 if (r->in.old_val) {
3307 const struct ldb_val *prior_val;
3308 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3309 if (!r->out.old_val) {
3310 return NT_STATUS_NO_MEMORY;
3312 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
3314 if (prior_val && prior_val->length) {
3315 secret.data = prior_val->data;
3316 secret.length = prior_val->length;
3319 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3320 if (!crypt_secret.length) {
3321 return NT_STATUS_NO_MEMORY;
3323 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3324 if (!r->out.old_val->buf) {
3325 return NT_STATUS_NO_MEMORY;
3327 r->out.old_val->buf->size = crypt_secret.length;
3328 r->out.old_val->buf->length = crypt_secret.length;
3329 r->out.old_val->buf->data = crypt_secret.data;
3333 if (r->in.old_mtime) {
3334 r->out.old_mtime = talloc(mem_ctx, NTTIME);
3335 if (!r->out.old_mtime) {
3336 return NT_STATUS_NO_MEMORY;
3338 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
3341 if (r->in.new_val) {
3342 const struct ldb_val *new_val;
3343 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3344 if (!r->out.new_val) {
3345 return NT_STATUS_NO_MEMORY;
3348 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3350 if (new_val && new_val->length) {
3351 secret.data = new_val->data;
3352 secret.length = new_val->length;
3355 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3356 if (!crypt_secret.length) {
3357 return NT_STATUS_NO_MEMORY;
3359 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3360 if (!r->out.new_val->buf) {
3361 return NT_STATUS_NO_MEMORY;
3363 r->out.new_val->buf->length = crypt_secret.length;
3364 r->out.new_val->buf->size = crypt_secret.length;
3365 r->out.new_val->buf->data = crypt_secret.data;
3369 if (r->in.new_mtime) {
3370 r->out.new_mtime = talloc(mem_ctx, NTTIME);
3371 if (!r->out.new_mtime) {
3372 return NT_STATUS_NO_MEMORY;
3374 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3377 return NT_STATUS_OK;
3384 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
3385 TALLOC_CTX *mem_ctx,
3386 struct lsa_LookupPrivValue *r)
3388 struct dcesrv_handle *h;
3389 struct lsa_policy_state *state;
3392 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3396 id = sec_privilege_id(r->in.name->string);
3397 if (id == SEC_PRIV_INVALID) {
3398 return NT_STATUS_NO_SUCH_PRIVILEGE;
3401 r->out.luid->low = id;
3402 r->out.luid->high = 0;
3404 return NT_STATUS_OK;
3411 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
3412 TALLOC_CTX *mem_ctx,
3413 struct lsa_LookupPrivName *r)
3415 struct dcesrv_handle *h;
3416 struct lsa_policy_state *state;
3417 struct lsa_StringLarge *name;
3418 const char *privname;
3420 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3424 if (r->in.luid->high != 0) {
3425 return NT_STATUS_NO_SUCH_PRIVILEGE;
3428 privname = sec_privilege_name(r->in.luid->low);
3429 if (privname == NULL) {
3430 return NT_STATUS_NO_SUCH_PRIVILEGE;
3433 name = talloc(mem_ctx, struct lsa_StringLarge);
3435 return NT_STATUS_NO_MEMORY;
3438 name->string = privname;
3440 *r->out.name = name;
3442 return NT_STATUS_OK;
3447 lsa_LookupPrivDisplayName
3449 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
3450 TALLOC_CTX *mem_ctx,
3451 struct lsa_LookupPrivDisplayName *r)
3453 struct dcesrv_handle *h;
3454 struct lsa_policy_state *state;
3455 struct lsa_StringLarge *disp_name = NULL;
3456 enum sec_privilege id;
3458 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3462 id = sec_privilege_id(r->in.name->string);
3463 if (id == SEC_PRIV_INVALID) {
3464 return NT_STATUS_NO_SUCH_PRIVILEGE;
3467 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
3468 if (disp_name == NULL) {
3469 return NT_STATUS_NO_MEMORY;
3472 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
3473 if (disp_name->string == NULL) {
3474 return NT_STATUS_INTERNAL_ERROR;
3477 *r->out.disp_name = disp_name;
3478 *r->out.returned_language_id = 0;
3480 return NT_STATUS_OK;
3485 lsa_EnumAccountsWithUserRight
3487 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
3488 TALLOC_CTX *mem_ctx,
3489 struct lsa_EnumAccountsWithUserRight *r)
3491 struct dcesrv_handle *h;
3492 struct lsa_policy_state *state;
3494 struct ldb_message **res;
3495 const char * const attrs[] = { "objectSid", NULL};
3496 const char *privname;
3498 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3502 if (r->in.name == NULL) {
3503 return NT_STATUS_NO_SUCH_PRIVILEGE;
3506 privname = r->in.name->string;
3507 if (sec_privilege_id(privname) == SEC_PRIV_INVALID && sec_right_bit(privname) == 0) {
3508 return NT_STATUS_NO_SUCH_PRIVILEGE;
3511 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
3512 "privilege=%s", privname);
3514 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3517 return NT_STATUS_NO_MORE_ENTRIES;
3520 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
3521 if (r->out.sids->sids == NULL) {
3522 return NT_STATUS_NO_MEMORY;
3524 for (i=0;i<ret;i++) {
3525 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
3526 res[i], "objectSid");
3527 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
3529 r->out.sids->num_sids = ret;
3531 return NT_STATUS_OK;
3536 lsa_AddAccountRights
3538 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
3539 TALLOC_CTX *mem_ctx,
3540 struct lsa_AddAccountRights *r)
3542 struct dcesrv_handle *h;
3543 struct lsa_policy_state *state;
3545 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3549 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3551 r->in.sid, r->in.rights);
3556 lsa_RemoveAccountRights
3558 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
3559 TALLOC_CTX *mem_ctx,
3560 struct lsa_RemoveAccountRights *r)
3562 struct dcesrv_handle *h;
3563 struct lsa_policy_state *state;
3565 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3569 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3570 LDB_FLAG_MOD_DELETE,
3571 r->in.sid, r->in.rights);
3576 lsa_StorePrivateData
3578 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3579 struct lsa_StorePrivateData *r)
3581 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3586 lsa_RetrievePrivateData
3588 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3589 struct lsa_RetrievePrivateData *r)
3591 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3598 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3599 struct lsa_GetUserName *r)
3601 NTSTATUS status = NT_STATUS_OK;
3602 const char *account_name;
3603 const char *authority_name;
3604 struct lsa_String *_account_name;
3605 struct lsa_String *_authority_name = NULL;
3607 /* this is what w2k3 does */
3608 r->out.account_name = r->in.account_name;
3609 r->out.authority_name = r->in.authority_name;
3611 if (r->in.account_name
3612 && *r->in.account_name
3613 /* && *(*r->in.account_name)->string */
3615 return NT_STATUS_INVALID_PARAMETER;
3618 if (r->in.authority_name
3619 && *r->in.authority_name
3620 /* && *(*r->in.authority_name)->string */
3622 return NT_STATUS_INVALID_PARAMETER;
3625 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
3626 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
3628 _account_name = talloc(mem_ctx, struct lsa_String);
3629 NT_STATUS_HAVE_NO_MEMORY(_account_name);
3630 _account_name->string = account_name;
3632 if (r->in.authority_name) {
3633 _authority_name = talloc(mem_ctx, struct lsa_String);
3634 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
3635 _authority_name->string = authority_name;
3638 *r->out.account_name = _account_name;
3639 if (r->out.authority_name) {
3640 *r->out.authority_name = _authority_name;
3649 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
3650 TALLOC_CTX *mem_ctx,
3651 struct lsa_SetInfoPolicy2 *r)
3653 /* need to support these */
3654 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3658 lsa_QueryDomainInformationPolicy
3660 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3661 TALLOC_CTX *mem_ctx,
3662 struct lsa_QueryDomainInformationPolicy *r)
3664 union lsa_DomainInformationPolicy *info;
3666 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
3668 return NT_STATUS_NO_MEMORY;
3671 switch (r->in.level) {
3672 case LSA_DOMAIN_INFO_POLICY_EFS:
3674 *r->out.info = NULL;
3675 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3676 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
3678 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
3679 struct smb_krb5_context *smb_krb5_context;
3680 int ret = smb_krb5_init_context(mem_ctx,
3681 dce_call->event_ctx,
3682 dce_call->conn->dce_ctx->lp_ctx,
3686 *r->out.info = NULL;
3687 return NT_STATUS_INTERNAL_ERROR;
3689 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
3690 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3691 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3692 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
3693 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
3694 talloc_free(smb_krb5_context);
3695 *r->out.info = info;
3696 return NT_STATUS_OK;
3700 *r->out.info = NULL;
3701 return NT_STATUS_INVALID_INFO_CLASS;
3706 lsa_SetDomInfoPolicy
3708 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3709 TALLOC_CTX *mem_ctx,
3710 struct lsa_SetDomainInformationPolicy *r)
3712 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3718 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3719 TALLOC_CTX *mem_ctx,
3720 struct lsa_TestCall *r)
3722 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3728 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3729 struct lsa_CREDRWRITE *r)
3731 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3738 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3739 struct lsa_CREDRREAD *r)
3741 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3748 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3749 struct lsa_CREDRENUMERATE *r)
3751 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3756 lsa_CREDRWRITEDOMAINCREDENTIALS
3758 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3759 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3761 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3766 lsa_CREDRREADDOMAINCREDENTIALS
3768 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3769 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3771 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3778 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3779 struct lsa_CREDRDELETE *r)
3781 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3786 lsa_CREDRGETTARGETINFO
3788 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3789 struct lsa_CREDRGETTARGETINFO *r)
3791 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3796 lsa_CREDRPROFILELOADED
3798 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3799 struct lsa_CREDRPROFILELOADED *r)
3801 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3806 lsa_CREDRGETSESSIONTYPES
3808 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3809 struct lsa_CREDRGETSESSIONTYPES *r)
3811 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3816 lsa_LSARREGISTERAUDITEVENT
3818 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3819 struct lsa_LSARREGISTERAUDITEVENT *r)
3821 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3826 lsa_LSARGENAUDITEVENT
3828 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3829 struct lsa_LSARGENAUDITEVENT *r)
3831 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3836 lsa_LSARUNREGISTERAUDITEVENT
3838 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3839 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3841 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3846 lsa_lsaRQueryForestTrustInformation
3848 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3849 struct lsa_lsaRQueryForestTrustInformation *r)
3851 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3854 #define DNS_CMP_MATCH 0
3855 #define DNS_CMP_FIRST_IS_CHILD 1
3856 #define DNS_CMP_SECOND_IS_CHILD 2
3857 #define DNS_CMP_NO_MATCH 3
3859 /* this function assumes names are well formed DNS names.
3860 * it doesn't validate them */
3861 static int dns_cmp(const char *s1, size_t l1,
3862 const char *s2, size_t l2)
3864 const char *p1, *p2;
3869 if (strcasecmp_m(s1, s2) == 0) {
3870 return DNS_CMP_MATCH;
3872 return DNS_CMP_NO_MATCH;
3880 cret = DNS_CMP_FIRST_IS_CHILD;
3886 cret = DNS_CMP_SECOND_IS_CHILD;
3889 if (p1[t1 - t2 - 1] != '.') {
3890 return DNS_CMP_NO_MATCH;
3893 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
3897 return DNS_CMP_NO_MATCH;
3900 /* decode all TDOs forest trust info blobs */
3901 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3902 struct ldb_message *msg,
3903 struct ForestTrustInfo *info)
3905 const struct ldb_val *ft_blob;
3906 enum ndr_err_code ndr_err;
3908 ft_blob = ldb_msg_find_ldb_val(msg, "msDS-TrustForestTrustInfo");
3909 if (!ft_blob || !ft_blob->data) {
3910 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3912 /* ldb_val is equivalent to DATA_BLOB */
3913 ndr_err = ndr_pull_struct_blob_all(ft_blob, mem_ctx, info,
3914 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3915 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3916 return NT_STATUS_INVALID_DOMAIN_STATE;
3919 return NT_STATUS_OK;
3922 static NTSTATUS own_ft_info(struct lsa_policy_state *ps,
3923 struct ForestTrustInfo *fti)
3925 struct ForestTrustDataDomainInfo *info;
3926 struct ForestTrustInfoRecord *rec;
3930 fti->records = talloc_array(fti,
3931 struct ForestTrustInfoRecordArmor, 2);
3932 if (!fti->records) {
3933 return NT_STATUS_NO_MEMORY;
3937 rec = &fti->records[0].record;
3941 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3943 rec->data.name.string = talloc_strdup(fti, ps->forest_dns);
3944 if (!rec->data.name.string) {
3945 return NT_STATUS_NO_MEMORY;
3947 rec->data.name.size = strlen(rec->data.name.string);
3950 rec = &fti->records[1].record;
3954 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3956 info = &rec->data.info;
3958 info->sid = *ps->domain_sid;
3959 info->dns_name.string = talloc_strdup(fti, ps->domain_dns);
3960 if (!info->dns_name.string) {
3961 return NT_STATUS_NO_MEMORY;
3963 info->dns_name.size = strlen(info->dns_name.string);
3964 info->netbios_name.string = talloc_strdup(fti, ps->domain_name);
3965 if (!info->netbios_name.string) {
3966 return NT_STATUS_NO_MEMORY;
3968 info->netbios_name.size = strlen(info->netbios_name.string);
3970 return NT_STATUS_OK;
3973 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3974 struct lsa_ForestTrustInformation *lfti,
3975 struct ForestTrustInfo *fti)
3977 struct lsa_ForestTrustRecord *lrec;
3978 struct ForestTrustInfoRecord *rec;
3979 struct lsa_StringLarge *tln;
3980 struct lsa_ForestTrustDomainInfo *info;
3984 fti->count = lfti->count;
3985 fti->records = talloc_array(mem_ctx,
3986 struct ForestTrustInfoRecordArmor,
3988 if (!fti->records) {
3989 return NT_STATUS_NO_MEMORY;
3991 for (i = 0; i < fti->count; i++) {
3992 lrec = lfti->entries[i];
3993 rec = &fti->records[i].record;
3995 rec->flags = lrec->flags;
3996 rec->timestamp = lrec->time;
3997 rec->type = lrec->type;
3999 switch (lrec->type) {
4000 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
4001 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4002 tln = &lrec->forest_trust_data.top_level_name;
4003 rec->data.name.string =
4004 talloc_strdup(mem_ctx, tln->string);
4005 if (!rec->data.name.string) {
4006 return NT_STATUS_NO_MEMORY;
4008 rec->data.name.size = strlen(rec->data.name.string);
4010 case LSA_FOREST_TRUST_DOMAIN_INFO:
4011 info = &lrec->forest_trust_data.domain_info;
4012 rec->data.info.sid = *info->domain_sid;
4013 rec->data.info.dns_name.string =
4014 talloc_strdup(mem_ctx,
4015 info->dns_domain_name.string);
4016 if (!rec->data.info.dns_name.string) {
4017 return NT_STATUS_NO_MEMORY;
4019 rec->data.info.dns_name.size =
4020 strlen(rec->data.info.dns_name.string);
4021 rec->data.info.netbios_name.string =
4022 talloc_strdup(mem_ctx,
4023 info->netbios_domain_name.string);
4024 if (!rec->data.info.netbios_name.string) {
4025 return NT_STATUS_NO_MEMORY;
4027 rec->data.info.netbios_name.size =
4028 strlen(rec->data.info.netbios_name.string);
4031 return NT_STATUS_INVALID_DOMAIN_STATE;
4035 return NT_STATUS_OK;
4038 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4039 uint32_t index, uint32_t collision_type,
4040 uint32_t conflict_type, const char *tdo_name);
4042 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4043 const char *tdo_name,
4044 struct ForestTrustInfo *tdo_fti,
4045 struct ForestTrustInfo *new_fti,
4046 struct lsa_ForestTrustCollisionInfo *c_info)
4048 struct ForestTrustInfoRecord *nrec;
4049 struct ForestTrustInfoRecord *trec;
4050 const char *dns_name;
4051 const char *nb_name;
4052 struct dom_sid *sid;
4058 uint32_t new_fti_idx;
4060 /* use always TDO type, until we understand when Xref can be used */
4061 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
4069 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
4071 nrec = &new_fti->records[new_fti_idx].record;
4073 tln_conflict = false;
4074 sid_conflict = false;
4075 nb_conflict = false;
4078 switch (nrec->type) {
4079 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4080 /* exclusions do not conflict by definition */
4083 case FOREST_TRUST_TOP_LEVEL_NAME:
4084 dns_name = nrec->data.name.string;
4085 dns_len = nrec->data.name.size;
4088 case LSA_FOREST_TRUST_DOMAIN_INFO:
4089 dns_name = nrec->data.info.dns_name.string;
4090 dns_len = nrec->data.info.dns_name.size;
4091 nb_name = nrec->data.info.netbios_name.string;
4092 nb_len = nrec->data.info.netbios_name.size;
4093 sid = &nrec->data.info.sid;
4097 if (!dns_name) continue;
4099 /* check if this is already taken and not excluded */
4100 for (i = 0; i < tdo_fti->count; i++) {
4101 trec = &tdo_fti->records[i].record;
4103 switch (trec->type) {
4104 case FOREST_TRUST_TOP_LEVEL_NAME:
4106 tname = trec->data.name.string;
4107 tlen = trec->data.name.size;
4109 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4111 tname = trec->data.name.string;
4112 tlen = trec->data.name.size;
4114 case FOREST_TRUST_DOMAIN_INFO:
4116 tname = trec->data.info.dns_name.string;
4117 tlen = trec->data.info.dns_name.size;
4119 ret = dns_cmp(dns_name, dns_len, tname, tlen);
4122 /* if it matches exclusion,
4123 * it doesn't conflict */
4129 case DNS_CMP_FIRST_IS_CHILD:
4130 case DNS_CMP_SECOND_IS_CHILD:
4131 tln_conflict = true;
4137 /* explicit exclusion, no dns name conflict here */
4139 tln_conflict = false;
4142 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
4146 /* also test for domain info */
4147 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
4148 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
4149 sid_conflict = true;
4151 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
4152 strcasecmp_m(trec->data.info.netbios_name.string,
4159 nt_status = add_collision(c_info, new_fti_idx,
4161 LSA_TLN_DISABLED_CONFLICT,
4165 nt_status = add_collision(c_info, new_fti_idx,
4167 LSA_SID_DISABLED_CONFLICT,
4171 nt_status = add_collision(c_info, new_fti_idx,
4173 LSA_NB_DISABLED_CONFLICT,
4178 return NT_STATUS_OK;
4181 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4182 uint32_t idx, uint32_t collision_type,
4183 uint32_t conflict_type, const char *tdo_name)
4185 struct lsa_ForestTrustCollisionRecord **es;
4186 uint32_t i = c_info->count;
4188 es = talloc_realloc(c_info, c_info->entries,
4189 struct lsa_ForestTrustCollisionRecord *, i + 1);
4191 return NT_STATUS_NO_MEMORY;
4193 c_info->entries = es;
4194 c_info->count = i + 1;
4196 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4198 return NT_STATUS_NO_MEMORY;
4202 es[i]->type = collision_type;
4203 es[i]->flags.flags = conflict_type;
4204 es[i]->name.string = talloc_strdup(es[i], tdo_name);
4205 if (!es[i]->name.string) {
4206 return NT_STATUS_NO_MEMORY;
4208 es[i]->name.size = strlen(es[i]->name.string);
4210 return NT_STATUS_OK;
4214 lsa_lsaRSetForestTrustInformation
4216 static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_state *dce_call,
4217 TALLOC_CTX *mem_ctx,
4218 struct lsa_lsaRSetForestTrustInformation *r)
4220 struct dcesrv_handle *h;
4221 struct lsa_policy_state *p_state;
4222 const char *trust_attrs[] = { "trustPartner", "trustAttributes",
4223 "msDS-TrustForestTrustInfo", NULL };
4224 struct ldb_message **dom_res = NULL;
4225 struct ldb_dn *tdo_dn;
4226 struct ldb_message *msg;
4228 const char *td_name;
4229 uint32_t trust_attributes;
4230 struct lsa_ForestTrustCollisionInfo *c_info;
4231 struct ForestTrustInfo *nfti;
4232 struct ForestTrustInfo *fti;
4234 enum ndr_err_code ndr_err;
4239 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4243 if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
4244 return NT_STATUS_INVALID_DOMAIN_STATE;
4247 /* abort if we are not a PDC */
4248 if (!samdb_is_pdc(p_state->sam_ldb)) {
4249 return NT_STATUS_INVALID_DOMAIN_ROLE;
4252 ret = samdb_rodc(p_state->sam_ldb, &am_rodc);
4253 if (ret == LDB_SUCCESS && am_rodc) {
4254 return NT_STATUS_NO_SUCH_DOMAIN;
4257 /* check caller has TRUSTED_SET_AUTH */
4259 /* fetch all trusted domain objects */
4260 num_res = gendb_search(p_state->sam_ldb, mem_ctx,
4262 &dom_res, trust_attrs,
4263 "(objectclass=trustedDomain)");
4265 return NT_STATUS_NO_SUCH_DOMAIN;
4268 for (i = 0; i < num_res; i++) {
4269 td_name = ldb_msg_find_attr_as_string(dom_res[i],
4270 "trustPartner", NULL);
4272 return NT_STATUS_INVALID_DOMAIN_STATE;
4274 if (strcasecmp_m(td_name,
4275 r->in.trusted_domain_name->string) == 0) {
4280 return NT_STATUS_NO_SUCH_DOMAIN;
4283 tdo_dn = dom_res[i]->dn;
4285 trust_attributes = ldb_msg_find_attr_as_uint(dom_res[i],
4286 "trustAttributes", 0);
4287 if (!(trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4288 return NT_STATUS_INVALID_PARAMETER;
4291 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4292 return NT_STATUS_INVALID_PARAMETER;
4295 nfti = talloc(mem_ctx, struct ForestTrustInfo);
4297 return NT_STATUS_NO_MEMORY;
4300 nt_status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4301 if (!NT_STATUS_IS_OK(nt_status)) {
4305 c_info = talloc_zero(r->out.collision_info,
4306 struct lsa_ForestTrustCollisionInfo);
4308 return NT_STATUS_NO_MEMORY;
4311 /* first check own info, then other domains */
4312 fti = talloc(mem_ctx, struct ForestTrustInfo);
4314 return NT_STATUS_NO_MEMORY;
4317 nt_status = own_ft_info(p_state, fti);
4318 if (!NT_STATUS_IS_OK(nt_status)) {
4322 nt_status = check_ft_info(c_info, p_state->domain_dns,
4324 if (!NT_STATUS_IS_OK(nt_status)) {
4328 for (i = 0; i < num_res; i++) {
4329 fti = talloc(mem_ctx, struct ForestTrustInfo);
4331 return NT_STATUS_NO_MEMORY;
4334 nt_status = get_ft_info(mem_ctx, dom_res[i], fti);
4335 if (!NT_STATUS_IS_OK(nt_status)) {
4336 if (NT_STATUS_EQUAL(nt_status,
4337 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4343 td_name = ldb_msg_find_attr_as_string(dom_res[i],
4344 "trustPartner", NULL);
4346 return NT_STATUS_INVALID_DOMAIN_STATE;
4349 nt_status = check_ft_info(c_info, td_name, fti, nfti, c_info);
4350 if (!NT_STATUS_IS_OK(nt_status)) {
4355 *r->out.collision_info = c_info;
4357 if (r->in.check_only != 0) {
4358 return NT_STATUS_OK;
4361 /* not just a check, write info back */
4363 ndr_err = ndr_push_struct_blob(&ft_blob, mem_ctx, nfti,
4364 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4365 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4366 return NT_STATUS_INVALID_PARAMETER;
4369 msg = ldb_msg_new(mem_ctx);
4371 return NT_STATUS_NO_MEMORY;
4374 msg->dn = ldb_dn_copy(mem_ctx, tdo_dn);
4376 return NT_STATUS_NO_MEMORY;
4379 ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo",
4380 LDB_FLAG_MOD_REPLACE, NULL);
4381 if (ret != LDB_SUCCESS) {
4382 return NT_STATUS_NO_MEMORY;
4384 ret = ldb_msg_add_value(msg, "msDS-TrustForestTrustInfo",
4386 if (ret != LDB_SUCCESS) {
4387 return NT_STATUS_NO_MEMORY;
4390 ret = ldb_modify(p_state->sam_ldb, msg);
4391 if (ret != LDB_SUCCESS) {
4392 DEBUG(0, ("Failed to store Forest Trust Info: %s\n",
4393 ldb_errstring(p_state->sam_ldb)));
4396 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
4397 return NT_STATUS_ACCESS_DENIED;
4399 return NT_STATUS_INTERNAL_DB_CORRUPTION;
4403 return NT_STATUS_OK;
4409 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4410 struct lsa_CREDRRENAME *r)
4412 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4418 lsa_LSAROPENPOLICYSCE
4420 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4421 struct lsa_LSAROPENPOLICYSCE *r)
4423 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4428 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
4430 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4431 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4433 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4438 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
4440 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4441 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4443 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4448 lsa_LSARADTREPORTSECURITYEVENT
4450 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4451 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4453 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4457 /* include the generated boilerplate */
4458 #include "librpc/gen_ndr/ndr_lsa_s.c"
4462 /*****************************************
4463 NOTE! The remaining calls below were
4464 removed in w2k3, so the DCESRV_FAULT()
4465 replies are the correct implementation. Do
4466 not try and fill these in with anything else
4467 ******************************************/
4470 dssetup_DsRoleDnsNameToFlatName
4472 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4473 struct dssetup_DsRoleDnsNameToFlatName *r)
4475 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4480 dssetup_DsRoleDcAsDc
4482 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4483 struct dssetup_DsRoleDcAsDc *r)
4485 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4490 dssetup_DsRoleDcAsReplica
4492 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4493 struct dssetup_DsRoleDcAsReplica *r)
4495 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4500 dssetup_DsRoleDemoteDc
4502 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4503 struct dssetup_DsRoleDemoteDc *r)
4505 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4510 dssetup_DsRoleGetDcOperationProgress
4512 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4513 struct dssetup_DsRoleGetDcOperationProgress *r)
4515 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4520 dssetup_DsRoleGetDcOperationResults
4522 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4523 struct dssetup_DsRoleGetDcOperationResults *r)
4525 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4530 dssetup_DsRoleCancel
4532 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4533 struct dssetup_DsRoleCancel *r)
4535 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4540 dssetup_DsRoleServerSaveStateForUpgrade
4542 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4543 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
4545 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4550 dssetup_DsRoleUpgradeDownlevelServer
4552 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4553 struct dssetup_DsRoleUpgradeDownlevelServer *r)
4555 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4560 dssetup_DsRoleAbortDownlevelServerUpgrade
4562 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4563 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
4565 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4569 /* include the generated boilerplate */
4570 #include "librpc/gen_ndr/ndr_dssetup_s.c"
4572 NTSTATUS dcerpc_server_lsa_init(void)
4576 ret = dcerpc_server_dssetup_init();
4577 if (!NT_STATUS_IS_OK(ret)) {
4580 ret = dcerpc_server_lsarpc_init();
4581 if (!NT_STATUS_IS_OK(ret)) {