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"
33 this type allows us to distinguish handle types
37 state associated with a lsa_OpenAccount() operation
39 struct lsa_account_state {
40 struct lsa_policy_state *policy;
42 struct dom_sid *account_sid;
47 state associated with a lsa_OpenSecret() operation
49 struct lsa_secret_state {
50 struct lsa_policy_state *policy;
52 struct ldb_dn *secret_dn;
53 struct ldb_context *sam_ldb;
58 state associated with a lsa_OpenTrustedDomain() operation
60 struct lsa_trusted_domain_state {
61 struct lsa_policy_state *policy;
63 struct ldb_dn *trusted_domain_dn;
64 struct ldb_dn *trusted_domain_user_dn;
68 this is based on the samba3 function make_lsa_object_sd()
69 It uses the same logic, but with samba4 helper functions
71 static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
72 struct security_descriptor **sd,
78 struct dom_sid *domain_sid, *domain_admins_sid;
79 const char *domain_admins_sid_str, *sidstr;
80 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
82 status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
83 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
85 domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
86 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid, tmp_ctx);
88 domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
89 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid_str, tmp_ctx);
91 sidstr = dom_sid_string(tmp_ctx, sid);
92 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, tmp_ctx);
94 *sd = security_descriptor_dacl_create(mem_ctx,
98 SEC_ACE_TYPE_ACCESS_ALLOWED,
99 SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,
101 SID_BUILTIN_ADMINISTRATORS,
102 SEC_ACE_TYPE_ACCESS_ALLOWED,
105 SID_BUILTIN_ACCOUNT_OPERATORS,
106 SEC_ACE_TYPE_ACCESS_ALLOWED,
109 domain_admins_sid_str,
110 SEC_ACE_TYPE_ACCESS_ALLOWED,
114 SEC_ACE_TYPE_ACCESS_ALLOWED,
118 talloc_free(tmp_ctx);
120 NT_STATUS_HAVE_NO_MEMORY(*sd);
126 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
128 struct lsa_EnumAccountRights *r);
130 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
132 struct lsa_policy_state *state,
135 const struct lsa_RightSet *rights);
140 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
143 struct dcesrv_handle *h;
145 *r->out.handle = *r->in.handle;
147 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
151 ZERO_STRUCTP(r->out.handle);
160 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
161 struct lsa_Delete *r)
163 return NT_STATUS_NOT_SUPPORTED;
170 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
171 struct lsa_DeleteObject *r)
173 struct dcesrv_handle *h;
176 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
178 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
179 struct lsa_secret_state *secret_state = h->data;
181 /* Ensure user is permitted to delete this... */
182 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
184 case SECURITY_SYSTEM:
185 case SECURITY_ADMINISTRATOR:
188 /* Users and annonymous are not allowed delete things */
189 return NT_STATUS_ACCESS_DENIED;
192 ret = ldb_delete(secret_state->sam_ldb,
193 secret_state->secret_dn);
196 return NT_STATUS_INVALID_HANDLE;
199 ZERO_STRUCTP(r->out.handle);
202 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
203 struct lsa_trusted_domain_state *trusted_domain_state =
204 talloc_get_type(h->data, struct lsa_trusted_domain_state);
205 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
207 return NT_STATUS_INTERNAL_DB_CORRUPTION;
210 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
211 trusted_domain_state->trusted_domain_dn);
213 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
214 return NT_STATUS_INVALID_HANDLE;
217 if (trusted_domain_state->trusted_domain_user_dn) {
218 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
219 trusted_domain_state->trusted_domain_user_dn);
221 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
222 return NT_STATUS_INVALID_HANDLE;
226 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
228 return NT_STATUS_INTERNAL_DB_CORRUPTION;
231 ZERO_STRUCTP(r->out.handle);
234 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
235 struct lsa_RightSet *rights;
236 struct lsa_account_state *astate;
237 struct lsa_EnumAccountRights r2;
240 rights = talloc(mem_ctx, struct lsa_RightSet);
242 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
246 r2.in.handle = &astate->policy->handle->wire_handle;
247 r2.in.sid = astate->account_sid;
248 r2.out.rights = rights;
250 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
251 but we have a LSA_HANDLE_ACCOUNT here, so this call
253 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
254 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
258 if (!NT_STATUS_IS_OK(status)) {
262 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
263 LDB_FLAG_MOD_DELETE, astate->account_sid,
265 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
269 if (!NT_STATUS_IS_OK(status)) {
273 ZERO_STRUCTP(r->out.handle);
276 return NT_STATUS_INVALID_HANDLE;
283 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
284 struct lsa_EnumPrivs *r)
286 struct dcesrv_handle *h;
287 struct lsa_policy_state *state;
289 const char *privname;
291 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
295 i = *r->in.resume_handle;
298 while ((privname = sec_privilege_name(i)) &&
299 r->out.privs->count < r->in.max_count) {
300 struct lsa_PrivEntry *e;
302 r->out.privs->privs = talloc_realloc(r->out.privs,
304 struct lsa_PrivEntry,
305 r->out.privs->count+1);
306 if (r->out.privs->privs == NULL) {
307 return NT_STATUS_NO_MEMORY;
309 e = &r->out.privs->privs[r->out.privs->count];
312 e->name.string = privname;
313 r->out.privs->count++;
317 *r->out.resume_handle = i;
326 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
327 struct lsa_QuerySecurity *r)
329 struct dcesrv_handle *h;
330 struct security_descriptor *sd;
334 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
336 sid = dce_call->conn->auth_state.session_info->security_token->user_sid;
338 if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
339 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid, 0);
340 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
341 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid,
342 LSA_ACCOUNT_ALL_ACCESS);
344 return NT_STATUS_INVALID_HANDLE;
346 NT_STATUS_NOT_OK_RETURN(status);
348 (*r->out.sdbuf) = talloc(mem_ctx, struct sec_desc_buf);
349 NT_STATUS_HAVE_NO_MEMORY(*r->out.sdbuf);
351 (*r->out.sdbuf)->sd = sd;
360 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
361 struct lsa_SetSecObj *r)
363 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
370 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
371 struct lsa_ChangePassword *r)
373 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
377 dssetup_DsRoleGetPrimaryDomainInformation
379 This is not an LSA call, but is the only call left on the DSSETUP
380 pipe (after the pipe was truncated), and needs lsa_get_policy_state
382 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
384 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
386 union dssetup_DsRoleInfo *info;
388 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
389 W_ERROR_HAVE_NO_MEMORY(info);
391 switch (r->in.level) {
392 case DS_ROLE_BASIC_INFORMATION:
394 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
396 const char *domain = NULL;
397 const char *dns_domain = NULL;
398 const char *forest = NULL;
399 struct GUID domain_guid;
400 struct lsa_policy_state *state;
402 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
403 if (!NT_STATUS_IS_OK(status)) {
404 return ntstatus_to_werror(status);
407 ZERO_STRUCT(domain_guid);
409 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
410 case ROLE_STANDALONE:
411 role = DS_ROLE_STANDALONE_SERVER;
413 case ROLE_DOMAIN_MEMBER:
414 role = DS_ROLE_MEMBER_SERVER;
416 case ROLE_DOMAIN_CONTROLLER:
417 if (samdb_is_pdc(state->sam_ldb)) {
418 role = DS_ROLE_PRIMARY_DC;
420 role = DS_ROLE_BACKUP_DC;
425 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
426 case ROLE_STANDALONE:
427 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
428 W_ERROR_HAVE_NO_MEMORY(domain);
430 case ROLE_DOMAIN_MEMBER:
431 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
432 W_ERROR_HAVE_NO_MEMORY(domain);
433 /* TODO: what is with dns_domain and forest and guid? */
435 case ROLE_DOMAIN_CONTROLLER:
436 flags = DS_ROLE_PRIMARY_DS_RUNNING;
438 if (state->mixed_domain == 1) {
439 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
442 domain = state->domain_name;
443 dns_domain = state->domain_dns;
444 forest = state->forest_dns;
446 domain_guid = state->domain_guid;
447 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
451 info->basic.role = role;
452 info->basic.flags = flags;
453 info->basic.domain = domain;
454 info->basic.dns_domain = dns_domain;
455 info->basic.forest = forest;
456 info->basic.domain_guid = domain_guid;
461 case DS_ROLE_UPGRADE_STATUS:
463 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
464 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
469 case DS_ROLE_OP_STATUS:
471 info->opstatus.status = DS_ROLE_OP_IDLE;
477 return WERR_INVALID_PARAM;
480 return WERR_INVALID_PARAM;
484 fill in the AccountDomain info
486 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
487 struct lsa_DomainInfo *info)
489 info->name.string = state->domain_name;
490 info->sid = state->domain_sid;
496 fill in the DNS domain info
498 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
499 struct lsa_DnsDomainInfo *info)
501 info->name.string = state->domain_name;
502 info->sid = state->domain_sid;
503 info->dns_domain.string = state->domain_dns;
504 info->dns_forest.string = state->forest_dns;
505 info->domain_guid = state->domain_guid;
513 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
514 struct lsa_QueryInfoPolicy2 *r)
516 struct lsa_policy_state *state;
517 struct dcesrv_handle *h;
518 union lsa_PolicyInformation *info;
522 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
526 info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
528 return NT_STATUS_NO_MEMORY;
532 switch (r->in.level) {
533 case LSA_POLICY_INFO_AUDIT_LOG:
534 /* we don't need to fill in any of this */
535 ZERO_STRUCT(info->audit_log);
537 case LSA_POLICY_INFO_AUDIT_EVENTS:
538 /* we don't need to fill in any of this */
539 ZERO_STRUCT(info->audit_events);
541 case LSA_POLICY_INFO_PD:
542 /* we don't need to fill in any of this */
543 ZERO_STRUCT(info->pd);
546 case LSA_POLICY_INFO_DOMAIN:
547 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
548 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
549 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
550 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
551 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
554 case LSA_POLICY_INFO_ROLE:
555 info->role.role = LSA_ROLE_PRIMARY;
558 case LSA_POLICY_INFO_DNS:
559 case LSA_POLICY_INFO_DNS_INT:
560 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
562 case LSA_POLICY_INFO_REPLICA:
563 ZERO_STRUCT(info->replica);
566 case LSA_POLICY_INFO_QUOTA:
567 ZERO_STRUCT(info->quota);
570 case LSA_POLICY_INFO_MOD:
571 case LSA_POLICY_INFO_AUDIT_FULL_SET:
572 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
573 /* windows gives INVALID_PARAMETER */
575 return NT_STATUS_INVALID_PARAMETER;
579 return NT_STATUS_INVALID_INFO_CLASS;
585 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
586 struct lsa_QueryInfoPolicy *r)
588 struct lsa_QueryInfoPolicy2 r2;
593 r2.in.handle = r->in.handle;
594 r2.in.level = r->in.level;
595 r2.out.info = r->out.info;
597 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
605 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
606 struct lsa_SetInfoPolicy *r)
608 /* need to support this */
609 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
616 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
617 struct lsa_ClearAuditLog *r)
619 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
626 This call does not seem to have any long-term effects, hence no database operations
628 we need to talk to the MS product group to find out what this account database means!
630 answer is that the lsa database is totally separate from the SAM and
631 ldap databases. We are going to need a separate ldb to store these
632 accounts. The SIDs on this account bear no relation to the SIDs in
635 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
636 struct lsa_CreateAccount *r)
638 struct lsa_account_state *astate;
640 struct lsa_policy_state *state;
641 struct dcesrv_handle *h, *ah;
643 ZERO_STRUCTP(r->out.acct_handle);
645 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
649 astate = talloc(dce_call->conn, struct lsa_account_state);
650 if (astate == NULL) {
651 return NT_STATUS_NO_MEMORY;
654 astate->account_sid = dom_sid_dup(astate, r->in.sid);
655 if (astate->account_sid == NULL) {
657 return NT_STATUS_NO_MEMORY;
660 astate->policy = talloc_reference(astate, state);
661 astate->access_mask = r->in.access_mask;
663 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
666 return NT_STATUS_NO_MEMORY;
669 ah->data = talloc_steal(ah, astate);
671 *r->out.acct_handle = ah->wire_handle;
680 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
681 struct lsa_EnumAccounts *r)
683 struct dcesrv_handle *h;
684 struct lsa_policy_state *state;
686 struct ldb_message **res;
687 const char * const attrs[] = { "objectSid", NULL};
690 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
694 /* NOTE: This call must only return accounts that have at least
697 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
698 "(&(objectSid=*)(privilege=*))");
700 return NT_STATUS_NO_SUCH_USER;
703 if (*r->in.resume_handle >= ret) {
704 return NT_STATUS_NO_MORE_ENTRIES;
707 count = ret - *r->in.resume_handle;
708 if (count > r->in.num_entries) {
709 count = r->in.num_entries;
713 return NT_STATUS_NO_MORE_ENTRIES;
716 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
717 if (r->out.sids->sids == NULL) {
718 return NT_STATUS_NO_MEMORY;
721 for (i=0;i<count;i++) {
722 r->out.sids->sids[i].sid =
723 samdb_result_dom_sid(r->out.sids->sids,
724 res[i + *r->in.resume_handle],
726 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
729 r->out.sids->num_sids = count;
730 *r->out.resume_handle = count + *r->in.resume_handle;
738 lsa_CreateTrustedDomainEx2
740 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
742 struct lsa_CreateTrustedDomainEx2 *r,
745 struct dcesrv_handle *policy_handle;
746 struct lsa_policy_state *policy_state;
747 struct lsa_trusted_domain_state *trusted_domain_state;
748 struct dcesrv_handle *handle;
749 struct ldb_message **msgs, *msg, *msg_user;
750 const char *attrs[] = {
753 const char *netbios_name;
754 const char *dns_name;
756 DATA_BLOB session_key = data_blob(NULL, 0);
757 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
758 struct trustDomainPasswords auth_struct;
761 enum ndr_err_code ndr_err;
763 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
764 ZERO_STRUCTP(r->out.trustdom_handle);
766 policy_state = policy_handle->data;
768 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
769 if (!NT_STATUS_IS_OK(nt_status)) {
773 netbios_name = r->in.info->netbios_name.string;
775 return NT_STATUS_INVALID_PARAMETER;
778 dns_name = r->in.info->domain_name.string;
780 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
781 if (!trusted_domain_state) {
782 return NT_STATUS_NO_MEMORY;
784 trusted_domain_state->policy = policy_state;
786 if (strcasecmp(netbios_name, "BUILTIN") == 0
787 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
788 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
789 return NT_STATUS_INVALID_PARAMETER;;
792 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
793 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
794 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
795 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
796 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
797 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
800 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
801 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
802 /* No secrets are created at this time, for this function */
803 auth_struct.outgoing.count = 0;
804 auth_struct.incoming.count = 0;
806 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data, r->in.auth_info->auth_blob.size);
807 arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key);
808 ndr_err = ndr_pull_struct_blob(&auth_blob, mem_ctx,
809 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
811 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
812 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
813 return NT_STATUS_INVALID_PARAMETER;
816 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
817 if (auth_struct.incoming.count > 1) {
818 return NT_STATUS_INVALID_PARAMETER;
823 if (auth_struct.incoming.count) {
825 struct trustAuthInOutBlob incoming;
827 incoming.count = auth_struct.incoming.count;
828 incoming.current = talloc(mem_ctx, struct AuthenticationInformationArray);
829 if (!incoming.current) {
830 return NT_STATUS_NO_MEMORY;
833 incoming.current->array = *auth_struct.incoming.current;
834 if (!incoming.current->array) {
835 return NT_STATUS_NO_MEMORY;
838 incoming.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
839 if (!incoming.previous) {
840 return NT_STATUS_NO_MEMORY;
842 incoming.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, incoming.count);
843 if (!incoming.previous->array) {
844 return NT_STATUS_NO_MEMORY;
847 for (i = 0; i < incoming.count; i++) {
848 incoming.previous->array[i].LastUpdateTime = 0;
849 incoming.previous->array[i].AuthType = 0;
851 ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx,
852 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
854 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
855 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
856 return NT_STATUS_INVALID_PARAMETER;
859 trustAuthIncoming = data_blob(NULL, 0);
862 if (auth_struct.outgoing.count) {
864 struct trustAuthInOutBlob outgoing;
866 outgoing.count = auth_struct.outgoing.count;
867 outgoing.current = talloc(mem_ctx, struct AuthenticationInformationArray);
868 if (!outgoing.current) {
869 return NT_STATUS_NO_MEMORY;
872 outgoing.current->array = *auth_struct.outgoing.current;
873 if (!outgoing.current->array) {
874 return NT_STATUS_NO_MEMORY;
877 outgoing.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
878 if (!outgoing.previous) {
879 return NT_STATUS_NO_MEMORY;
881 outgoing.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, outgoing.count);
882 if (!outgoing.previous->array) {
883 return NT_STATUS_NO_MEMORY;
886 for (i = 0; i < outgoing.count; i++) {
887 outgoing.previous->array[i].LastUpdateTime = 0;
888 outgoing.previous->array[i].AuthType = 0;
890 ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx,
891 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
893 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
894 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
895 return NT_STATUS_INVALID_PARAMETER;
898 trustAuthOutgoing = data_blob(NULL, 0);
901 ret = ldb_transaction_start(policy_state->sam_ldb);
902 if (ret != LDB_SUCCESS) {
903 return NT_STATUS_INTERNAL_DB_CORRUPTION;
907 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
908 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
909 /* search for the trusted_domain record */
910 ret = gendb_search(policy_state->sam_ldb,
911 mem_ctx, policy_state->system_dn, &msgs, attrs,
912 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
913 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
915 ldb_transaction_cancel(policy_state->sam_ldb);
916 return NT_STATUS_OBJECT_NAME_COLLISION;
919 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
920 /* search for the trusted_domain record */
921 ret = gendb_search(policy_state->sam_ldb,
922 mem_ctx, policy_state->system_dn, &msgs, attrs,
923 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
924 netbios_encoded, netbios_encoded, netbios_encoded);
926 ldb_transaction_cancel(policy_state->sam_ldb);
927 return NT_STATUS_OBJECT_NAME_COLLISION;
932 ldb_transaction_cancel(policy_state->sam_ldb);
933 return NT_STATUS_INTERNAL_DB_CORRUPTION;
936 name = dns_name ? dns_name : netbios_name;
938 msg = ldb_msg_new(mem_ctx);
940 return NT_STATUS_NO_MEMORY;
943 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
944 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
945 ldb_transaction_cancel(policy_state->sam_ldb);
946 return NT_STATUS_NO_MEMORY;
949 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", netbios_name);
951 if (r->in.info->sid) {
952 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
954 ldb_transaction_cancel(policy_state->sam_ldb);
955 return NT_STATUS_NO_MEMORY;
958 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
961 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
963 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
965 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
967 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
970 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
973 if (trustAuthIncoming.data) {
974 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
975 if (ret != LDB_SUCCESS) {
976 ldb_transaction_cancel(policy_state->sam_ldb);
977 return NT_STATUS_NO_MEMORY;
980 if (trustAuthOutgoing.data) {
981 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
982 if (ret != LDB_SUCCESS) {
983 ldb_transaction_cancel(policy_state->sam_ldb);
984 return NT_STATUS_NO_MEMORY;
988 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
990 /* create the trusted_domain */
991 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
995 case LDB_ERR_ENTRY_ALREADY_EXISTS:
996 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
997 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
998 ldb_dn_get_linearized(msg->dn),
999 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1000 return NT_STATUS_DOMAIN_EXISTS;
1001 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1002 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1003 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1004 ldb_dn_get_linearized(msg->dn),
1005 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1006 return NT_STATUS_ACCESS_DENIED;
1008 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1009 DEBUG(0,("Failed to create user record %s: %s\n",
1010 ldb_dn_get_linearized(msg->dn),
1011 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1012 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1015 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1016 msg_user = ldb_msg_new(mem_ctx);
1017 if (msg_user == NULL) {
1018 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1019 return NT_STATUS_NO_MEMORY;
1022 /* Inbound trusts must also create a cn=users object to match */
1024 trusted_domain_state->trusted_domain_user_dn = msg_user->dn
1025 = ldb_dn_copy(trusted_domain_state, policy_state->domain_dn);
1026 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=users")) {
1027 ldb_transaction_cancel(policy_state->sam_ldb);
1028 return NT_STATUS_NO_MEMORY;
1031 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=%s", netbios_name)) {
1032 ldb_transaction_cancel(policy_state->sam_ldb);
1033 return NT_STATUS_NO_MEMORY;
1036 ldb_msg_add_string(msg_user, "objectClass", "user");
1038 ldb_msg_add_steal_string(msg_user, "samAccountName",
1039 talloc_asprintf(mem_ctx, "%s$", netbios_name));
1041 if (samdb_msg_add_uint(trusted_domain_state->policy->sam_ldb, mem_ctx, msg_user,
1042 "userAccountControl",
1043 UF_INTERDOMAIN_TRUST_ACCOUNT) != 0) {
1044 ldb_transaction_cancel(policy_state->sam_ldb);
1045 return NT_STATUS_NO_MEMORY;
1048 if (auth_struct.incoming.count) {
1050 for (i=0; i < auth_struct.incoming.count; i++ ) {
1051 if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_NT4OWF) {
1052 samdb_msg_add_hash(trusted_domain_state->policy->sam_ldb,
1053 mem_ctx, msg_user, "unicodePwd",
1054 &auth_struct.incoming.current[i]->AuthInfo.nt4owf.password);
1055 } else if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_CLEAR) {
1056 DATA_BLOB new_password = data_blob_const(auth_struct.incoming.current[i]->AuthInfo.clear.password,
1057 auth_struct.incoming.current[i]->AuthInfo.clear.size);
1058 ret = ldb_msg_add_value(msg_user, "clearTextPassword", &new_password, NULL);
1059 if (ret != LDB_SUCCESS) {
1060 ldb_transaction_cancel(policy_state->sam_ldb);
1061 return NT_STATUS_NO_MEMORY;
1067 /* create the cn=users trusted_domain account */
1068 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg_user);
1072 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1073 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1074 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1075 ldb_dn_get_linearized(msg_user->dn),
1076 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1077 return NT_STATUS_DOMAIN_EXISTS;
1078 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1079 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1080 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1081 ldb_dn_get_linearized(msg_user->dn),
1082 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1083 return NT_STATUS_ACCESS_DENIED;
1085 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1086 DEBUG(0,("Failed to create user record %s: %s\n",
1087 ldb_dn_get_linearized(msg_user->dn),
1088 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1089 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1093 ret = ldb_transaction_commit(policy_state->sam_ldb);
1094 if (ret != LDB_SUCCESS) {
1095 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1098 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1100 return NT_STATUS_NO_MEMORY;
1103 handle->data = talloc_steal(handle, trusted_domain_state);
1105 trusted_domain_state->access_mask = r->in.access_mask;
1106 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1108 *r->out.trustdom_handle = handle->wire_handle;
1110 return NT_STATUS_OK;
1114 lsa_CreateTrustedDomainEx2
1116 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1117 TALLOC_CTX *mem_ctx,
1118 struct lsa_CreateTrustedDomainEx2 *r)
1120 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
1123 lsa_CreateTrustedDomainEx
1125 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1126 TALLOC_CTX *mem_ctx,
1127 struct lsa_CreateTrustedDomainEx *r)
1129 struct lsa_CreateTrustedDomainEx2 r2;
1131 r2.in.policy_handle = r->in.policy_handle;
1132 r2.in.info = r->in.info;
1133 r2.in.auth_info = r->in.auth_info;
1134 r2.out.trustdom_handle = r->out.trustdom_handle;
1135 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
1139 lsa_CreateTrustedDomain
1141 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1142 struct lsa_CreateTrustedDomain *r)
1144 struct lsa_CreateTrustedDomainEx2 r2;
1146 r2.in.policy_handle = r->in.policy_handle;
1147 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1149 return NT_STATUS_NO_MEMORY;
1152 r2.in.info->domain_name.string = NULL;
1153 r2.in.info->netbios_name = r->in.info->name;
1154 r2.in.info->sid = r->in.info->sid;
1155 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1156 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1157 r2.in.info->trust_attributes = 0;
1159 r2.in.access_mask = r->in.access_mask;
1160 r2.out.trustdom_handle = r->out.trustdom_handle;
1162 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1167 lsa_OpenTrustedDomain
1169 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1170 struct lsa_OpenTrustedDomain *r)
1172 struct dcesrv_handle *policy_handle;
1174 struct lsa_policy_state *policy_state;
1175 struct lsa_trusted_domain_state *trusted_domain_state;
1176 struct dcesrv_handle *handle;
1177 struct ldb_message **msgs;
1178 const char *attrs[] = {
1184 const char *sid_string;
1187 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1188 ZERO_STRUCTP(r->out.trustdom_handle);
1189 policy_state = policy_handle->data;
1191 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1192 if (!trusted_domain_state) {
1193 return NT_STATUS_NO_MEMORY;
1195 trusted_domain_state->policy = policy_state;
1197 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1199 return NT_STATUS_NO_MEMORY;
1202 /* search for the trusted_domain record */
1203 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1204 mem_ctx, policy_state->system_dn, &msgs, attrs,
1205 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
1208 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1212 DEBUG(0,("Found %d records matching DN %s\n", ret,
1213 ldb_dn_get_linearized(policy_state->system_dn)));
1214 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1217 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1219 trusted_domain_state->trusted_domain_user_dn = NULL;
1221 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1222 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1223 /* search for the trusted_domain record */
1224 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1225 mem_ctx, policy_state->domain_dn, &msgs, attrs,
1226 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%d))",
1227 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1229 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1232 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1234 return NT_STATUS_NO_MEMORY;
1237 handle->data = talloc_steal(handle, trusted_domain_state);
1239 trusted_domain_state->access_mask = r->in.access_mask;
1240 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1242 *r->out.trustdom_handle = handle->wire_handle;
1244 return NT_STATUS_OK;
1249 lsa_OpenTrustedDomainByName
1251 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1252 TALLOC_CTX *mem_ctx,
1253 struct lsa_OpenTrustedDomainByName *r)
1255 struct dcesrv_handle *policy_handle;
1257 struct lsa_policy_state *policy_state;
1258 struct lsa_trusted_domain_state *trusted_domain_state;
1259 struct dcesrv_handle *handle;
1260 struct ldb_message **msgs;
1261 const char *attrs[] = {
1267 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1268 ZERO_STRUCTP(r->out.trustdom_handle);
1269 policy_state = policy_handle->data;
1271 if (!r->in.name.string) {
1272 return NT_STATUS_INVALID_PARAMETER;
1275 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1276 if (!trusted_domain_state) {
1277 return NT_STATUS_NO_MEMORY;
1279 trusted_domain_state->policy = policy_state;
1281 /* search for the trusted_domain record */
1282 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1283 mem_ctx, policy_state->system_dn, &msgs, attrs,
1284 "(&(flatname=%s)(objectclass=trustedDomain))",
1285 ldb_binary_encode_string(mem_ctx, r->in.name.string));
1287 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1291 DEBUG(0,("Found %d records matching DN %s\n", ret,
1292 ldb_dn_get_linearized(policy_state->system_dn)));
1293 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1296 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1298 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1300 return NT_STATUS_NO_MEMORY;
1303 handle->data = talloc_steal(handle, trusted_domain_state);
1305 trusted_domain_state->access_mask = r->in.access_mask;
1306 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1308 *r->out.trustdom_handle = handle->wire_handle;
1310 return NT_STATUS_OK;
1316 lsa_SetTrustedDomainInfo
1318 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1319 struct lsa_SetTrustedDomainInfo *r)
1321 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1327 lsa_SetInfomrationTrustedDomain
1329 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1330 TALLOC_CTX *mem_ctx,
1331 struct lsa_SetInformationTrustedDomain *r)
1333 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1338 lsa_DeleteTrustedDomain
1340 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1341 struct lsa_DeleteTrustedDomain *r)
1344 struct lsa_OpenTrustedDomain opn;
1345 struct lsa_DeleteObject del;
1346 struct dcesrv_handle *h;
1348 opn.in.handle = r->in.handle;
1349 opn.in.sid = r->in.dom_sid;
1350 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1351 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1352 if (!opn.out.trustdom_handle) {
1353 return NT_STATUS_NO_MEMORY;
1355 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1356 if (!NT_STATUS_IS_OK(status)) {
1360 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1361 talloc_steal(mem_ctx, h);
1363 del.in.handle = opn.out.trustdom_handle;
1364 del.out.handle = opn.out.trustdom_handle;
1365 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
1366 if (!NT_STATUS_IS_OK(status)) {
1369 return NT_STATUS_OK;
1372 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1373 struct ldb_message *msg,
1374 struct lsa_TrustDomainInfoInfoEx *info_ex)
1376 info_ex->domain_name.string
1377 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1378 info_ex->netbios_name.string
1379 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1381 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1382 info_ex->trust_direction
1383 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1385 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1386 info_ex->trust_attributes
1387 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1388 return NT_STATUS_OK;
1392 lsa_QueryTrustedDomainInfo
1394 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1395 struct lsa_QueryTrustedDomainInfo *r)
1397 union lsa_TrustedDomainInfo *info = NULL;
1398 struct dcesrv_handle *h;
1399 struct lsa_trusted_domain_state *trusted_domain_state;
1400 struct ldb_message *msg;
1402 struct ldb_message **res;
1403 const char *attrs[] = {
1406 "securityIdentifier",
1410 "msDs-supportedEncryptionTypes",
1414 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1416 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1418 /* pull all the user attributes */
1419 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1420 trusted_domain_state->trusted_domain_dn, &res, attrs);
1422 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1426 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
1428 return NT_STATUS_NO_MEMORY;
1430 *r->out.info = info;
1432 switch (r->in.level) {
1433 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1434 info->name.netbios_name.string
1435 = samdb_result_string(msg, "flatname", NULL);
1437 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1438 info->posix_offset.posix_offset
1439 = samdb_result_uint(msg, "posixOffset", 0);
1441 #if 0 /* Win2k3 doesn't implement this */
1442 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1443 r->out.info->info_basic.netbios_name.string
1444 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1445 r->out.info->info_basic.sid
1446 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1449 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1450 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
1452 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1453 ZERO_STRUCT(info->full_info);
1454 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
1456 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1457 ZERO_STRUCT(info->full_info2_internal);
1458 info->full_info2_internal.posix_offset.posix_offset
1459 = samdb_result_uint(msg, "posixOffset", 0);
1460 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
1462 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1463 info->enc_types.enc_types
1464 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
1467 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1468 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1469 /* oops, we don't want to return the info after all */
1471 *r->out.info = NULL;
1472 return NT_STATUS_INVALID_PARAMETER;
1474 /* oops, we don't want to return the info after all */
1476 *r->out.info = NULL;
1477 return NT_STATUS_INVALID_INFO_CLASS;
1480 return NT_STATUS_OK;
1485 lsa_QueryTrustedDomainInfoBySid
1487 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1488 struct lsa_QueryTrustedDomainInfoBySid *r)
1491 struct lsa_OpenTrustedDomain opn;
1492 struct lsa_QueryTrustedDomainInfo query;
1493 struct dcesrv_handle *h;
1495 opn.in.handle = r->in.handle;
1496 opn.in.sid = r->in.dom_sid;
1497 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1498 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1499 if (!opn.out.trustdom_handle) {
1500 return NT_STATUS_NO_MEMORY;
1502 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1503 if (!NT_STATUS_IS_OK(status)) {
1507 /* Ensure this handle goes away at the end of this call */
1508 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1509 talloc_steal(mem_ctx, h);
1511 query.in.trustdom_handle = opn.out.trustdom_handle;
1512 query.in.level = r->in.level;
1513 query.out.info = r->out.info;
1514 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1515 if (!NT_STATUS_IS_OK(status)) {
1519 return NT_STATUS_OK;
1523 lsa_SetTrustedDomainInfoByName
1525 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1526 TALLOC_CTX *mem_ctx,
1527 struct lsa_SetTrustedDomainInfoByName *r)
1529 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1533 lsa_QueryTrustedDomainInfoByName
1535 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1536 TALLOC_CTX *mem_ctx,
1537 struct lsa_QueryTrustedDomainInfoByName *r)
1540 struct lsa_OpenTrustedDomainByName opn;
1541 struct lsa_QueryTrustedDomainInfo query;
1542 struct dcesrv_handle *h;
1544 opn.in.handle = r->in.handle;
1545 opn.in.name = *r->in.trusted_domain;
1546 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1547 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1548 if (!opn.out.trustdom_handle) {
1549 return NT_STATUS_NO_MEMORY;
1551 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
1552 if (!NT_STATUS_IS_OK(status)) {
1556 /* Ensure this handle goes away at the end of this call */
1557 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1558 talloc_steal(mem_ctx, h);
1560 query.in.trustdom_handle = opn.out.trustdom_handle;
1561 query.in.level = r->in.level;
1562 query.out.info = r->out.info;
1563 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1564 if (!NT_STATUS_IS_OK(status)) {
1568 return NT_STATUS_OK;
1572 lsa_CloseTrustedDomainEx
1574 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1575 TALLOC_CTX *mem_ctx,
1576 struct lsa_CloseTrustedDomainEx *r)
1578 /* The result of a bad hair day from an IDL programmer? Not
1579 * implmented in Win2k3. You should always just lsa_Close
1581 return NT_STATUS_NOT_IMPLEMENTED;
1586 comparison function for sorting lsa_DomainInformation array
1588 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1590 return strcasecmp_m(e1->name.string, e2->name.string);
1596 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1597 struct lsa_EnumTrustDom *r)
1599 struct dcesrv_handle *policy_handle;
1600 struct lsa_DomainInfo *entries;
1601 struct lsa_policy_state *policy_state;
1602 struct ldb_message **domains;
1603 const char *attrs[] = {
1605 "securityIdentifier",
1612 *r->out.resume_handle = 0;
1614 r->out.domains->domains = NULL;
1615 r->out.domains->count = 0;
1617 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1619 policy_state = policy_handle->data;
1621 /* search for all users in this domain. This could possibly be cached and
1622 resumed based on resume_key */
1623 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1624 "objectclass=trustedDomain");
1626 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1629 /* convert to lsa_TrustInformation format */
1630 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1632 return NT_STATUS_NO_MEMORY;
1634 for (i=0;i<count;i++) {
1635 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1636 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1639 /* sort the results by name */
1640 qsort(entries, count, sizeof(*entries),
1641 (comparison_fn_t)compare_DomainInfo);
1643 if (*r->in.resume_handle >= count) {
1644 *r->out.resume_handle = -1;
1646 return NT_STATUS_NO_MORE_ENTRIES;
1649 /* return the rest, limit by max_size. Note that we
1650 use the w2k3 element size value of 60 */
1651 r->out.domains->count = count - *r->in.resume_handle;
1652 r->out.domains->count = MIN(r->out.domains->count,
1653 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1655 r->out.domains->domains = entries + *r->in.resume_handle;
1656 r->out.domains->count = r->out.domains->count;
1658 if (r->out.domains->count < count - *r->in.resume_handle) {
1659 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1660 return STATUS_MORE_ENTRIES;
1663 return NT_STATUS_OK;
1667 comparison function for sorting lsa_DomainInformation array
1669 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1671 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1675 lsa_EnumTrustedDomainsEx
1677 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1678 struct lsa_EnumTrustedDomainsEx *r)
1680 struct dcesrv_handle *policy_handle;
1681 struct lsa_TrustDomainInfoInfoEx *entries;
1682 struct lsa_policy_state *policy_state;
1683 struct ldb_message **domains;
1684 const char *attrs[] = {
1687 "securityIdentifier",
1697 *r->out.resume_handle = 0;
1699 r->out.domains->domains = NULL;
1700 r->out.domains->count = 0;
1702 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1704 policy_state = policy_handle->data;
1706 /* search for all users in this domain. This could possibly be cached and
1707 resumed based on resume_key */
1708 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1709 "objectclass=trustedDomain");
1711 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1714 /* convert to lsa_DomainInformation format */
1715 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1717 return NT_STATUS_NO_MEMORY;
1719 for (i=0;i<count;i++) {
1720 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1721 if (!NT_STATUS_IS_OK(nt_status)) {
1726 /* sort the results by name */
1727 qsort(entries, count, sizeof(*entries),
1728 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1730 if (*r->in.resume_handle >= count) {
1731 *r->out.resume_handle = -1;
1733 return NT_STATUS_NO_MORE_ENTRIES;
1736 /* return the rest, limit by max_size. Note that we
1737 use the w2k3 element size value of 60 */
1738 r->out.domains->count = count - *r->in.resume_handle;
1739 r->out.domains->count = MIN(r->out.domains->count,
1740 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1742 r->out.domains->domains = entries + *r->in.resume_handle;
1743 r->out.domains->count = r->out.domains->count;
1745 if (r->out.domains->count < count - *r->in.resume_handle) {
1746 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1747 return STATUS_MORE_ENTRIES;
1750 return NT_STATUS_OK;
1757 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1758 struct lsa_OpenAccount *r)
1760 struct dcesrv_handle *h, *ah;
1761 struct lsa_policy_state *state;
1762 struct lsa_account_state *astate;
1764 ZERO_STRUCTP(r->out.acct_handle);
1766 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1770 astate = talloc(dce_call->conn, struct lsa_account_state);
1771 if (astate == NULL) {
1772 return NT_STATUS_NO_MEMORY;
1775 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1776 if (astate->account_sid == NULL) {
1777 talloc_free(astate);
1778 return NT_STATUS_NO_MEMORY;
1781 astate->policy = talloc_reference(astate, state);
1782 astate->access_mask = r->in.access_mask;
1784 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1786 talloc_free(astate);
1787 return NT_STATUS_NO_MEMORY;
1790 ah->data = talloc_steal(ah, astate);
1792 *r->out.acct_handle = ah->wire_handle;
1794 return NT_STATUS_OK;
1799 lsa_EnumPrivsAccount
1801 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1802 TALLOC_CTX *mem_ctx,
1803 struct lsa_EnumPrivsAccount *r)
1805 struct dcesrv_handle *h;
1806 struct lsa_account_state *astate;
1808 struct ldb_message **res;
1809 const char * const attrs[] = { "privilege", NULL};
1810 struct ldb_message_element *el;
1812 struct lsa_PrivilegeSet *privs;
1814 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1818 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1819 if (privs == NULL) {
1820 return NT_STATUS_NO_MEMORY;
1826 *r->out.privs = privs;
1828 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1829 if (sidstr == NULL) {
1830 return NT_STATUS_NO_MEMORY;
1833 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
1834 "objectSid=%s", sidstr);
1836 return NT_STATUS_OK;
1839 el = ldb_msg_find_element(res[0], "privilege");
1840 if (el == NULL || el->num_values == 0) {
1841 return NT_STATUS_OK;
1844 privs->set = talloc_array(privs,
1845 struct lsa_LUIDAttribute, el->num_values);
1846 if (privs->set == NULL) {
1847 return NT_STATUS_NO_MEMORY;
1850 for (i=0;i<el->num_values;i++) {
1851 int id = sec_privilege_id((const char *)el->values[i].data);
1853 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1855 privs->set[i].attribute = 0;
1856 privs->set[i].luid.low = id;
1857 privs->set[i].luid.high = 0;
1860 privs->count = el->num_values;
1862 return NT_STATUS_OK;
1866 lsa_EnumAccountRights
1868 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1869 TALLOC_CTX *mem_ctx,
1870 struct lsa_EnumAccountRights *r)
1872 struct dcesrv_handle *h;
1873 struct lsa_policy_state *state;
1875 struct ldb_message **res;
1876 const char * const attrs[] = { "privilege", NULL};
1878 struct ldb_message_element *el;
1880 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1884 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1885 if (sidstr == NULL) {
1886 return NT_STATUS_NO_MEMORY;
1889 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
1890 "(&(objectSid=%s)(privilege=*))", sidstr);
1892 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1895 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1898 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1899 dom_sid_string(mem_ctx, r->in.sid),
1900 ldb_errstring(state->pdb)));
1901 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1904 el = ldb_msg_find_element(res[0], "privilege");
1905 if (el == NULL || el->num_values == 0) {
1906 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1909 r->out.rights->count = el->num_values;
1910 r->out.rights->names = talloc_array(r->out.rights,
1911 struct lsa_StringLarge, r->out.rights->count);
1912 if (r->out.rights->names == NULL) {
1913 return NT_STATUS_NO_MEMORY;
1916 for (i=0;i<el->num_values;i++) {
1917 r->out.rights->names[i].string = (const char *)el->values[i].data;
1920 return NT_STATUS_OK;
1926 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1928 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1929 TALLOC_CTX *mem_ctx,
1930 struct lsa_policy_state *state,
1932 struct dom_sid *sid,
1933 const struct lsa_RightSet *rights)
1935 const char *sidstr, *sidndrstr;
1936 struct ldb_message *msg;
1937 struct ldb_message_element *el;
1939 struct lsa_EnumAccountRights r2;
1942 if (security_session_user_level(dce_call->conn->auth_state.session_info) <
1943 SECURITY_ADMINISTRATOR) {
1944 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
1945 return NT_STATUS_ACCESS_DENIED;
1948 msg = ldb_msg_new(mem_ctx);
1950 return NT_STATUS_NO_MEMORY;
1953 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
1954 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg);
1956 sidstr = dom_sid_string(msg, sid);
1957 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg);
1959 dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
1960 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg);
1962 msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
1963 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg);
1965 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1968 r2.in.handle = &state->handle->wire_handle;
1970 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1972 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1973 if (!NT_STATUS_IS_OK(status)) {
1974 ZERO_STRUCTP(r2.out.rights);
1978 for (i=0;i<rights->count;i++) {
1979 if (sec_privilege_id(rights->names[i].string) == -1) {
1981 return NT_STATUS_NO_SUCH_PRIVILEGE;
1984 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1986 for (j=0;j<r2.out.rights->count;j++) {
1987 if (strcasecmp_m(r2.out.rights->names[j].string,
1988 rights->names[i].string) == 0) {
1992 if (j != r2.out.rights->count) continue;
1995 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1996 if (ret != LDB_SUCCESS) {
1998 return NT_STATUS_NO_MEMORY;
2002 el = ldb_msg_find_element(msg, "privilege");
2005 return NT_STATUS_OK;
2008 el->flags = ldb_flag;
2010 ret = ldb_modify(state->pdb, msg);
2011 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
2012 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
2014 return NT_STATUS_NO_MEMORY;
2016 samdb_msg_add_string(state->pdb, msg, msg, "comment", "added via LSA");
2017 ret = ldb_add(state->pdb, msg);
2020 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2022 return NT_STATUS_OK;
2024 DEBUG(3, ("Could not %s attributes from %s: %s",
2025 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2026 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
2028 return NT_STATUS_UNEXPECTED_IO_ERROR;
2032 return NT_STATUS_OK;
2036 lsa_AddPrivilegesToAccount
2038 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2039 struct lsa_AddPrivilegesToAccount *r)
2041 struct lsa_RightSet rights;
2042 struct dcesrv_handle *h;
2043 struct lsa_account_state *astate;
2046 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2050 rights.count = r->in.privs->count;
2051 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2052 if (rights.names == NULL) {
2053 return NT_STATUS_NO_MEMORY;
2055 for (i=0;i<rights.count;i++) {
2056 int id = r->in.privs->set[i].luid.low;
2057 if (r->in.privs->set[i].luid.high) {
2058 return NT_STATUS_NO_SUCH_PRIVILEGE;
2060 rights.names[i].string = sec_privilege_name(id);
2061 if (rights.names[i].string == NULL) {
2062 return NT_STATUS_NO_SUCH_PRIVILEGE;
2066 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2067 LDB_FLAG_MOD_ADD, astate->account_sid,
2073 lsa_RemovePrivilegesFromAccount
2075 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2076 struct lsa_RemovePrivilegesFromAccount *r)
2078 struct lsa_RightSet *rights;
2079 struct dcesrv_handle *h;
2080 struct lsa_account_state *astate;
2083 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2087 rights = talloc(mem_ctx, struct lsa_RightSet);
2089 if (r->in.remove_all == 1 &&
2090 r->in.privs == NULL) {
2091 struct lsa_EnumAccountRights r2;
2094 r2.in.handle = &astate->policy->handle->wire_handle;
2095 r2.in.sid = astate->account_sid;
2096 r2.out.rights = rights;
2098 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2099 if (!NT_STATUS_IS_OK(status)) {
2103 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2104 LDB_FLAG_MOD_DELETE, astate->account_sid,
2108 if (r->in.remove_all != 0) {
2109 return NT_STATUS_INVALID_PARAMETER;
2112 rights->count = r->in.privs->count;
2113 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2114 if (rights->names == NULL) {
2115 return NT_STATUS_NO_MEMORY;
2117 for (i=0;i<rights->count;i++) {
2118 int id = r->in.privs->set[i].luid.low;
2119 if (r->in.privs->set[i].luid.high) {
2120 return NT_STATUS_NO_SUCH_PRIVILEGE;
2122 rights->names[i].string = sec_privilege_name(id);
2123 if (rights->names[i].string == NULL) {
2124 return NT_STATUS_NO_SUCH_PRIVILEGE;
2128 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2129 LDB_FLAG_MOD_DELETE, astate->account_sid,
2135 lsa_GetQuotasForAccount
2137 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2138 struct lsa_GetQuotasForAccount *r)
2140 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2145 lsa_SetQuotasForAccount
2147 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2148 struct lsa_SetQuotasForAccount *r)
2150 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2155 lsa_GetSystemAccessAccount
2157 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2158 struct lsa_GetSystemAccessAccount *r)
2162 struct lsa_EnumPrivsAccount enumPrivs;
2163 struct lsa_PrivilegeSet *privs;
2165 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2167 return NT_STATUS_NO_MEMORY;
2173 enumPrivs.in.handle = r->in.handle;
2174 enumPrivs.out.privs = &privs;
2176 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2177 if (!NT_STATUS_IS_OK(status)) {
2181 *(r->out.access_mask) = 0x00000000;
2183 for (i = 0; i < privs->count; i++) {
2184 int priv = privs->set[i].luid.low;
2187 case SEC_PRIV_INTERACTIVE_LOGON:
2188 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2190 case SEC_PRIV_NETWORK_LOGON:
2191 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2193 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2194 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2199 return NT_STATUS_OK;
2204 lsa_SetSystemAccessAccount
2206 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2207 struct lsa_SetSystemAccessAccount *r)
2209 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2216 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2217 struct lsa_CreateSecret *r)
2219 struct dcesrv_handle *policy_handle;
2220 struct lsa_policy_state *policy_state;
2221 struct lsa_secret_state *secret_state;
2222 struct dcesrv_handle *handle;
2223 struct ldb_message **msgs, *msg;
2224 const char *attrs[] = {
2232 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2233 ZERO_STRUCTP(r->out.sec_handle);
2235 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2237 case SECURITY_SYSTEM:
2238 case SECURITY_ADMINISTRATOR:
2241 /* Users and annonymous are not allowed create secrets */
2242 return NT_STATUS_ACCESS_DENIED;
2245 policy_state = policy_handle->data;
2247 if (!r->in.name.string) {
2248 return NT_STATUS_INVALID_PARAMETER;
2251 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2252 if (!secret_state) {
2253 return NT_STATUS_NO_MEMORY;
2255 secret_state->policy = policy_state;
2257 msg = ldb_msg_new(mem_ctx);
2259 return NT_STATUS_NO_MEMORY;
2262 if (strncmp("G$", r->in.name.string, 2) == 0) {
2264 name = &r->in.name.string[2];
2265 /* 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) */
2266 secret_state->sam_ldb = talloc_reference(secret_state,
2267 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(secret_state, dce_call->conn->dce_ctx->lp_ctx)));
2268 secret_state->global = true;
2270 if (strlen(name) < 1) {
2271 return NT_STATUS_INVALID_PARAMETER;
2274 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2275 /* search for the secret record */
2276 ret = gendb_search(secret_state->sam_ldb,
2277 mem_ctx, policy_state->system_dn, &msgs, attrs,
2278 "(&(cn=%s)(objectclass=secret))",
2281 return NT_STATUS_OBJECT_NAME_COLLISION;
2285 DEBUG(0,("Failure searching for CN=%s: %s\n",
2286 name2, ldb_errstring(secret_state->sam_ldb)));
2287 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2290 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2291 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2292 return NT_STATUS_NO_MEMORY;
2295 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2298 secret_state->global = false;
2300 name = r->in.name.string;
2301 if (strlen(name) < 1) {
2302 return NT_STATUS_INVALID_PARAMETER;
2305 secret_state->sam_ldb = talloc_reference(secret_state,
2306 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2307 /* search for the secret record */
2308 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2309 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2311 "(&(cn=%s)(objectclass=secret))",
2312 ldb_binary_encode_string(mem_ctx, name));
2314 return NT_STATUS_OBJECT_NAME_COLLISION;
2318 DEBUG(0,("Failure searching for CN=%s: %s\n",
2319 name, ldb_errstring(secret_state->sam_ldb)));
2320 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2323 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2324 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2327 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2329 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2331 /* create the secret */
2332 ret = ldb_add(secret_state->sam_ldb, msg);
2334 DEBUG(0,("Failed to create secret record %s: %s\n",
2335 ldb_dn_get_linearized(msg->dn),
2336 ldb_errstring(secret_state->sam_ldb)));
2337 return NT_STATUS_ACCESS_DENIED;
2340 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2342 return NT_STATUS_NO_MEMORY;
2345 handle->data = talloc_steal(handle, secret_state);
2347 secret_state->access_mask = r->in.access_mask;
2348 secret_state->policy = talloc_reference(secret_state, policy_state);
2350 *r->out.sec_handle = handle->wire_handle;
2352 return NT_STATUS_OK;
2359 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2360 struct lsa_OpenSecret *r)
2362 struct dcesrv_handle *policy_handle;
2364 struct lsa_policy_state *policy_state;
2365 struct lsa_secret_state *secret_state;
2366 struct dcesrv_handle *handle;
2367 struct ldb_message **msgs;
2368 const char *attrs[] = {
2376 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2377 ZERO_STRUCTP(r->out.sec_handle);
2378 policy_state = policy_handle->data;
2380 if (!r->in.name.string) {
2381 return NT_STATUS_INVALID_PARAMETER;
2384 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2386 case SECURITY_SYSTEM:
2387 case SECURITY_ADMINISTRATOR:
2390 /* Users and annonymous are not allowed to access secrets */
2391 return NT_STATUS_ACCESS_DENIED;
2394 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2395 if (!secret_state) {
2396 return NT_STATUS_NO_MEMORY;
2398 secret_state->policy = policy_state;
2400 if (strncmp("G$", r->in.name.string, 2) == 0) {
2401 name = &r->in.name.string[2];
2402 /* 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) */
2403 secret_state->sam_ldb = talloc_reference(secret_state,
2404 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(secret_state, dce_call->conn->dce_ctx->lp_ctx)));
2405 secret_state->global = true;
2407 if (strlen(name) < 1) {
2408 return NT_STATUS_INVALID_PARAMETER;
2411 /* search for the secret record */
2412 ret = gendb_search(secret_state->sam_ldb,
2413 mem_ctx, policy_state->system_dn, &msgs, attrs,
2414 "(&(cn=%s Secret)(objectclass=secret))",
2415 ldb_binary_encode_string(mem_ctx, name));
2417 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2421 DEBUG(0,("Found %d records matching DN %s\n", ret,
2422 ldb_dn_get_linearized(policy_state->system_dn)));
2423 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2427 secret_state->global = false;
2428 secret_state->sam_ldb = talloc_reference(secret_state,
2429 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2431 name = r->in.name.string;
2432 if (strlen(name) < 1) {
2433 return NT_STATUS_INVALID_PARAMETER;
2436 /* search for the secret record */
2437 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2438 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2440 "(&(cn=%s)(objectclass=secret))",
2441 ldb_binary_encode_string(mem_ctx, name));
2443 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2447 DEBUG(0,("Found %d records matching CN=%s\n",
2448 ret, ldb_binary_encode_string(mem_ctx, name)));
2449 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2453 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2455 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2457 return NT_STATUS_NO_MEMORY;
2460 handle->data = talloc_steal(handle, secret_state);
2462 secret_state->access_mask = r->in.access_mask;
2463 secret_state->policy = talloc_reference(secret_state, policy_state);
2465 *r->out.sec_handle = handle->wire_handle;
2467 return NT_STATUS_OK;
2474 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2475 struct lsa_SetSecret *r)
2478 struct dcesrv_handle *h;
2479 struct lsa_secret_state *secret_state;
2480 struct ldb_message *msg;
2481 DATA_BLOB session_key;
2482 DATA_BLOB crypt_secret, secret;
2485 NTSTATUS status = NT_STATUS_OK;
2487 struct timeval now = timeval_current();
2488 NTTIME nt_now = timeval_to_nttime(&now);
2490 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2492 secret_state = h->data;
2494 msg = ldb_msg_new(mem_ctx);
2496 return NT_STATUS_NO_MEMORY;
2499 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2501 return NT_STATUS_NO_MEMORY;
2503 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2504 if (!NT_STATUS_IS_OK(status)) {
2508 if (r->in.old_val) {
2510 crypt_secret.data = r->in.old_val->data;
2511 crypt_secret.length = r->in.old_val->size;
2513 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2514 if (!NT_STATUS_IS_OK(status)) {
2518 val.data = secret.data;
2519 val.length = secret.length;
2522 if (samdb_msg_add_value(secret_state->sam_ldb,
2523 mem_ctx, msg, "priorValue", &val) != 0) {
2524 return NT_STATUS_NO_MEMORY;
2527 /* set old value mtime */
2528 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2529 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2530 return NT_STATUS_NO_MEMORY;
2534 /* If the old value is not set, then migrate the
2535 * current value to the old value */
2536 const struct ldb_val *old_val;
2537 NTTIME last_set_time;
2538 struct ldb_message **res;
2539 const char *attrs[] = {
2545 /* search for the secret record */
2546 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2547 secret_state->secret_dn, &res, attrs);
2549 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2553 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2554 ldb_dn_get_linearized(secret_state->secret_dn)));
2555 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2558 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2559 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2563 if (samdb_msg_add_value(secret_state->sam_ldb,
2564 mem_ctx, msg, "priorValue",
2566 return NT_STATUS_NO_MEMORY;
2569 if (samdb_msg_add_delete(secret_state->sam_ldb,
2570 mem_ctx, msg, "priorValue")) {
2571 return NT_STATUS_NO_MEMORY;
2576 /* set old value mtime */
2577 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2578 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2579 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2580 return NT_STATUS_NO_MEMORY;
2583 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2584 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2585 return NT_STATUS_NO_MEMORY;
2590 if (r->in.new_val) {
2592 crypt_secret.data = r->in.new_val->data;
2593 crypt_secret.length = r->in.new_val->size;
2595 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2596 if (!NT_STATUS_IS_OK(status)) {
2600 val.data = secret.data;
2601 val.length = secret.length;
2604 if (samdb_msg_add_value(secret_state->sam_ldb,
2605 mem_ctx, msg, "currentValue", &val) != 0) {
2606 return NT_STATUS_NO_MEMORY;
2609 /* set new value mtime */
2610 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2611 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2612 return NT_STATUS_NO_MEMORY;
2616 /* NULL out the NEW value */
2617 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2618 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2619 return NT_STATUS_NO_MEMORY;
2621 if (samdb_msg_add_delete(secret_state->sam_ldb,
2622 mem_ctx, msg, "currentValue")) {
2623 return NT_STATUS_NO_MEMORY;
2627 /* modify the samdb record */
2628 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2630 /* we really need samdb.c to return NTSTATUS */
2631 return NT_STATUS_UNSUCCESSFUL;
2634 return NT_STATUS_OK;
2641 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2642 struct lsa_QuerySecret *r)
2644 struct dcesrv_handle *h;
2645 struct lsa_secret_state *secret_state;
2646 struct ldb_message *msg;
2647 DATA_BLOB session_key;
2648 DATA_BLOB crypt_secret, secret;
2650 struct ldb_message **res;
2651 const char *attrs[] = {
2661 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2663 /* Ensure user is permitted to read this... */
2664 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2666 case SECURITY_SYSTEM:
2667 case SECURITY_ADMINISTRATOR:
2670 /* Users and annonymous are not allowed to read secrets */
2671 return NT_STATUS_ACCESS_DENIED;
2674 secret_state = h->data;
2676 /* pull all the user attributes */
2677 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2678 secret_state->secret_dn, &res, attrs);
2680 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2684 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2685 if (!NT_STATUS_IS_OK(nt_status)) {
2689 if (r->in.old_val) {
2690 const struct ldb_val *prior_val;
2691 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2692 if (!r->out.old_val) {
2693 return NT_STATUS_NO_MEMORY;
2695 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2697 if (prior_val && prior_val->length) {
2698 secret.data = prior_val->data;
2699 secret.length = prior_val->length;
2702 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2703 if (!crypt_secret.length) {
2704 return NT_STATUS_NO_MEMORY;
2706 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2707 if (!r->out.old_val->buf) {
2708 return NT_STATUS_NO_MEMORY;
2710 r->out.old_val->buf->size = crypt_secret.length;
2711 r->out.old_val->buf->length = crypt_secret.length;
2712 r->out.old_val->buf->data = crypt_secret.data;
2716 if (r->in.old_mtime) {
2717 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2718 if (!r->out.old_mtime) {
2719 return NT_STATUS_NO_MEMORY;
2721 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2724 if (r->in.new_val) {
2725 const struct ldb_val *new_val;
2726 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2727 if (!r->out.new_val) {
2728 return NT_STATUS_NO_MEMORY;
2731 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2733 if (new_val && new_val->length) {
2734 secret.data = new_val->data;
2735 secret.length = new_val->length;
2738 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2739 if (!crypt_secret.length) {
2740 return NT_STATUS_NO_MEMORY;
2742 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2743 if (!r->out.new_val->buf) {
2744 return NT_STATUS_NO_MEMORY;
2746 r->out.new_val->buf->length = crypt_secret.length;
2747 r->out.new_val->buf->size = crypt_secret.length;
2748 r->out.new_val->buf->data = crypt_secret.data;
2752 if (r->in.new_mtime) {
2753 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2754 if (!r->out.new_mtime) {
2755 return NT_STATUS_NO_MEMORY;
2757 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2760 return NT_STATUS_OK;
2767 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2768 TALLOC_CTX *mem_ctx,
2769 struct lsa_LookupPrivValue *r)
2771 struct dcesrv_handle *h;
2772 struct lsa_policy_state *state;
2775 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2779 id = sec_privilege_id(r->in.name->string);
2781 return NT_STATUS_NO_SUCH_PRIVILEGE;
2784 r->out.luid->low = id;
2785 r->out.luid->high = 0;
2787 return NT_STATUS_OK;
2794 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2795 TALLOC_CTX *mem_ctx,
2796 struct lsa_LookupPrivName *r)
2798 struct dcesrv_handle *h;
2799 struct lsa_policy_state *state;
2800 struct lsa_StringLarge *name;
2801 const char *privname;
2803 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2807 if (r->in.luid->high != 0) {
2808 return NT_STATUS_NO_SUCH_PRIVILEGE;
2811 privname = sec_privilege_name(r->in.luid->low);
2812 if (privname == NULL) {
2813 return NT_STATUS_NO_SUCH_PRIVILEGE;
2816 name = talloc(mem_ctx, struct lsa_StringLarge);
2818 return NT_STATUS_NO_MEMORY;
2821 name->string = privname;
2823 *r->out.name = name;
2825 return NT_STATUS_OK;
2830 lsa_LookupPrivDisplayName
2832 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2833 TALLOC_CTX *mem_ctx,
2834 struct lsa_LookupPrivDisplayName *r)
2836 struct dcesrv_handle *h;
2837 struct lsa_policy_state *state;
2838 struct lsa_StringLarge *disp_name = NULL;
2841 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2845 id = sec_privilege_id(r->in.name->string);
2847 return NT_STATUS_NO_SUCH_PRIVILEGE;
2850 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2851 if (disp_name == NULL) {
2852 return NT_STATUS_NO_MEMORY;
2855 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
2856 if (disp_name->string == NULL) {
2857 return NT_STATUS_INTERNAL_ERROR;
2860 *r->out.disp_name = disp_name;
2861 *r->out.returned_language_id = 0;
2863 return NT_STATUS_OK;
2868 lsa_EnumAccountsWithUserRight
2870 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2871 TALLOC_CTX *mem_ctx,
2872 struct lsa_EnumAccountsWithUserRight *r)
2874 struct dcesrv_handle *h;
2875 struct lsa_policy_state *state;
2877 struct ldb_message **res;
2878 const char * const attrs[] = { "objectSid", NULL};
2879 const char *privname;
2881 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2885 if (r->in.name == NULL) {
2886 return NT_STATUS_NO_SUCH_PRIVILEGE;
2889 privname = r->in.name->string;
2890 if (sec_privilege_id(privname) == -1) {
2891 return NT_STATUS_NO_SUCH_PRIVILEGE;
2894 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2895 "privilege=%s", privname);
2897 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2900 return NT_STATUS_NO_MORE_ENTRIES;
2903 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2904 if (r->out.sids->sids == NULL) {
2905 return NT_STATUS_NO_MEMORY;
2907 for (i=0;i<ret;i++) {
2908 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2909 res[i], "objectSid");
2910 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2912 r->out.sids->num_sids = ret;
2914 return NT_STATUS_OK;
2919 lsa_AddAccountRights
2921 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2922 TALLOC_CTX *mem_ctx,
2923 struct lsa_AddAccountRights *r)
2925 struct dcesrv_handle *h;
2926 struct lsa_policy_state *state;
2928 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2932 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2934 r->in.sid, r->in.rights);
2939 lsa_RemoveAccountRights
2941 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2942 TALLOC_CTX *mem_ctx,
2943 struct lsa_RemoveAccountRights *r)
2945 struct dcesrv_handle *h;
2946 struct lsa_policy_state *state;
2948 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2952 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2953 LDB_FLAG_MOD_DELETE,
2954 r->in.sid, r->in.rights);
2959 lsa_StorePrivateData
2961 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2962 struct lsa_StorePrivateData *r)
2964 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2969 lsa_RetrievePrivateData
2971 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2972 struct lsa_RetrievePrivateData *r)
2974 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2981 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2982 struct lsa_GetUserName *r)
2984 NTSTATUS status = NT_STATUS_OK;
2985 const char *account_name;
2986 const char *authority_name;
2987 struct lsa_String *_account_name;
2988 struct lsa_String *_authority_name = NULL;
2990 /* this is what w2k3 does */
2991 r->out.account_name = r->in.account_name;
2992 r->out.authority_name = r->in.authority_name;
2994 if (r->in.account_name
2995 && *r->in.account_name
2996 /* && *(*r->in.account_name)->string */
2998 return NT_STATUS_INVALID_PARAMETER;
3001 if (r->in.authority_name
3002 && *r->in.authority_name
3003 /* && *(*r->in.authority_name)->string */
3005 return NT_STATUS_INVALID_PARAMETER;
3008 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
3009 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
3011 _account_name = talloc(mem_ctx, struct lsa_String);
3012 NT_STATUS_HAVE_NO_MEMORY(_account_name);
3013 _account_name->string = account_name;
3015 if (r->in.authority_name) {
3016 _authority_name = talloc(mem_ctx, struct lsa_String);
3017 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
3018 _authority_name->string = authority_name;
3021 *r->out.account_name = _account_name;
3022 if (r->out.authority_name) {
3023 *r->out.authority_name = _authority_name;
3032 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
3033 TALLOC_CTX *mem_ctx,
3034 struct lsa_SetInfoPolicy2 *r)
3036 /* need to support these */
3037 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3041 lsa_QueryDomainInformationPolicy
3043 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3044 TALLOC_CTX *mem_ctx,
3045 struct lsa_QueryDomainInformationPolicy *r)
3047 union lsa_DomainInformationPolicy *info;
3049 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
3051 return NT_STATUS_NO_MEMORY;
3054 switch (r->in.level) {
3055 case LSA_DOMAIN_INFO_POLICY_EFS:
3057 *r->out.info = NULL;
3058 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3059 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
3061 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
3062 struct smb_krb5_context *smb_krb5_context;
3063 int ret = smb_krb5_init_context(mem_ctx,
3064 dce_call->event_ctx,
3065 dce_call->conn->dce_ctx->lp_ctx,
3069 *r->out.info = NULL;
3070 return NT_STATUS_INTERNAL_ERROR;
3072 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
3073 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3074 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3075 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
3076 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
3077 talloc_free(smb_krb5_context);
3078 *r->out.info = info;
3079 return NT_STATUS_OK;
3083 *r->out.info = NULL;
3084 return NT_STATUS_INVALID_INFO_CLASS;
3089 lsa_SetDomInfoPolicy
3091 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3092 TALLOC_CTX *mem_ctx,
3093 struct lsa_SetDomainInformationPolicy *r)
3095 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3101 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3102 TALLOC_CTX *mem_ctx,
3103 struct lsa_TestCall *r)
3105 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3111 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3112 struct lsa_CREDRWRITE *r)
3114 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3121 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3122 struct lsa_CREDRREAD *r)
3124 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3131 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3132 struct lsa_CREDRENUMERATE *r)
3134 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3139 lsa_CREDRWRITEDOMAINCREDENTIALS
3141 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3142 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3144 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3149 lsa_CREDRREADDOMAINCREDENTIALS
3151 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3152 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3154 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3161 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3162 struct lsa_CREDRDELETE *r)
3164 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3169 lsa_CREDRGETTARGETINFO
3171 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3172 struct lsa_CREDRGETTARGETINFO *r)
3174 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3179 lsa_CREDRPROFILELOADED
3181 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3182 struct lsa_CREDRPROFILELOADED *r)
3184 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3189 lsa_CREDRGETSESSIONTYPES
3191 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3192 struct lsa_CREDRGETSESSIONTYPES *r)
3194 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3199 lsa_LSARREGISTERAUDITEVENT
3201 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3202 struct lsa_LSARREGISTERAUDITEVENT *r)
3204 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3209 lsa_LSARGENAUDITEVENT
3211 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3212 struct lsa_LSARGENAUDITEVENT *r)
3214 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3219 lsa_LSARUNREGISTERAUDITEVENT
3221 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3222 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3224 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3229 lsa_lsaRQueryForestTrustInformation
3231 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3232 struct lsa_lsaRQueryForestTrustInformation *r)
3234 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3239 lsa_LSARSETFORESTTRUSTINFORMATION
3241 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3242 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3244 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3251 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3252 struct lsa_CREDRRENAME *r)
3254 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3260 lsa_LSAROPENPOLICYSCE
3262 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3263 struct lsa_LSAROPENPOLICYSCE *r)
3265 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3270 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3272 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3273 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3275 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3280 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3282 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3283 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3285 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3290 lsa_LSARADTREPORTSECURITYEVENT
3292 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3293 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3295 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3299 /* include the generated boilerplate */
3300 #include "librpc/gen_ndr/ndr_lsa_s.c"
3304 /*****************************************
3305 NOTE! The remaining calls below were
3306 removed in w2k3, so the DCESRV_FAULT()
3307 replies are the correct implementation. Do
3308 not try and fill these in with anything else
3309 ******************************************/
3312 dssetup_DsRoleDnsNameToFlatName
3314 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3315 struct dssetup_DsRoleDnsNameToFlatName *r)
3317 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3322 dssetup_DsRoleDcAsDc
3324 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3325 struct dssetup_DsRoleDcAsDc *r)
3327 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3332 dssetup_DsRoleDcAsReplica
3334 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3335 struct dssetup_DsRoleDcAsReplica *r)
3337 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3342 dssetup_DsRoleDemoteDc
3344 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3345 struct dssetup_DsRoleDemoteDc *r)
3347 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3352 dssetup_DsRoleGetDcOperationProgress
3354 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3355 struct dssetup_DsRoleGetDcOperationProgress *r)
3357 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3362 dssetup_DsRoleGetDcOperationResults
3364 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3365 struct dssetup_DsRoleGetDcOperationResults *r)
3367 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3372 dssetup_DsRoleCancel
3374 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3375 struct dssetup_DsRoleCancel *r)
3377 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3382 dssetup_DsRoleServerSaveStateForUpgrade
3384 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3385 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3387 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3392 dssetup_DsRoleUpgradeDownlevelServer
3394 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3395 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3397 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3402 dssetup_DsRoleAbortDownlevelServerUpgrade
3404 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3405 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3407 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3411 /* include the generated boilerplate */
3412 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3414 NTSTATUS dcerpc_server_lsa_init(void)
3418 ret = dcerpc_server_dssetup_init();
3419 if (!NT_STATUS_IS_OK(ret)) {
3422 ret = dcerpc_server_lsarpc_init();
3423 if (!NT_STATUS_IS_OK(ret)) {