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 msg = ldb_msg_new(mem_ctx);
1944 return NT_STATUS_NO_MEMORY;
1947 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
1948 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg);
1950 sidstr = dom_sid_string(msg, sid);
1951 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg);
1953 dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
1954 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg);
1956 msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
1957 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg);
1959 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1962 r2.in.handle = &state->handle->wire_handle;
1964 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1966 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1967 if (!NT_STATUS_IS_OK(status)) {
1968 ZERO_STRUCTP(r2.out.rights);
1972 for (i=0;i<rights->count;i++) {
1973 if (sec_privilege_id(rights->names[i].string) == -1) {
1975 return NT_STATUS_NO_SUCH_PRIVILEGE;
1978 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1980 for (j=0;j<r2.out.rights->count;j++) {
1981 if (strcasecmp_m(r2.out.rights->names[j].string,
1982 rights->names[i].string) == 0) {
1986 if (j != r2.out.rights->count) continue;
1989 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1990 if (ret != LDB_SUCCESS) {
1992 return NT_STATUS_NO_MEMORY;
1996 el = ldb_msg_find_element(msg, "privilege");
1999 return NT_STATUS_OK;
2002 el->flags = ldb_flag;
2004 ret = ldb_modify(state->pdb, msg);
2005 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
2006 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
2008 return NT_STATUS_NO_MEMORY;
2010 samdb_msg_add_string(state->pdb, msg, msg, "comment", "added via LSA");
2011 ret = ldb_add(state->pdb, msg);
2014 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2016 return NT_STATUS_OK;
2018 DEBUG(3, ("Could not %s attributes from %s: %s",
2019 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2020 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
2022 return NT_STATUS_UNEXPECTED_IO_ERROR;
2026 return NT_STATUS_OK;
2030 lsa_AddPrivilegesToAccount
2032 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2033 struct lsa_AddPrivilegesToAccount *r)
2035 struct lsa_RightSet rights;
2036 struct dcesrv_handle *h;
2037 struct lsa_account_state *astate;
2040 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2044 rights.count = r->in.privs->count;
2045 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2046 if (rights.names == NULL) {
2047 return NT_STATUS_NO_MEMORY;
2049 for (i=0;i<rights.count;i++) {
2050 int id = r->in.privs->set[i].luid.low;
2051 if (r->in.privs->set[i].luid.high) {
2052 return NT_STATUS_NO_SUCH_PRIVILEGE;
2054 rights.names[i].string = sec_privilege_name(id);
2055 if (rights.names[i].string == NULL) {
2056 return NT_STATUS_NO_SUCH_PRIVILEGE;
2060 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2061 LDB_FLAG_MOD_ADD, astate->account_sid,
2067 lsa_RemovePrivilegesFromAccount
2069 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2070 struct lsa_RemovePrivilegesFromAccount *r)
2072 struct lsa_RightSet *rights;
2073 struct dcesrv_handle *h;
2074 struct lsa_account_state *astate;
2077 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2081 rights = talloc(mem_ctx, struct lsa_RightSet);
2083 if (r->in.remove_all == 1 &&
2084 r->in.privs == NULL) {
2085 struct lsa_EnumAccountRights r2;
2088 r2.in.handle = &astate->policy->handle->wire_handle;
2089 r2.in.sid = astate->account_sid;
2090 r2.out.rights = rights;
2092 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2093 if (!NT_STATUS_IS_OK(status)) {
2097 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2098 LDB_FLAG_MOD_DELETE, astate->account_sid,
2102 if (r->in.remove_all != 0) {
2103 return NT_STATUS_INVALID_PARAMETER;
2106 rights->count = r->in.privs->count;
2107 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2108 if (rights->names == NULL) {
2109 return NT_STATUS_NO_MEMORY;
2111 for (i=0;i<rights->count;i++) {
2112 int id = r->in.privs->set[i].luid.low;
2113 if (r->in.privs->set[i].luid.high) {
2114 return NT_STATUS_NO_SUCH_PRIVILEGE;
2116 rights->names[i].string = sec_privilege_name(id);
2117 if (rights->names[i].string == NULL) {
2118 return NT_STATUS_NO_SUCH_PRIVILEGE;
2122 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2123 LDB_FLAG_MOD_DELETE, astate->account_sid,
2129 lsa_GetQuotasForAccount
2131 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2132 struct lsa_GetQuotasForAccount *r)
2134 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2139 lsa_SetQuotasForAccount
2141 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2142 struct lsa_SetQuotasForAccount *r)
2144 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2149 lsa_GetSystemAccessAccount
2151 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2152 struct lsa_GetSystemAccessAccount *r)
2156 struct lsa_EnumPrivsAccount enumPrivs;
2157 struct lsa_PrivilegeSet *privs;
2159 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2161 return NT_STATUS_NO_MEMORY;
2167 enumPrivs.in.handle = r->in.handle;
2168 enumPrivs.out.privs = &privs;
2170 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2171 if (!NT_STATUS_IS_OK(status)) {
2175 *(r->out.access_mask) = 0x00000000;
2177 for (i = 0; i < privs->count; i++) {
2178 int priv = privs->set[i].luid.low;
2181 case SEC_PRIV_INTERACTIVE_LOGON:
2182 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2184 case SEC_PRIV_NETWORK_LOGON:
2185 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2187 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2188 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2193 return NT_STATUS_OK;
2198 lsa_SetSystemAccessAccount
2200 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2201 struct lsa_SetSystemAccessAccount *r)
2203 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2210 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2211 struct lsa_CreateSecret *r)
2213 struct dcesrv_handle *policy_handle;
2214 struct lsa_policy_state *policy_state;
2215 struct lsa_secret_state *secret_state;
2216 struct dcesrv_handle *handle;
2217 struct ldb_message **msgs, *msg;
2218 const char *attrs[] = {
2226 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2227 ZERO_STRUCTP(r->out.sec_handle);
2229 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2231 case SECURITY_SYSTEM:
2232 case SECURITY_ADMINISTRATOR:
2235 /* Users and annonymous are not allowed create secrets */
2236 return NT_STATUS_ACCESS_DENIED;
2239 policy_state = policy_handle->data;
2241 if (!r->in.name.string) {
2242 return NT_STATUS_INVALID_PARAMETER;
2245 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2246 if (!secret_state) {
2247 return NT_STATUS_NO_MEMORY;
2249 secret_state->policy = policy_state;
2251 msg = ldb_msg_new(mem_ctx);
2253 return NT_STATUS_NO_MEMORY;
2256 if (strncmp("G$", r->in.name.string, 2) == 0) {
2258 name = &r->in.name.string[2];
2259 /* 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) */
2260 secret_state->sam_ldb = talloc_reference(secret_state,
2261 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)));
2262 secret_state->global = true;
2264 if (strlen(name) < 1) {
2265 return NT_STATUS_INVALID_PARAMETER;
2268 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2269 /* search for the secret record */
2270 ret = gendb_search(secret_state->sam_ldb,
2271 mem_ctx, policy_state->system_dn, &msgs, attrs,
2272 "(&(cn=%s)(objectclass=secret))",
2275 return NT_STATUS_OBJECT_NAME_COLLISION;
2279 DEBUG(0,("Failure searching for CN=%s: %s\n",
2280 name2, ldb_errstring(secret_state->sam_ldb)));
2281 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2284 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2285 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2286 return NT_STATUS_NO_MEMORY;
2289 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2292 secret_state->global = false;
2294 name = r->in.name.string;
2295 if (strlen(name) < 1) {
2296 return NT_STATUS_INVALID_PARAMETER;
2299 secret_state->sam_ldb = talloc_reference(secret_state,
2300 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2301 /* search for the secret record */
2302 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2303 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2305 "(&(cn=%s)(objectclass=secret))",
2306 ldb_binary_encode_string(mem_ctx, name));
2308 return NT_STATUS_OBJECT_NAME_COLLISION;
2312 DEBUG(0,("Failure searching for CN=%s: %s\n",
2313 name, ldb_errstring(secret_state->sam_ldb)));
2314 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2317 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2318 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2321 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2323 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2325 /* create the secret */
2326 ret = ldb_add(secret_state->sam_ldb, msg);
2328 DEBUG(0,("Failed to create secret record %s: %s\n",
2329 ldb_dn_get_linearized(msg->dn),
2330 ldb_errstring(secret_state->sam_ldb)));
2331 return NT_STATUS_ACCESS_DENIED;
2334 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2336 return NT_STATUS_NO_MEMORY;
2339 handle->data = talloc_steal(handle, secret_state);
2341 secret_state->access_mask = r->in.access_mask;
2342 secret_state->policy = talloc_reference(secret_state, policy_state);
2344 *r->out.sec_handle = handle->wire_handle;
2346 return NT_STATUS_OK;
2353 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2354 struct lsa_OpenSecret *r)
2356 struct dcesrv_handle *policy_handle;
2358 struct lsa_policy_state *policy_state;
2359 struct lsa_secret_state *secret_state;
2360 struct dcesrv_handle *handle;
2361 struct ldb_message **msgs;
2362 const char *attrs[] = {
2370 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2371 ZERO_STRUCTP(r->out.sec_handle);
2372 policy_state = policy_handle->data;
2374 if (!r->in.name.string) {
2375 return NT_STATUS_INVALID_PARAMETER;
2378 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2380 case SECURITY_SYSTEM:
2381 case SECURITY_ADMINISTRATOR:
2384 /* Users and annonymous are not allowed to access secrets */
2385 return NT_STATUS_ACCESS_DENIED;
2388 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2389 if (!secret_state) {
2390 return NT_STATUS_NO_MEMORY;
2392 secret_state->policy = policy_state;
2394 if (strncmp("G$", r->in.name.string, 2) == 0) {
2395 name = &r->in.name.string[2];
2396 /* 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) */
2397 secret_state->sam_ldb = talloc_reference(secret_state,
2398 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)));
2399 secret_state->global = true;
2401 if (strlen(name) < 1) {
2402 return NT_STATUS_INVALID_PARAMETER;
2405 /* search for the secret record */
2406 ret = gendb_search(secret_state->sam_ldb,
2407 mem_ctx, policy_state->system_dn, &msgs, attrs,
2408 "(&(cn=%s Secret)(objectclass=secret))",
2409 ldb_binary_encode_string(mem_ctx, name));
2411 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2415 DEBUG(0,("Found %d records matching DN %s\n", ret,
2416 ldb_dn_get_linearized(policy_state->system_dn)));
2417 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2421 secret_state->global = false;
2422 secret_state->sam_ldb = talloc_reference(secret_state,
2423 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2425 name = r->in.name.string;
2426 if (strlen(name) < 1) {
2427 return NT_STATUS_INVALID_PARAMETER;
2430 /* search for the secret record */
2431 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2432 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2434 "(&(cn=%s)(objectclass=secret))",
2435 ldb_binary_encode_string(mem_ctx, name));
2437 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2441 DEBUG(0,("Found %d records matching CN=%s\n",
2442 ret, ldb_binary_encode_string(mem_ctx, name)));
2443 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2447 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2449 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2451 return NT_STATUS_NO_MEMORY;
2454 handle->data = talloc_steal(handle, secret_state);
2456 secret_state->access_mask = r->in.access_mask;
2457 secret_state->policy = talloc_reference(secret_state, policy_state);
2459 *r->out.sec_handle = handle->wire_handle;
2461 return NT_STATUS_OK;
2468 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2469 struct lsa_SetSecret *r)
2472 struct dcesrv_handle *h;
2473 struct lsa_secret_state *secret_state;
2474 struct ldb_message *msg;
2475 DATA_BLOB session_key;
2476 DATA_BLOB crypt_secret, secret;
2479 NTSTATUS status = NT_STATUS_OK;
2481 struct timeval now = timeval_current();
2482 NTTIME nt_now = timeval_to_nttime(&now);
2484 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2486 secret_state = h->data;
2488 msg = ldb_msg_new(mem_ctx);
2490 return NT_STATUS_NO_MEMORY;
2493 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2495 return NT_STATUS_NO_MEMORY;
2497 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2498 if (!NT_STATUS_IS_OK(status)) {
2502 if (r->in.old_val) {
2504 crypt_secret.data = r->in.old_val->data;
2505 crypt_secret.length = r->in.old_val->size;
2507 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2508 if (!NT_STATUS_IS_OK(status)) {
2512 val.data = secret.data;
2513 val.length = secret.length;
2516 if (samdb_msg_add_value(secret_state->sam_ldb,
2517 mem_ctx, msg, "priorValue", &val) != 0) {
2518 return NT_STATUS_NO_MEMORY;
2521 /* set old value mtime */
2522 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2523 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2524 return NT_STATUS_NO_MEMORY;
2528 /* If the old value is not set, then migrate the
2529 * current value to the old value */
2530 const struct ldb_val *old_val;
2531 NTTIME last_set_time;
2532 struct ldb_message **res;
2533 const char *attrs[] = {
2539 /* search for the secret record */
2540 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2541 secret_state->secret_dn, &res, attrs);
2543 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2547 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2548 ldb_dn_get_linearized(secret_state->secret_dn)));
2549 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2552 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2553 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2557 if (samdb_msg_add_value(secret_state->sam_ldb,
2558 mem_ctx, msg, "priorValue",
2560 return NT_STATUS_NO_MEMORY;
2563 if (samdb_msg_add_delete(secret_state->sam_ldb,
2564 mem_ctx, msg, "priorValue")) {
2565 return NT_STATUS_NO_MEMORY;
2570 /* set old value mtime */
2571 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2572 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2573 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2574 return NT_STATUS_NO_MEMORY;
2577 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2578 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2579 return NT_STATUS_NO_MEMORY;
2584 if (r->in.new_val) {
2586 crypt_secret.data = r->in.new_val->data;
2587 crypt_secret.length = r->in.new_val->size;
2589 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2590 if (!NT_STATUS_IS_OK(status)) {
2594 val.data = secret.data;
2595 val.length = secret.length;
2598 if (samdb_msg_add_value(secret_state->sam_ldb,
2599 mem_ctx, msg, "currentValue", &val) != 0) {
2600 return NT_STATUS_NO_MEMORY;
2603 /* set new value mtime */
2604 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2605 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2606 return NT_STATUS_NO_MEMORY;
2610 /* NULL out the NEW value */
2611 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2612 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2613 return NT_STATUS_NO_MEMORY;
2615 if (samdb_msg_add_delete(secret_state->sam_ldb,
2616 mem_ctx, msg, "currentValue")) {
2617 return NT_STATUS_NO_MEMORY;
2621 /* modify the samdb record */
2622 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2624 /* we really need samdb.c to return NTSTATUS */
2625 return NT_STATUS_UNSUCCESSFUL;
2628 return NT_STATUS_OK;
2635 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2636 struct lsa_QuerySecret *r)
2638 struct dcesrv_handle *h;
2639 struct lsa_secret_state *secret_state;
2640 struct ldb_message *msg;
2641 DATA_BLOB session_key;
2642 DATA_BLOB crypt_secret, secret;
2644 struct ldb_message **res;
2645 const char *attrs[] = {
2655 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2657 /* Ensure user is permitted to read this... */
2658 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2660 case SECURITY_SYSTEM:
2661 case SECURITY_ADMINISTRATOR:
2664 /* Users and annonymous are not allowed to read secrets */
2665 return NT_STATUS_ACCESS_DENIED;
2668 secret_state = h->data;
2670 /* pull all the user attributes */
2671 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2672 secret_state->secret_dn, &res, attrs);
2674 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2678 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2679 if (!NT_STATUS_IS_OK(nt_status)) {
2683 if (r->in.old_val) {
2684 const struct ldb_val *prior_val;
2685 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2686 if (!r->out.old_val) {
2687 return NT_STATUS_NO_MEMORY;
2689 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2691 if (prior_val && prior_val->length) {
2692 secret.data = prior_val->data;
2693 secret.length = prior_val->length;
2696 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2697 if (!crypt_secret.length) {
2698 return NT_STATUS_NO_MEMORY;
2700 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2701 if (!r->out.old_val->buf) {
2702 return NT_STATUS_NO_MEMORY;
2704 r->out.old_val->buf->size = crypt_secret.length;
2705 r->out.old_val->buf->length = crypt_secret.length;
2706 r->out.old_val->buf->data = crypt_secret.data;
2710 if (r->in.old_mtime) {
2711 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2712 if (!r->out.old_mtime) {
2713 return NT_STATUS_NO_MEMORY;
2715 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2718 if (r->in.new_val) {
2719 const struct ldb_val *new_val;
2720 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2721 if (!r->out.new_val) {
2722 return NT_STATUS_NO_MEMORY;
2725 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2727 if (new_val && new_val->length) {
2728 secret.data = new_val->data;
2729 secret.length = new_val->length;
2732 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2733 if (!crypt_secret.length) {
2734 return NT_STATUS_NO_MEMORY;
2736 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2737 if (!r->out.new_val->buf) {
2738 return NT_STATUS_NO_MEMORY;
2740 r->out.new_val->buf->length = crypt_secret.length;
2741 r->out.new_val->buf->size = crypt_secret.length;
2742 r->out.new_val->buf->data = crypt_secret.data;
2746 if (r->in.new_mtime) {
2747 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2748 if (!r->out.new_mtime) {
2749 return NT_STATUS_NO_MEMORY;
2751 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2754 return NT_STATUS_OK;
2761 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2762 TALLOC_CTX *mem_ctx,
2763 struct lsa_LookupPrivValue *r)
2765 struct dcesrv_handle *h;
2766 struct lsa_policy_state *state;
2769 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2773 id = sec_privilege_id(r->in.name->string);
2775 return NT_STATUS_NO_SUCH_PRIVILEGE;
2778 r->out.luid->low = id;
2779 r->out.luid->high = 0;
2781 return NT_STATUS_OK;
2788 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2789 TALLOC_CTX *mem_ctx,
2790 struct lsa_LookupPrivName *r)
2792 struct dcesrv_handle *h;
2793 struct lsa_policy_state *state;
2794 struct lsa_StringLarge *name;
2795 const char *privname;
2797 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2801 if (r->in.luid->high != 0) {
2802 return NT_STATUS_NO_SUCH_PRIVILEGE;
2805 privname = sec_privilege_name(r->in.luid->low);
2806 if (privname == NULL) {
2807 return NT_STATUS_NO_SUCH_PRIVILEGE;
2810 name = talloc(mem_ctx, struct lsa_StringLarge);
2812 return NT_STATUS_NO_MEMORY;
2815 name->string = privname;
2817 *r->out.name = name;
2819 return NT_STATUS_OK;
2824 lsa_LookupPrivDisplayName
2826 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2827 TALLOC_CTX *mem_ctx,
2828 struct lsa_LookupPrivDisplayName *r)
2830 struct dcesrv_handle *h;
2831 struct lsa_policy_state *state;
2832 struct lsa_StringLarge *disp_name = NULL;
2835 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2839 id = sec_privilege_id(r->in.name->string);
2841 return NT_STATUS_NO_SUCH_PRIVILEGE;
2844 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2845 if (disp_name == NULL) {
2846 return NT_STATUS_NO_MEMORY;
2849 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
2850 if (disp_name->string == NULL) {
2851 return NT_STATUS_INTERNAL_ERROR;
2854 *r->out.disp_name = disp_name;
2855 *r->out.returned_language_id = 0;
2857 return NT_STATUS_OK;
2862 lsa_EnumAccountsWithUserRight
2864 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2865 TALLOC_CTX *mem_ctx,
2866 struct lsa_EnumAccountsWithUserRight *r)
2868 struct dcesrv_handle *h;
2869 struct lsa_policy_state *state;
2871 struct ldb_message **res;
2872 const char * const attrs[] = { "objectSid", NULL};
2873 const char *privname;
2875 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2879 if (r->in.name == NULL) {
2880 return NT_STATUS_NO_SUCH_PRIVILEGE;
2883 privname = r->in.name->string;
2884 if (sec_privilege_id(privname) == -1) {
2885 return NT_STATUS_NO_SUCH_PRIVILEGE;
2888 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2889 "privilege=%s", privname);
2891 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2894 return NT_STATUS_NO_MORE_ENTRIES;
2897 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2898 if (r->out.sids->sids == NULL) {
2899 return NT_STATUS_NO_MEMORY;
2901 for (i=0;i<ret;i++) {
2902 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2903 res[i], "objectSid");
2904 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2906 r->out.sids->num_sids = ret;
2908 return NT_STATUS_OK;
2913 lsa_AddAccountRights
2915 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2916 TALLOC_CTX *mem_ctx,
2917 struct lsa_AddAccountRights *r)
2919 struct dcesrv_handle *h;
2920 struct lsa_policy_state *state;
2922 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2926 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2928 r->in.sid, r->in.rights);
2933 lsa_RemoveAccountRights
2935 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2936 TALLOC_CTX *mem_ctx,
2937 struct lsa_RemoveAccountRights *r)
2939 struct dcesrv_handle *h;
2940 struct lsa_policy_state *state;
2942 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2946 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2947 LDB_FLAG_MOD_DELETE,
2948 r->in.sid, r->in.rights);
2953 lsa_StorePrivateData
2955 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2956 struct lsa_StorePrivateData *r)
2958 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2963 lsa_RetrievePrivateData
2965 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2966 struct lsa_RetrievePrivateData *r)
2968 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2975 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2976 struct lsa_GetUserName *r)
2978 NTSTATUS status = NT_STATUS_OK;
2979 const char *account_name;
2980 const char *authority_name;
2981 struct lsa_String *_account_name;
2982 struct lsa_String *_authority_name = NULL;
2984 /* this is what w2k3 does */
2985 r->out.account_name = r->in.account_name;
2986 r->out.authority_name = r->in.authority_name;
2988 if (r->in.account_name
2989 && *r->in.account_name
2990 /* && *(*r->in.account_name)->string */
2992 return NT_STATUS_INVALID_PARAMETER;
2995 if (r->in.authority_name
2996 && *r->in.authority_name
2997 /* && *(*r->in.authority_name)->string */
2999 return NT_STATUS_INVALID_PARAMETER;
3002 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
3003 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
3005 _account_name = talloc(mem_ctx, struct lsa_String);
3006 NT_STATUS_HAVE_NO_MEMORY(_account_name);
3007 _account_name->string = account_name;
3009 if (r->in.authority_name) {
3010 _authority_name = talloc(mem_ctx, struct lsa_String);
3011 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
3012 _authority_name->string = authority_name;
3015 *r->out.account_name = _account_name;
3016 if (r->out.authority_name) {
3017 *r->out.authority_name = _authority_name;
3026 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
3027 TALLOC_CTX *mem_ctx,
3028 struct lsa_SetInfoPolicy2 *r)
3030 /* need to support these */
3031 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3035 lsa_QueryDomainInformationPolicy
3037 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3038 TALLOC_CTX *mem_ctx,
3039 struct lsa_QueryDomainInformationPolicy *r)
3041 union lsa_DomainInformationPolicy *info;
3043 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
3045 return NT_STATUS_NO_MEMORY;
3048 switch (r->in.level) {
3049 case LSA_DOMAIN_INFO_POLICY_EFS:
3051 *r->out.info = NULL;
3052 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3053 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
3055 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
3056 struct smb_krb5_context *smb_krb5_context;
3057 int ret = smb_krb5_init_context(mem_ctx,
3058 dce_call->event_ctx,
3059 dce_call->conn->dce_ctx->lp_ctx,
3063 *r->out.info = NULL;
3064 return NT_STATUS_INTERNAL_ERROR;
3066 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
3067 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3068 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3069 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
3070 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
3071 talloc_free(smb_krb5_context);
3072 *r->out.info = info;
3073 return NT_STATUS_OK;
3077 *r->out.info = NULL;
3078 return NT_STATUS_INVALID_INFO_CLASS;
3083 lsa_SetDomInfoPolicy
3085 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3086 TALLOC_CTX *mem_ctx,
3087 struct lsa_SetDomainInformationPolicy *r)
3089 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3095 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3096 TALLOC_CTX *mem_ctx,
3097 struct lsa_TestCall *r)
3099 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3105 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3106 struct lsa_CREDRWRITE *r)
3108 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3115 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3116 struct lsa_CREDRREAD *r)
3118 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3125 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3126 struct lsa_CREDRENUMERATE *r)
3128 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3133 lsa_CREDRWRITEDOMAINCREDENTIALS
3135 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3136 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3138 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3143 lsa_CREDRREADDOMAINCREDENTIALS
3145 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3146 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3148 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3155 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3156 struct lsa_CREDRDELETE *r)
3158 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3163 lsa_CREDRGETTARGETINFO
3165 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3166 struct lsa_CREDRGETTARGETINFO *r)
3168 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3173 lsa_CREDRPROFILELOADED
3175 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3176 struct lsa_CREDRPROFILELOADED *r)
3178 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3183 lsa_CREDRGETSESSIONTYPES
3185 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3186 struct lsa_CREDRGETSESSIONTYPES *r)
3188 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3193 lsa_LSARREGISTERAUDITEVENT
3195 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3196 struct lsa_LSARREGISTERAUDITEVENT *r)
3198 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3203 lsa_LSARGENAUDITEVENT
3205 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3206 struct lsa_LSARGENAUDITEVENT *r)
3208 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3213 lsa_LSARUNREGISTERAUDITEVENT
3215 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3216 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3218 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3223 lsa_lsaRQueryForestTrustInformation
3225 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3226 struct lsa_lsaRQueryForestTrustInformation *r)
3228 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3233 lsa_LSARSETFORESTTRUSTINFORMATION
3235 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3236 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3238 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3245 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3246 struct lsa_CREDRRENAME *r)
3248 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3254 lsa_LSAROPENPOLICYSCE
3256 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3257 struct lsa_LSAROPENPOLICYSCE *r)
3259 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3264 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3266 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3267 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3269 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3274 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3276 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3277 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3279 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3284 lsa_LSARADTREPORTSECURITYEVENT
3286 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3287 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3289 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3293 /* include the generated boilerplate */
3294 #include "librpc/gen_ndr/ndr_lsa_s.c"
3298 /*****************************************
3299 NOTE! The remaining calls below were
3300 removed in w2k3, so the DCESRV_FAULT()
3301 replies are the correct implementation. Do
3302 not try and fill these in with anything else
3303 ******************************************/
3306 dssetup_DsRoleDnsNameToFlatName
3308 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3309 struct dssetup_DsRoleDnsNameToFlatName *r)
3311 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3316 dssetup_DsRoleDcAsDc
3318 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3319 struct dssetup_DsRoleDcAsDc *r)
3321 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3326 dssetup_DsRoleDcAsReplica
3328 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3329 struct dssetup_DsRoleDcAsReplica *r)
3331 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3336 dssetup_DsRoleDemoteDc
3338 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3339 struct dssetup_DsRoleDemoteDc *r)
3341 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3346 dssetup_DsRoleGetDcOperationProgress
3348 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3349 struct dssetup_DsRoleGetDcOperationProgress *r)
3351 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3356 dssetup_DsRoleGetDcOperationResults
3358 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3359 struct dssetup_DsRoleGetDcOperationResults *r)
3361 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3366 dssetup_DsRoleCancel
3368 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3369 struct dssetup_DsRoleCancel *r)
3371 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3376 dssetup_DsRoleServerSaveStateForUpgrade
3378 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3379 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3381 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3386 dssetup_DsRoleUpgradeDownlevelServer
3388 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3389 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3391 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3396 dssetup_DsRoleAbortDownlevelServerUpgrade
3398 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3399 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3401 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3405 /* include the generated boilerplate */
3406 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3408 NTSTATUS dcerpc_server_lsa_init(void)
3412 ret = dcerpc_server_dssetup_init();
3413 if (!NT_STATUS_IS_OK(ret)) {
3416 ret = dcerpc_server_lsarpc_init();
3417 if (!NT_STATUS_IS_OK(ret)) {