1 /* need access mask/acl implementation */
4 Unix SMB/CIFS implementation.
6 endpoint server for the lsarpc pipe
8 Copyright (C) Andrew Tridgell 2004
9 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "rpc_server/lsa/lsa.h"
26 #include "system/kerberos.h"
27 #include "auth/kerberos/kerberos.h"
28 #include "librpc/gen_ndr/ndr_drsblobs.h"
29 #include "librpc/gen_ndr/ndr_lsa.h"
30 #include "../lib/crypto/crypto.h"
31 #include "lib/util/tsort.h"
34 this type allows us to distinguish handle types
38 state associated with a lsa_OpenAccount() operation
40 struct lsa_account_state {
41 struct lsa_policy_state *policy;
43 struct dom_sid *account_sid;
48 state associated with a lsa_OpenSecret() operation
50 struct lsa_secret_state {
51 struct lsa_policy_state *policy;
53 struct ldb_dn *secret_dn;
54 struct ldb_context *sam_ldb;
59 state associated with a lsa_OpenTrustedDomain() operation
61 struct lsa_trusted_domain_state {
62 struct lsa_policy_state *policy;
64 struct ldb_dn *trusted_domain_dn;
65 struct ldb_dn *trusted_domain_user_dn;
69 this is based on the samba3 function make_lsa_object_sd()
70 It uses the same logic, but with samba4 helper functions
72 static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
73 struct security_descriptor **sd,
79 struct dom_sid *domain_sid, *domain_admins_sid;
80 const char *domain_admins_sid_str, *sidstr;
81 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
83 status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
84 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
86 domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
87 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid, tmp_ctx);
89 domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
90 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid_str, tmp_ctx);
92 sidstr = dom_sid_string(tmp_ctx, sid);
93 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, tmp_ctx);
95 *sd = security_descriptor_dacl_create(mem_ctx,
99 SEC_ACE_TYPE_ACCESS_ALLOWED,
100 SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,
102 SID_BUILTIN_ADMINISTRATORS,
103 SEC_ACE_TYPE_ACCESS_ALLOWED,
106 SID_BUILTIN_ACCOUNT_OPERATORS,
107 SEC_ACE_TYPE_ACCESS_ALLOWED,
110 domain_admins_sid_str,
111 SEC_ACE_TYPE_ACCESS_ALLOWED,
115 SEC_ACE_TYPE_ACCESS_ALLOWED,
119 talloc_free(tmp_ctx);
121 NT_STATUS_HAVE_NO_MEMORY(*sd);
127 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
129 struct lsa_EnumAccountRights *r);
131 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
133 struct lsa_policy_state *state,
136 const struct lsa_RightSet *rights);
141 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
144 struct dcesrv_handle *h;
146 *r->out.handle = *r->in.handle;
148 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
152 ZERO_STRUCTP(r->out.handle);
161 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
162 struct lsa_Delete *r)
164 return NT_STATUS_NOT_SUPPORTED;
171 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
172 struct lsa_DeleteObject *r)
174 struct dcesrv_handle *h;
177 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
179 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
180 struct lsa_secret_state *secret_state = h->data;
182 /* Ensure user is permitted to delete this... */
183 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
185 case SECURITY_SYSTEM:
186 case SECURITY_ADMINISTRATOR:
189 /* Users and annonymous are not allowed delete things */
190 return NT_STATUS_ACCESS_DENIED;
193 ret = ldb_delete(secret_state->sam_ldb,
194 secret_state->secret_dn);
196 if (ret != LDB_SUCCESS) {
197 return NT_STATUS_INVALID_HANDLE;
200 ZERO_STRUCTP(r->out.handle);
203 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
204 struct lsa_trusted_domain_state *trusted_domain_state =
205 talloc_get_type(h->data, struct lsa_trusted_domain_state);
206 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
207 if (ret != LDB_SUCCESS) {
208 return NT_STATUS_INTERNAL_DB_CORRUPTION;
211 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
212 trusted_domain_state->trusted_domain_dn);
213 if (ret != LDB_SUCCESS) {
214 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
215 return NT_STATUS_INVALID_HANDLE;
218 if (trusted_domain_state->trusted_domain_user_dn) {
219 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
220 trusted_domain_state->trusted_domain_user_dn);
221 if (ret != LDB_SUCCESS) {
222 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
223 return NT_STATUS_INVALID_HANDLE;
227 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
228 if (ret != LDB_SUCCESS) {
229 return NT_STATUS_INTERNAL_DB_CORRUPTION;
232 ZERO_STRUCTP(r->out.handle);
235 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
236 struct lsa_RightSet *rights;
237 struct lsa_account_state *astate;
238 struct lsa_EnumAccountRights r2;
241 rights = talloc(mem_ctx, struct lsa_RightSet);
243 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
247 r2.in.handle = &astate->policy->handle->wire_handle;
248 r2.in.sid = astate->account_sid;
249 r2.out.rights = rights;
251 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
252 but we have a LSA_HANDLE_ACCOUNT here, so this call
254 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
255 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
259 if (!NT_STATUS_IS_OK(status)) {
263 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
264 LDB_FLAG_MOD_DELETE, astate->account_sid,
266 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
270 if (!NT_STATUS_IS_OK(status)) {
274 ZERO_STRUCTP(r->out.handle);
277 return NT_STATUS_INVALID_HANDLE;
284 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
285 struct lsa_EnumPrivs *r)
287 struct dcesrv_handle *h;
288 struct lsa_policy_state *state;
290 const char *privname;
292 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
296 i = *r->in.resume_handle;
299 while ((privname = sec_privilege_name(i)) &&
300 r->out.privs->count < r->in.max_count) {
301 struct lsa_PrivEntry *e;
303 r->out.privs->privs = talloc_realloc(r->out.privs,
305 struct lsa_PrivEntry,
306 r->out.privs->count+1);
307 if (r->out.privs->privs == NULL) {
308 return NT_STATUS_NO_MEMORY;
310 e = &r->out.privs->privs[r->out.privs->count];
313 e->name.string = privname;
314 r->out.privs->count++;
318 *r->out.resume_handle = i;
327 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
328 struct lsa_QuerySecurity *r)
330 struct dcesrv_handle *h;
331 struct security_descriptor *sd;
335 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
337 sid = dce_call->conn->auth_state.session_info->security_token->user_sid;
339 if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
340 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid, 0);
341 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
342 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid,
343 LSA_ACCOUNT_ALL_ACCESS);
345 return NT_STATUS_INVALID_HANDLE;
347 NT_STATUS_NOT_OK_RETURN(status);
349 (*r->out.sdbuf) = talloc(mem_ctx, struct sec_desc_buf);
350 NT_STATUS_HAVE_NO_MEMORY(*r->out.sdbuf);
352 (*r->out.sdbuf)->sd = sd;
361 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
362 struct lsa_SetSecObj *r)
364 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
371 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
372 struct lsa_ChangePassword *r)
374 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
378 dssetup_DsRoleGetPrimaryDomainInformation
380 This is not an LSA call, but is the only call left on the DSSETUP
381 pipe (after the pipe was truncated), and needs lsa_get_policy_state
383 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
385 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
387 union dssetup_DsRoleInfo *info;
389 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
390 W_ERROR_HAVE_NO_MEMORY(info);
392 switch (r->in.level) {
393 case DS_ROLE_BASIC_INFORMATION:
395 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
397 const char *domain = NULL;
398 const char *dns_domain = NULL;
399 const char *forest = NULL;
400 struct GUID domain_guid;
401 struct lsa_policy_state *state;
403 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
404 if (!NT_STATUS_IS_OK(status)) {
405 return ntstatus_to_werror(status);
408 ZERO_STRUCT(domain_guid);
410 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
411 case ROLE_STANDALONE:
412 role = DS_ROLE_STANDALONE_SERVER;
414 case ROLE_DOMAIN_MEMBER:
415 role = DS_ROLE_MEMBER_SERVER;
417 case ROLE_DOMAIN_CONTROLLER:
418 if (samdb_is_pdc(state->sam_ldb)) {
419 role = DS_ROLE_PRIMARY_DC;
421 role = DS_ROLE_BACKUP_DC;
426 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
427 case ROLE_STANDALONE:
428 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
429 W_ERROR_HAVE_NO_MEMORY(domain);
431 case ROLE_DOMAIN_MEMBER:
432 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
433 W_ERROR_HAVE_NO_MEMORY(domain);
434 /* TODO: what is with dns_domain and forest and guid? */
436 case ROLE_DOMAIN_CONTROLLER:
437 flags = DS_ROLE_PRIMARY_DS_RUNNING;
439 if (state->mixed_domain == 1) {
440 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
443 domain = state->domain_name;
444 dns_domain = state->domain_dns;
445 forest = state->forest_dns;
447 domain_guid = state->domain_guid;
448 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
452 info->basic.role = role;
453 info->basic.flags = flags;
454 info->basic.domain = domain;
455 info->basic.dns_domain = dns_domain;
456 info->basic.forest = forest;
457 info->basic.domain_guid = domain_guid;
462 case DS_ROLE_UPGRADE_STATUS:
464 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
465 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
470 case DS_ROLE_OP_STATUS:
472 info->opstatus.status = DS_ROLE_OP_IDLE;
478 return WERR_INVALID_PARAM;
481 return WERR_INVALID_PARAM;
485 fill in the AccountDomain info
487 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
488 struct lsa_DomainInfo *info)
490 info->name.string = state->domain_name;
491 info->sid = state->domain_sid;
497 fill in the DNS domain info
499 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
500 struct lsa_DnsDomainInfo *info)
502 info->name.string = state->domain_name;
503 info->sid = state->domain_sid;
504 info->dns_domain.string = state->domain_dns;
505 info->dns_forest.string = state->forest_dns;
506 info->domain_guid = state->domain_guid;
514 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
515 struct lsa_QueryInfoPolicy2 *r)
517 struct lsa_policy_state *state;
518 struct dcesrv_handle *h;
519 union lsa_PolicyInformation *info;
523 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
527 info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
529 return NT_STATUS_NO_MEMORY;
533 switch (r->in.level) {
534 case LSA_POLICY_INFO_AUDIT_LOG:
535 /* we don't need to fill in any of this */
536 ZERO_STRUCT(info->audit_log);
538 case LSA_POLICY_INFO_AUDIT_EVENTS:
539 /* we don't need to fill in any of this */
540 ZERO_STRUCT(info->audit_events);
542 case LSA_POLICY_INFO_PD:
543 /* we don't need to fill in any of this */
544 ZERO_STRUCT(info->pd);
547 case LSA_POLICY_INFO_DOMAIN:
548 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
549 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
550 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
551 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
552 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
555 case LSA_POLICY_INFO_ROLE:
556 info->role.role = LSA_ROLE_PRIMARY;
559 case LSA_POLICY_INFO_DNS:
560 case LSA_POLICY_INFO_DNS_INT:
561 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
563 case LSA_POLICY_INFO_REPLICA:
564 ZERO_STRUCT(info->replica);
567 case LSA_POLICY_INFO_QUOTA:
568 ZERO_STRUCT(info->quota);
571 case LSA_POLICY_INFO_MOD:
572 case LSA_POLICY_INFO_AUDIT_FULL_SET:
573 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
574 /* windows gives INVALID_PARAMETER */
576 return NT_STATUS_INVALID_PARAMETER;
580 return NT_STATUS_INVALID_INFO_CLASS;
586 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
587 struct lsa_QueryInfoPolicy *r)
589 struct lsa_QueryInfoPolicy2 r2;
594 r2.in.handle = r->in.handle;
595 r2.in.level = r->in.level;
596 r2.out.info = r->out.info;
598 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
606 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
607 struct lsa_SetInfoPolicy *r)
609 /* need to support this */
610 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
617 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
618 struct lsa_ClearAuditLog *r)
620 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
627 This call does not seem to have any long-term effects, hence no database operations
629 we need to talk to the MS product group to find out what this account database means!
631 answer is that the lsa database is totally separate from the SAM and
632 ldap databases. We are going to need a separate ldb to store these
633 accounts. The SIDs on this account bear no relation to the SIDs in
636 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
637 struct lsa_CreateAccount *r)
639 struct lsa_account_state *astate;
641 struct lsa_policy_state *state;
642 struct dcesrv_handle *h, *ah;
644 ZERO_STRUCTP(r->out.acct_handle);
646 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
650 astate = talloc(dce_call->conn, struct lsa_account_state);
651 if (astate == NULL) {
652 return NT_STATUS_NO_MEMORY;
655 astate->account_sid = dom_sid_dup(astate, r->in.sid);
656 if (astate->account_sid == NULL) {
658 return NT_STATUS_NO_MEMORY;
661 astate->policy = talloc_reference(astate, state);
662 astate->access_mask = r->in.access_mask;
664 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
667 return NT_STATUS_NO_MEMORY;
670 ah->data = talloc_steal(ah, astate);
672 *r->out.acct_handle = ah->wire_handle;
681 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
682 struct lsa_EnumAccounts *r)
684 struct dcesrv_handle *h;
685 struct lsa_policy_state *state;
687 struct ldb_message **res;
688 const char * const attrs[] = { "objectSid", NULL};
691 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
695 /* NOTE: This call must only return accounts that have at least
698 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
699 "(&(objectSid=*)(privilege=*))");
701 return NT_STATUS_NO_SUCH_USER;
704 if (*r->in.resume_handle >= ret) {
705 return NT_STATUS_NO_MORE_ENTRIES;
708 count = ret - *r->in.resume_handle;
709 if (count > r->in.num_entries) {
710 count = r->in.num_entries;
714 return NT_STATUS_NO_MORE_ENTRIES;
717 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
718 if (r->out.sids->sids == NULL) {
719 return NT_STATUS_NO_MEMORY;
722 for (i=0;i<count;i++) {
723 r->out.sids->sids[i].sid =
724 samdb_result_dom_sid(r->out.sids->sids,
725 res[i + *r->in.resume_handle],
727 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
730 r->out.sids->num_sids = count;
731 *r->out.resume_handle = count + *r->in.resume_handle;
739 lsa_CreateTrustedDomainEx2
741 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
743 struct lsa_CreateTrustedDomainEx2 *r,
746 struct dcesrv_handle *policy_handle;
747 struct lsa_policy_state *policy_state;
748 struct lsa_trusted_domain_state *trusted_domain_state;
749 struct dcesrv_handle *handle;
750 struct ldb_message **msgs, *msg, *msg_user;
751 const char *attrs[] = {
754 const char *netbios_name;
755 const char *dns_name;
757 DATA_BLOB session_key = data_blob(NULL, 0);
758 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
759 struct trustDomainPasswords auth_struct;
762 enum ndr_err_code ndr_err;
764 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
765 ZERO_STRUCTP(r->out.trustdom_handle);
767 policy_state = policy_handle->data;
769 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
770 if (!NT_STATUS_IS_OK(nt_status)) {
774 netbios_name = r->in.info->netbios_name.string;
776 return NT_STATUS_INVALID_PARAMETER;
779 dns_name = r->in.info->domain_name.string;
781 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
782 if (!trusted_domain_state) {
783 return NT_STATUS_NO_MEMORY;
785 trusted_domain_state->policy = policy_state;
787 if (strcasecmp(netbios_name, "BUILTIN") == 0
788 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
789 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
790 return NT_STATUS_INVALID_PARAMETER;;
793 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
794 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
795 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
796 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
797 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
798 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
801 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
802 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
803 /* No secrets are created at this time, for this function */
804 auth_struct.outgoing.count = 0;
805 auth_struct.incoming.count = 0;
807 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data, r->in.auth_info->auth_blob.size);
808 arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key);
809 ndr_err = ndr_pull_struct_blob(&auth_blob, mem_ctx,
810 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
812 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
813 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
814 return NT_STATUS_INVALID_PARAMETER;
817 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
818 if (auth_struct.incoming.count > 1) {
819 return NT_STATUS_INVALID_PARAMETER;
824 if (auth_struct.incoming.count) {
826 struct trustAuthInOutBlob incoming;
828 incoming.count = auth_struct.incoming.count;
829 incoming.current = talloc(mem_ctx, struct AuthenticationInformationArray);
830 if (!incoming.current) {
831 return NT_STATUS_NO_MEMORY;
834 incoming.current->array = *auth_struct.incoming.current;
835 if (!incoming.current->array) {
836 return NT_STATUS_NO_MEMORY;
839 incoming.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
840 if (!incoming.previous) {
841 return NT_STATUS_NO_MEMORY;
843 incoming.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, incoming.count);
844 if (!incoming.previous->array) {
845 return NT_STATUS_NO_MEMORY;
848 for (i = 0; i < incoming.count; i++) {
849 incoming.previous->array[i].LastUpdateTime = 0;
850 incoming.previous->array[i].AuthType = 0;
852 ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx,
853 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
855 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
856 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
857 return NT_STATUS_INVALID_PARAMETER;
860 trustAuthIncoming = data_blob(NULL, 0);
863 if (auth_struct.outgoing.count) {
865 struct trustAuthInOutBlob outgoing;
867 outgoing.count = auth_struct.outgoing.count;
868 outgoing.current = talloc(mem_ctx, struct AuthenticationInformationArray);
869 if (!outgoing.current) {
870 return NT_STATUS_NO_MEMORY;
873 outgoing.current->array = *auth_struct.outgoing.current;
874 if (!outgoing.current->array) {
875 return NT_STATUS_NO_MEMORY;
878 outgoing.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
879 if (!outgoing.previous) {
880 return NT_STATUS_NO_MEMORY;
882 outgoing.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, outgoing.count);
883 if (!outgoing.previous->array) {
884 return NT_STATUS_NO_MEMORY;
887 for (i = 0; i < outgoing.count; i++) {
888 outgoing.previous->array[i].LastUpdateTime = 0;
889 outgoing.previous->array[i].AuthType = 0;
891 ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx,
892 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
894 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
895 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
896 return NT_STATUS_INVALID_PARAMETER;
899 trustAuthOutgoing = data_blob(NULL, 0);
902 ret = ldb_transaction_start(policy_state->sam_ldb);
903 if (ret != LDB_SUCCESS) {
904 return NT_STATUS_INTERNAL_DB_CORRUPTION;
908 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
909 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
910 /* search for the trusted_domain record */
911 ret = gendb_search(policy_state->sam_ldb,
912 mem_ctx, policy_state->system_dn, &msgs, attrs,
913 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
914 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
916 ldb_transaction_cancel(policy_state->sam_ldb);
917 return NT_STATUS_OBJECT_NAME_COLLISION;
920 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
921 /* search for the trusted_domain record */
922 ret = gendb_search(policy_state->sam_ldb,
923 mem_ctx, policy_state->system_dn, &msgs, attrs,
924 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
925 netbios_encoded, netbios_encoded, netbios_encoded);
927 ldb_transaction_cancel(policy_state->sam_ldb);
928 return NT_STATUS_OBJECT_NAME_COLLISION;
933 ldb_transaction_cancel(policy_state->sam_ldb);
934 return NT_STATUS_INTERNAL_DB_CORRUPTION;
937 name = dns_name ? dns_name : netbios_name;
939 msg = ldb_msg_new(mem_ctx);
941 return NT_STATUS_NO_MEMORY;
944 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
945 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
946 ldb_transaction_cancel(policy_state->sam_ldb);
947 return NT_STATUS_NO_MEMORY;
950 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", netbios_name);
952 if (r->in.info->sid) {
953 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
955 ldb_transaction_cancel(policy_state->sam_ldb);
956 return NT_STATUS_NO_MEMORY;
959 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
962 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
964 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
966 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
968 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
971 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
974 if (trustAuthIncoming.data) {
975 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
976 if (ret != LDB_SUCCESS) {
977 ldb_transaction_cancel(policy_state->sam_ldb);
978 return NT_STATUS_NO_MEMORY;
981 if (trustAuthOutgoing.data) {
982 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
983 if (ret != LDB_SUCCESS) {
984 ldb_transaction_cancel(policy_state->sam_ldb);
985 return NT_STATUS_NO_MEMORY;
989 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
991 /* create the trusted_domain */
992 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
996 case LDB_ERR_ENTRY_ALREADY_EXISTS:
997 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
998 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
999 ldb_dn_get_linearized(msg->dn),
1000 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1001 return NT_STATUS_DOMAIN_EXISTS;
1002 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1003 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1004 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1005 ldb_dn_get_linearized(msg->dn),
1006 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1007 return NT_STATUS_ACCESS_DENIED;
1009 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1010 DEBUG(0,("Failed to create user record %s: %s\n",
1011 ldb_dn_get_linearized(msg->dn),
1012 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1013 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1016 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1017 msg_user = ldb_msg_new(mem_ctx);
1018 if (msg_user == NULL) {
1019 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1020 return NT_STATUS_NO_MEMORY;
1023 /* Inbound trusts must also create a cn=users object to match */
1025 trusted_domain_state->trusted_domain_user_dn = msg_user->dn
1026 = ldb_dn_copy(trusted_domain_state, policy_state->domain_dn);
1027 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=users")) {
1028 ldb_transaction_cancel(policy_state->sam_ldb);
1029 return NT_STATUS_NO_MEMORY;
1032 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=%s", netbios_name)) {
1033 ldb_transaction_cancel(policy_state->sam_ldb);
1034 return NT_STATUS_NO_MEMORY;
1037 ldb_msg_add_string(msg_user, "objectClass", "user");
1039 ldb_msg_add_steal_string(msg_user, "samAccountName",
1040 talloc_asprintf(mem_ctx, "%s$", netbios_name));
1042 if (samdb_msg_add_uint(trusted_domain_state->policy->sam_ldb, mem_ctx, msg_user,
1043 "userAccountControl",
1044 UF_INTERDOMAIN_TRUST_ACCOUNT) != 0) {
1045 ldb_transaction_cancel(policy_state->sam_ldb);
1046 return NT_STATUS_NO_MEMORY;
1049 if (auth_struct.incoming.count) {
1051 for (i=0; i < auth_struct.incoming.count; i++ ) {
1052 if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_NT4OWF) {
1053 samdb_msg_add_hash(trusted_domain_state->policy->sam_ldb,
1054 mem_ctx, msg_user, "unicodePwd",
1055 &auth_struct.incoming.current[i]->AuthInfo.nt4owf.password);
1056 } else if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_CLEAR) {
1057 DATA_BLOB new_password = data_blob_const(auth_struct.incoming.current[i]->AuthInfo.clear.password,
1058 auth_struct.incoming.current[i]->AuthInfo.clear.size);
1059 ret = ldb_msg_add_value(msg_user, "clearTextPassword", &new_password, NULL);
1060 if (ret != LDB_SUCCESS) {
1061 ldb_transaction_cancel(policy_state->sam_ldb);
1062 return NT_STATUS_NO_MEMORY;
1068 /* create the cn=users trusted_domain account */
1069 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg_user);
1073 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1074 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1075 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1076 ldb_dn_get_linearized(msg_user->dn),
1077 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1078 return NT_STATUS_DOMAIN_EXISTS;
1079 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1080 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1081 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1082 ldb_dn_get_linearized(msg_user->dn),
1083 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1084 return NT_STATUS_ACCESS_DENIED;
1086 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1087 DEBUG(0,("Failed to create user record %s: %s\n",
1088 ldb_dn_get_linearized(msg_user->dn),
1089 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1090 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1094 ret = ldb_transaction_commit(policy_state->sam_ldb);
1095 if (ret != LDB_SUCCESS) {
1096 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1099 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1101 return NT_STATUS_NO_MEMORY;
1104 handle->data = talloc_steal(handle, trusted_domain_state);
1106 trusted_domain_state->access_mask = r->in.access_mask;
1107 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1109 *r->out.trustdom_handle = handle->wire_handle;
1111 return NT_STATUS_OK;
1115 lsa_CreateTrustedDomainEx2
1117 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1118 TALLOC_CTX *mem_ctx,
1119 struct lsa_CreateTrustedDomainEx2 *r)
1121 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
1124 lsa_CreateTrustedDomainEx
1126 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1127 TALLOC_CTX *mem_ctx,
1128 struct lsa_CreateTrustedDomainEx *r)
1130 struct lsa_CreateTrustedDomainEx2 r2;
1132 r2.in.policy_handle = r->in.policy_handle;
1133 r2.in.info = r->in.info;
1134 r2.in.auth_info = r->in.auth_info;
1135 r2.out.trustdom_handle = r->out.trustdom_handle;
1136 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
1140 lsa_CreateTrustedDomain
1142 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1143 struct lsa_CreateTrustedDomain *r)
1145 struct lsa_CreateTrustedDomainEx2 r2;
1147 r2.in.policy_handle = r->in.policy_handle;
1148 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1150 return NT_STATUS_NO_MEMORY;
1153 r2.in.info->domain_name.string = NULL;
1154 r2.in.info->netbios_name = r->in.info->name;
1155 r2.in.info->sid = r->in.info->sid;
1156 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1157 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1158 r2.in.info->trust_attributes = 0;
1160 r2.in.access_mask = r->in.access_mask;
1161 r2.out.trustdom_handle = r->out.trustdom_handle;
1163 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1168 lsa_OpenTrustedDomain
1170 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1171 struct lsa_OpenTrustedDomain *r)
1173 struct dcesrv_handle *policy_handle;
1175 struct lsa_policy_state *policy_state;
1176 struct lsa_trusted_domain_state *trusted_domain_state;
1177 struct dcesrv_handle *handle;
1178 struct ldb_message **msgs;
1179 const char *attrs[] = {
1185 const char *sid_string;
1188 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1189 ZERO_STRUCTP(r->out.trustdom_handle);
1190 policy_state = policy_handle->data;
1192 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1193 if (!trusted_domain_state) {
1194 return NT_STATUS_NO_MEMORY;
1196 trusted_domain_state->policy = policy_state;
1198 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1200 return NT_STATUS_NO_MEMORY;
1203 /* search for the trusted_domain record */
1204 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1205 mem_ctx, policy_state->system_dn, &msgs, attrs,
1206 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
1209 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1213 DEBUG(0,("Found %d records matching DN %s\n", ret,
1214 ldb_dn_get_linearized(policy_state->system_dn)));
1215 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1218 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1220 trusted_domain_state->trusted_domain_user_dn = NULL;
1222 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1223 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1224 /* search for the trusted_domain record */
1225 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1226 mem_ctx, policy_state->domain_dn, &msgs, attrs,
1227 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%d))",
1228 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1230 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1233 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1235 return NT_STATUS_NO_MEMORY;
1238 handle->data = talloc_steal(handle, trusted_domain_state);
1240 trusted_domain_state->access_mask = r->in.access_mask;
1241 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1243 *r->out.trustdom_handle = handle->wire_handle;
1245 return NT_STATUS_OK;
1250 lsa_OpenTrustedDomainByName
1252 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1253 TALLOC_CTX *mem_ctx,
1254 struct lsa_OpenTrustedDomainByName *r)
1256 struct dcesrv_handle *policy_handle;
1258 struct lsa_policy_state *policy_state;
1259 struct lsa_trusted_domain_state *trusted_domain_state;
1260 struct dcesrv_handle *handle;
1261 struct ldb_message **msgs;
1262 const char *attrs[] = {
1268 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1269 ZERO_STRUCTP(r->out.trustdom_handle);
1270 policy_state = policy_handle->data;
1272 if (!r->in.name.string) {
1273 return NT_STATUS_INVALID_PARAMETER;
1276 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1277 if (!trusted_domain_state) {
1278 return NT_STATUS_NO_MEMORY;
1280 trusted_domain_state->policy = policy_state;
1282 /* search for the trusted_domain record */
1283 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1284 mem_ctx, policy_state->system_dn, &msgs, attrs,
1285 "(&(flatname=%s)(objectclass=trustedDomain))",
1286 ldb_binary_encode_string(mem_ctx, r->in.name.string));
1288 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1292 DEBUG(0,("Found %d records matching DN %s\n", ret,
1293 ldb_dn_get_linearized(policy_state->system_dn)));
1294 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1297 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1299 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1301 return NT_STATUS_NO_MEMORY;
1304 handle->data = talloc_steal(handle, trusted_domain_state);
1306 trusted_domain_state->access_mask = r->in.access_mask;
1307 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1309 *r->out.trustdom_handle = handle->wire_handle;
1311 return NT_STATUS_OK;
1317 lsa_SetTrustedDomainInfo
1319 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1320 struct lsa_SetTrustedDomainInfo *r)
1322 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1328 lsa_SetInfomrationTrustedDomain
1330 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1331 TALLOC_CTX *mem_ctx,
1332 struct lsa_SetInformationTrustedDomain *r)
1334 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1339 lsa_DeleteTrustedDomain
1341 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1342 struct lsa_DeleteTrustedDomain *r)
1345 struct lsa_OpenTrustedDomain opn;
1346 struct lsa_DeleteObject del;
1347 struct dcesrv_handle *h;
1349 opn.in.handle = r->in.handle;
1350 opn.in.sid = r->in.dom_sid;
1351 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1352 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1353 if (!opn.out.trustdom_handle) {
1354 return NT_STATUS_NO_MEMORY;
1356 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1357 if (!NT_STATUS_IS_OK(status)) {
1361 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1362 talloc_steal(mem_ctx, h);
1364 del.in.handle = opn.out.trustdom_handle;
1365 del.out.handle = opn.out.trustdom_handle;
1366 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
1367 if (!NT_STATUS_IS_OK(status)) {
1370 return NT_STATUS_OK;
1373 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1374 struct ldb_message *msg,
1375 struct lsa_TrustDomainInfoInfoEx *info_ex)
1377 info_ex->domain_name.string
1378 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1379 info_ex->netbios_name.string
1380 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1382 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1383 info_ex->trust_direction
1384 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1386 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1387 info_ex->trust_attributes
1388 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1389 return NT_STATUS_OK;
1393 lsa_QueryTrustedDomainInfo
1395 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1396 struct lsa_QueryTrustedDomainInfo *r)
1398 union lsa_TrustedDomainInfo *info = NULL;
1399 struct dcesrv_handle *h;
1400 struct lsa_trusted_domain_state *trusted_domain_state;
1401 struct ldb_message *msg;
1403 struct ldb_message **res;
1404 const char *attrs[] = {
1407 "securityIdentifier",
1411 "msDs-supportedEncryptionTypes",
1415 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1417 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1419 /* pull all the user attributes */
1420 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1421 trusted_domain_state->trusted_domain_dn, &res, attrs);
1423 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1427 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
1429 return NT_STATUS_NO_MEMORY;
1431 *r->out.info = info;
1433 switch (r->in.level) {
1434 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1435 info->name.netbios_name.string
1436 = samdb_result_string(msg, "flatname", NULL);
1438 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1439 info->posix_offset.posix_offset
1440 = samdb_result_uint(msg, "posixOffset", 0);
1442 #if 0 /* Win2k3 doesn't implement this */
1443 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1444 r->out.info->info_basic.netbios_name.string
1445 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1446 r->out.info->info_basic.sid
1447 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1450 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1451 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
1453 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1454 ZERO_STRUCT(info->full_info);
1455 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
1457 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1458 ZERO_STRUCT(info->full_info2_internal);
1459 info->full_info2_internal.posix_offset.posix_offset
1460 = samdb_result_uint(msg, "posixOffset", 0);
1461 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
1463 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1464 info->enc_types.enc_types
1465 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
1468 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1469 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1470 /* oops, we don't want to return the info after all */
1472 *r->out.info = NULL;
1473 return NT_STATUS_INVALID_PARAMETER;
1475 /* oops, we don't want to return the info after all */
1477 *r->out.info = NULL;
1478 return NT_STATUS_INVALID_INFO_CLASS;
1481 return NT_STATUS_OK;
1486 lsa_QueryTrustedDomainInfoBySid
1488 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1489 struct lsa_QueryTrustedDomainInfoBySid *r)
1492 struct lsa_OpenTrustedDomain opn;
1493 struct lsa_QueryTrustedDomainInfo query;
1494 struct dcesrv_handle *h;
1496 opn.in.handle = r->in.handle;
1497 opn.in.sid = r->in.dom_sid;
1498 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1499 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1500 if (!opn.out.trustdom_handle) {
1501 return NT_STATUS_NO_MEMORY;
1503 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1504 if (!NT_STATUS_IS_OK(status)) {
1508 /* Ensure this handle goes away at the end of this call */
1509 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1510 talloc_steal(mem_ctx, h);
1512 query.in.trustdom_handle = opn.out.trustdom_handle;
1513 query.in.level = r->in.level;
1514 query.out.info = r->out.info;
1515 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1516 if (!NT_STATUS_IS_OK(status)) {
1520 return NT_STATUS_OK;
1524 lsa_SetTrustedDomainInfoByName
1526 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1527 TALLOC_CTX *mem_ctx,
1528 struct lsa_SetTrustedDomainInfoByName *r)
1530 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1534 lsa_QueryTrustedDomainInfoByName
1536 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1537 TALLOC_CTX *mem_ctx,
1538 struct lsa_QueryTrustedDomainInfoByName *r)
1541 struct lsa_OpenTrustedDomainByName opn;
1542 struct lsa_QueryTrustedDomainInfo query;
1543 struct dcesrv_handle *h;
1545 opn.in.handle = r->in.handle;
1546 opn.in.name = *r->in.trusted_domain;
1547 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1548 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1549 if (!opn.out.trustdom_handle) {
1550 return NT_STATUS_NO_MEMORY;
1552 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
1553 if (!NT_STATUS_IS_OK(status)) {
1557 /* Ensure this handle goes away at the end of this call */
1558 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1559 talloc_steal(mem_ctx, h);
1561 query.in.trustdom_handle = opn.out.trustdom_handle;
1562 query.in.level = r->in.level;
1563 query.out.info = r->out.info;
1564 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1565 if (!NT_STATUS_IS_OK(status)) {
1569 return NT_STATUS_OK;
1573 lsa_CloseTrustedDomainEx
1575 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1576 TALLOC_CTX *mem_ctx,
1577 struct lsa_CloseTrustedDomainEx *r)
1579 /* The result of a bad hair day from an IDL programmer? Not
1580 * implmented in Win2k3. You should always just lsa_Close
1582 return NT_STATUS_NOT_IMPLEMENTED;
1587 comparison function for sorting lsa_DomainInformation array
1589 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1591 return strcasecmp_m(e1->name.string, e2->name.string);
1597 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1598 struct lsa_EnumTrustDom *r)
1600 struct dcesrv_handle *policy_handle;
1601 struct lsa_DomainInfo *entries;
1602 struct lsa_policy_state *policy_state;
1603 struct ldb_message **domains;
1604 const char *attrs[] = {
1606 "securityIdentifier",
1613 *r->out.resume_handle = 0;
1615 r->out.domains->domains = NULL;
1616 r->out.domains->count = 0;
1618 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1620 policy_state = policy_handle->data;
1622 /* search for all users in this domain. This could possibly be cached and
1623 resumed based on resume_key */
1624 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1625 "objectclass=trustedDomain");
1627 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1630 /* convert to lsa_TrustInformation format */
1631 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1633 return NT_STATUS_NO_MEMORY;
1635 for (i=0;i<count;i++) {
1636 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1637 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1640 /* sort the results by name */
1641 TYPESAFE_QSORT(entries, count, 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 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
1664 * always be larger than the previous input resume handle, in
1665 * particular when hitting the last query it is vital to set the
1666 * resume handle correctly to avoid infinite client loops, as
1667 * seen e.g. with Windows XP SP3 when resume handle is 0 and
1668 * status is NT_STATUS_OK - gd */
1670 *r->out.resume_handle = (uint32_t)-1;
1672 return NT_STATUS_OK;
1676 comparison function for sorting lsa_DomainInformation array
1678 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1680 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1684 lsa_EnumTrustedDomainsEx
1686 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1687 struct lsa_EnumTrustedDomainsEx *r)
1689 struct dcesrv_handle *policy_handle;
1690 struct lsa_TrustDomainInfoInfoEx *entries;
1691 struct lsa_policy_state *policy_state;
1692 struct ldb_message **domains;
1693 const char *attrs[] = {
1696 "securityIdentifier",
1706 *r->out.resume_handle = 0;
1708 r->out.domains->domains = NULL;
1709 r->out.domains->count = 0;
1711 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1713 policy_state = policy_handle->data;
1715 /* search for all users in this domain. This could possibly be cached and
1716 resumed based on resume_key */
1717 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1718 "objectclass=trustedDomain");
1720 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1723 /* convert to lsa_DomainInformation format */
1724 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1726 return NT_STATUS_NO_MEMORY;
1728 for (i=0;i<count;i++) {
1729 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1730 if (!NT_STATUS_IS_OK(nt_status)) {
1735 /* sort the results by name */
1736 TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
1738 if (*r->in.resume_handle >= count) {
1739 *r->out.resume_handle = -1;
1741 return NT_STATUS_NO_MORE_ENTRIES;
1744 /* return the rest, limit by max_size. Note that we
1745 use the w2k3 element size value of 60 */
1746 r->out.domains->count = count - *r->in.resume_handle;
1747 r->out.domains->count = MIN(r->out.domains->count,
1748 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1750 r->out.domains->domains = entries + *r->in.resume_handle;
1751 r->out.domains->count = r->out.domains->count;
1753 if (r->out.domains->count < count - *r->in.resume_handle) {
1754 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1755 return STATUS_MORE_ENTRIES;
1758 return NT_STATUS_OK;
1765 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1766 struct lsa_OpenAccount *r)
1768 struct dcesrv_handle *h, *ah;
1769 struct lsa_policy_state *state;
1770 struct lsa_account_state *astate;
1772 ZERO_STRUCTP(r->out.acct_handle);
1774 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1778 astate = talloc(dce_call->conn, struct lsa_account_state);
1779 if (astate == NULL) {
1780 return NT_STATUS_NO_MEMORY;
1783 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1784 if (astate->account_sid == NULL) {
1785 talloc_free(astate);
1786 return NT_STATUS_NO_MEMORY;
1789 astate->policy = talloc_reference(astate, state);
1790 astate->access_mask = r->in.access_mask;
1792 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1794 talloc_free(astate);
1795 return NT_STATUS_NO_MEMORY;
1798 ah->data = talloc_steal(ah, astate);
1800 *r->out.acct_handle = ah->wire_handle;
1802 return NT_STATUS_OK;
1807 lsa_EnumPrivsAccount
1809 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1810 TALLOC_CTX *mem_ctx,
1811 struct lsa_EnumPrivsAccount *r)
1813 struct dcesrv_handle *h;
1814 struct lsa_account_state *astate;
1816 struct ldb_message **res;
1817 const char * const attrs[] = { "privilege", NULL};
1818 struct ldb_message_element *el;
1820 struct lsa_PrivilegeSet *privs;
1822 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1826 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1827 if (privs == NULL) {
1828 return NT_STATUS_NO_MEMORY;
1834 *r->out.privs = privs;
1836 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1837 if (sidstr == NULL) {
1838 return NT_STATUS_NO_MEMORY;
1841 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
1842 "objectSid=%s", sidstr);
1844 return NT_STATUS_OK;
1847 el = ldb_msg_find_element(res[0], "privilege");
1848 if (el == NULL || el->num_values == 0) {
1849 return NT_STATUS_OK;
1852 privs->set = talloc_array(privs,
1853 struct lsa_LUIDAttribute, el->num_values);
1854 if (privs->set == NULL) {
1855 return NT_STATUS_NO_MEMORY;
1858 for (i=0;i<el->num_values;i++) {
1859 int id = sec_privilege_id((const char *)el->values[i].data);
1861 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1863 privs->set[i].attribute = 0;
1864 privs->set[i].luid.low = id;
1865 privs->set[i].luid.high = 0;
1868 privs->count = el->num_values;
1870 return NT_STATUS_OK;
1874 lsa_EnumAccountRights
1876 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1877 TALLOC_CTX *mem_ctx,
1878 struct lsa_EnumAccountRights *r)
1880 struct dcesrv_handle *h;
1881 struct lsa_policy_state *state;
1883 struct ldb_message **res;
1884 const char * const attrs[] = { "privilege", NULL};
1886 struct ldb_message_element *el;
1888 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1892 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1893 if (sidstr == NULL) {
1894 return NT_STATUS_NO_MEMORY;
1897 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
1898 "(&(objectSid=%s)(privilege=*))", sidstr);
1900 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1903 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1906 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1907 dom_sid_string(mem_ctx, r->in.sid),
1908 ldb_errstring(state->pdb)));
1909 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1912 el = ldb_msg_find_element(res[0], "privilege");
1913 if (el == NULL || el->num_values == 0) {
1914 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1917 r->out.rights->count = el->num_values;
1918 r->out.rights->names = talloc_array(r->out.rights,
1919 struct lsa_StringLarge, r->out.rights->count);
1920 if (r->out.rights->names == NULL) {
1921 return NT_STATUS_NO_MEMORY;
1924 for (i=0;i<el->num_values;i++) {
1925 r->out.rights->names[i].string = (const char *)el->values[i].data;
1928 return NT_STATUS_OK;
1934 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1936 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1937 TALLOC_CTX *mem_ctx,
1938 struct lsa_policy_state *state,
1940 struct dom_sid *sid,
1941 const struct lsa_RightSet *rights)
1943 const char *sidstr, *sidndrstr;
1944 struct ldb_message *msg;
1945 struct ldb_message_element *el;
1947 struct lsa_EnumAccountRights r2;
1950 if (security_session_user_level(dce_call->conn->auth_state.session_info) <
1951 SECURITY_ADMINISTRATOR) {
1952 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
1953 return NT_STATUS_ACCESS_DENIED;
1956 msg = ldb_msg_new(mem_ctx);
1958 return NT_STATUS_NO_MEMORY;
1961 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
1962 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg);
1964 sidstr = dom_sid_string(msg, sid);
1965 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg);
1967 dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
1968 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg);
1970 msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
1971 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg);
1973 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1976 r2.in.handle = &state->handle->wire_handle;
1978 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1980 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1981 if (!NT_STATUS_IS_OK(status)) {
1982 ZERO_STRUCTP(r2.out.rights);
1986 for (i=0;i<rights->count;i++) {
1987 if (sec_privilege_id(rights->names[i].string) == -1) {
1989 return NT_STATUS_NO_SUCH_PRIVILEGE;
1992 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1994 for (j=0;j<r2.out.rights->count;j++) {
1995 if (strcasecmp_m(r2.out.rights->names[j].string,
1996 rights->names[i].string) == 0) {
2000 if (j != r2.out.rights->count) continue;
2003 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2004 if (ret != LDB_SUCCESS) {
2006 return NT_STATUS_NO_MEMORY;
2010 el = ldb_msg_find_element(msg, "privilege");
2013 return NT_STATUS_OK;
2016 el->flags = ldb_flag;
2018 ret = ldb_modify(state->pdb, msg);
2019 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
2020 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
2022 return NT_STATUS_NO_MEMORY;
2024 samdb_msg_add_string(state->pdb, msg, msg, "comment", "added via LSA");
2025 ret = ldb_add(state->pdb, msg);
2027 if (ret != LDB_SUCCESS) {
2028 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2030 return NT_STATUS_OK;
2032 DEBUG(3, ("Could not %s attributes from %s: %s",
2033 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2034 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
2036 return NT_STATUS_UNEXPECTED_IO_ERROR;
2040 return NT_STATUS_OK;
2044 lsa_AddPrivilegesToAccount
2046 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2047 struct lsa_AddPrivilegesToAccount *r)
2049 struct lsa_RightSet rights;
2050 struct dcesrv_handle *h;
2051 struct lsa_account_state *astate;
2054 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2058 rights.count = r->in.privs->count;
2059 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2060 if (rights.names == NULL) {
2061 return NT_STATUS_NO_MEMORY;
2063 for (i=0;i<rights.count;i++) {
2064 int id = r->in.privs->set[i].luid.low;
2065 if (r->in.privs->set[i].luid.high) {
2066 return NT_STATUS_NO_SUCH_PRIVILEGE;
2068 rights.names[i].string = sec_privilege_name(id);
2069 if (rights.names[i].string == NULL) {
2070 return NT_STATUS_NO_SUCH_PRIVILEGE;
2074 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2075 LDB_FLAG_MOD_ADD, astate->account_sid,
2081 lsa_RemovePrivilegesFromAccount
2083 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2084 struct lsa_RemovePrivilegesFromAccount *r)
2086 struct lsa_RightSet *rights;
2087 struct dcesrv_handle *h;
2088 struct lsa_account_state *astate;
2091 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2095 rights = talloc(mem_ctx, struct lsa_RightSet);
2097 if (r->in.remove_all == 1 &&
2098 r->in.privs == NULL) {
2099 struct lsa_EnumAccountRights r2;
2102 r2.in.handle = &astate->policy->handle->wire_handle;
2103 r2.in.sid = astate->account_sid;
2104 r2.out.rights = rights;
2106 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2107 if (!NT_STATUS_IS_OK(status)) {
2111 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2112 LDB_FLAG_MOD_DELETE, astate->account_sid,
2116 if (r->in.remove_all != 0) {
2117 return NT_STATUS_INVALID_PARAMETER;
2120 rights->count = r->in.privs->count;
2121 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2122 if (rights->names == NULL) {
2123 return NT_STATUS_NO_MEMORY;
2125 for (i=0;i<rights->count;i++) {
2126 int id = r->in.privs->set[i].luid.low;
2127 if (r->in.privs->set[i].luid.high) {
2128 return NT_STATUS_NO_SUCH_PRIVILEGE;
2130 rights->names[i].string = sec_privilege_name(id);
2131 if (rights->names[i].string == NULL) {
2132 return NT_STATUS_NO_SUCH_PRIVILEGE;
2136 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2137 LDB_FLAG_MOD_DELETE, astate->account_sid,
2143 lsa_GetQuotasForAccount
2145 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2146 struct lsa_GetQuotasForAccount *r)
2148 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2153 lsa_SetQuotasForAccount
2155 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2156 struct lsa_SetQuotasForAccount *r)
2158 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2163 lsa_GetSystemAccessAccount
2165 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2166 struct lsa_GetSystemAccessAccount *r)
2170 struct lsa_EnumPrivsAccount enumPrivs;
2171 struct lsa_PrivilegeSet *privs;
2173 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2175 return NT_STATUS_NO_MEMORY;
2181 enumPrivs.in.handle = r->in.handle;
2182 enumPrivs.out.privs = &privs;
2184 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2185 if (!NT_STATUS_IS_OK(status)) {
2189 *(r->out.access_mask) = 0x00000000;
2191 for (i = 0; i < privs->count; i++) {
2192 int priv = privs->set[i].luid.low;
2195 case SEC_PRIV_INTERACTIVE_LOGON:
2196 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2198 case SEC_PRIV_NETWORK_LOGON:
2199 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2201 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2202 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2207 return NT_STATUS_OK;
2212 lsa_SetSystemAccessAccount
2214 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2215 struct lsa_SetSystemAccessAccount *r)
2217 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2224 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2225 struct lsa_CreateSecret *r)
2227 struct dcesrv_handle *policy_handle;
2228 struct lsa_policy_state *policy_state;
2229 struct lsa_secret_state *secret_state;
2230 struct dcesrv_handle *handle;
2231 struct ldb_message **msgs, *msg;
2232 const char *attrs[] = {
2240 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2241 ZERO_STRUCTP(r->out.sec_handle);
2243 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2245 case SECURITY_SYSTEM:
2246 case SECURITY_ADMINISTRATOR:
2249 /* Users and annonymous are not allowed create secrets */
2250 return NT_STATUS_ACCESS_DENIED;
2253 policy_state = policy_handle->data;
2255 if (!r->in.name.string) {
2256 return NT_STATUS_INVALID_PARAMETER;
2259 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2260 if (!secret_state) {
2261 return NT_STATUS_NO_MEMORY;
2263 secret_state->policy = policy_state;
2265 msg = ldb_msg_new(mem_ctx);
2267 return NT_STATUS_NO_MEMORY;
2270 if (strncmp("G$", r->in.name.string, 2) == 0) {
2272 name = &r->in.name.string[2];
2273 /* 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) */
2274 secret_state->sam_ldb = talloc_reference(secret_state,
2275 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
2276 secret_state->global = true;
2278 if (strlen(name) < 1) {
2279 return NT_STATUS_INVALID_PARAMETER;
2282 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2283 /* search for the secret record */
2284 ret = gendb_search(secret_state->sam_ldb,
2285 mem_ctx, policy_state->system_dn, &msgs, attrs,
2286 "(&(cn=%s)(objectclass=secret))",
2289 return NT_STATUS_OBJECT_NAME_COLLISION;
2293 DEBUG(0,("Failure searching for CN=%s: %s\n",
2294 name2, ldb_errstring(secret_state->sam_ldb)));
2295 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2298 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2299 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2300 return NT_STATUS_NO_MEMORY;
2303 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2306 secret_state->global = false;
2308 name = r->in.name.string;
2309 if (strlen(name) < 1) {
2310 return NT_STATUS_INVALID_PARAMETER;
2313 secret_state->sam_ldb = talloc_reference(secret_state,
2314 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2315 /* search for the secret record */
2316 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2317 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2319 "(&(cn=%s)(objectclass=secret))",
2320 ldb_binary_encode_string(mem_ctx, name));
2322 return NT_STATUS_OBJECT_NAME_COLLISION;
2326 DEBUG(0,("Failure searching for CN=%s: %s\n",
2327 name, ldb_errstring(secret_state->sam_ldb)));
2328 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2331 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2332 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2335 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2337 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2339 /* create the secret */
2340 ret = ldb_add(secret_state->sam_ldb, msg);
2341 if (ret != LDB_SUCCESS) {
2342 DEBUG(0,("Failed to create secret record %s: %s\n",
2343 ldb_dn_get_linearized(msg->dn),
2344 ldb_errstring(secret_state->sam_ldb)));
2345 return NT_STATUS_ACCESS_DENIED;
2348 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2350 return NT_STATUS_NO_MEMORY;
2353 handle->data = talloc_steal(handle, secret_state);
2355 secret_state->access_mask = r->in.access_mask;
2356 secret_state->policy = talloc_reference(secret_state, policy_state);
2358 *r->out.sec_handle = handle->wire_handle;
2360 return NT_STATUS_OK;
2367 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2368 struct lsa_OpenSecret *r)
2370 struct dcesrv_handle *policy_handle;
2372 struct lsa_policy_state *policy_state;
2373 struct lsa_secret_state *secret_state;
2374 struct dcesrv_handle *handle;
2375 struct ldb_message **msgs;
2376 const char *attrs[] = {
2384 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2385 ZERO_STRUCTP(r->out.sec_handle);
2386 policy_state = policy_handle->data;
2388 if (!r->in.name.string) {
2389 return NT_STATUS_INVALID_PARAMETER;
2392 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2394 case SECURITY_SYSTEM:
2395 case SECURITY_ADMINISTRATOR:
2398 /* Users and annonymous are not allowed to access secrets */
2399 return NT_STATUS_ACCESS_DENIED;
2402 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2403 if (!secret_state) {
2404 return NT_STATUS_NO_MEMORY;
2406 secret_state->policy = policy_state;
2408 if (strncmp("G$", r->in.name.string, 2) == 0) {
2409 name = &r->in.name.string[2];
2410 /* 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) */
2411 secret_state->sam_ldb = talloc_reference(secret_state,
2412 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
2413 secret_state->global = true;
2415 if (strlen(name) < 1) {
2416 return NT_STATUS_INVALID_PARAMETER;
2419 /* search for the secret record */
2420 ret = gendb_search(secret_state->sam_ldb,
2421 mem_ctx, policy_state->system_dn, &msgs, attrs,
2422 "(&(cn=%s Secret)(objectclass=secret))",
2423 ldb_binary_encode_string(mem_ctx, name));
2425 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2429 DEBUG(0,("Found %d records matching DN %s\n", ret,
2430 ldb_dn_get_linearized(policy_state->system_dn)));
2431 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2435 secret_state->global = false;
2436 secret_state->sam_ldb = talloc_reference(secret_state,
2437 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2439 name = r->in.name.string;
2440 if (strlen(name) < 1) {
2441 return NT_STATUS_INVALID_PARAMETER;
2444 /* search for the secret record */
2445 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2446 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2448 "(&(cn=%s)(objectclass=secret))",
2449 ldb_binary_encode_string(mem_ctx, name));
2451 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2455 DEBUG(0,("Found %d records matching CN=%s\n",
2456 ret, ldb_binary_encode_string(mem_ctx, name)));
2457 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2461 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2463 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2465 return NT_STATUS_NO_MEMORY;
2468 handle->data = talloc_steal(handle, secret_state);
2470 secret_state->access_mask = r->in.access_mask;
2471 secret_state->policy = talloc_reference(secret_state, policy_state);
2473 *r->out.sec_handle = handle->wire_handle;
2475 return NT_STATUS_OK;
2482 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2483 struct lsa_SetSecret *r)
2486 struct dcesrv_handle *h;
2487 struct lsa_secret_state *secret_state;
2488 struct ldb_message *msg;
2489 DATA_BLOB session_key;
2490 DATA_BLOB crypt_secret, secret;
2493 NTSTATUS status = NT_STATUS_OK;
2495 struct timeval now = timeval_current();
2496 NTTIME nt_now = timeval_to_nttime(&now);
2498 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2500 secret_state = h->data;
2502 msg = ldb_msg_new(mem_ctx);
2504 return NT_STATUS_NO_MEMORY;
2507 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2509 return NT_STATUS_NO_MEMORY;
2511 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2512 if (!NT_STATUS_IS_OK(status)) {
2516 if (r->in.old_val) {
2518 crypt_secret.data = r->in.old_val->data;
2519 crypt_secret.length = r->in.old_val->size;
2521 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2522 if (!NT_STATUS_IS_OK(status)) {
2526 val.data = secret.data;
2527 val.length = secret.length;
2530 if (samdb_msg_add_value(secret_state->sam_ldb,
2531 mem_ctx, msg, "priorValue", &val) != LDB_SUCCESS) {
2532 return NT_STATUS_NO_MEMORY;
2535 /* set old value mtime */
2536 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2537 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
2538 return NT_STATUS_NO_MEMORY;
2542 /* If the old value is not set, then migrate the
2543 * current value to the old value */
2544 const struct ldb_val *old_val;
2545 NTTIME last_set_time;
2546 struct ldb_message **res;
2547 const char *attrs[] = {
2553 /* search for the secret record */
2554 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2555 secret_state->secret_dn, &res, attrs);
2557 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2561 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2562 ldb_dn_get_linearized(secret_state->secret_dn)));
2563 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2566 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2567 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2571 if (samdb_msg_add_value(secret_state->sam_ldb,
2572 mem_ctx, msg, "priorValue",
2574 return NT_STATUS_NO_MEMORY;
2577 if (samdb_msg_add_delete(secret_state->sam_ldb,
2578 mem_ctx, msg, "priorValue")) {
2579 return NT_STATUS_NO_MEMORY;
2584 /* set old value mtime */
2585 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2586 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2587 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
2588 return NT_STATUS_NO_MEMORY;
2591 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2592 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
2593 return NT_STATUS_NO_MEMORY;
2598 if (r->in.new_val) {
2600 crypt_secret.data = r->in.new_val->data;
2601 crypt_secret.length = r->in.new_val->size;
2603 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2604 if (!NT_STATUS_IS_OK(status)) {
2608 val.data = secret.data;
2609 val.length = secret.length;
2612 if (samdb_msg_add_value(secret_state->sam_ldb,
2613 mem_ctx, msg, "currentValue", &val) != LDB_SUCCESS) {
2614 return NT_STATUS_NO_MEMORY;
2617 /* set new value mtime */
2618 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2619 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
2620 return NT_STATUS_NO_MEMORY;
2624 /* NULL out the NEW value */
2625 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2626 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
2627 return NT_STATUS_NO_MEMORY;
2629 if (samdb_msg_add_delete(secret_state->sam_ldb,
2630 mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
2631 return NT_STATUS_NO_MEMORY;
2635 /* modify the samdb record */
2636 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2637 if (ret != LDB_SUCCESS) {
2638 /* we really need samdb.c to return NTSTATUS */
2639 return NT_STATUS_UNSUCCESSFUL;
2642 return NT_STATUS_OK;
2649 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2650 struct lsa_QuerySecret *r)
2652 struct dcesrv_handle *h;
2653 struct lsa_secret_state *secret_state;
2654 struct ldb_message *msg;
2655 DATA_BLOB session_key;
2656 DATA_BLOB crypt_secret, secret;
2658 struct ldb_message **res;
2659 const char *attrs[] = {
2669 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2671 /* Ensure user is permitted to read this... */
2672 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2674 case SECURITY_SYSTEM:
2675 case SECURITY_ADMINISTRATOR:
2678 /* Users and annonymous are not allowed to read secrets */
2679 return NT_STATUS_ACCESS_DENIED;
2682 secret_state = h->data;
2684 /* pull all the user attributes */
2685 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2686 secret_state->secret_dn, &res, attrs);
2688 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2692 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2693 if (!NT_STATUS_IS_OK(nt_status)) {
2697 if (r->in.old_val) {
2698 const struct ldb_val *prior_val;
2699 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2700 if (!r->out.old_val) {
2701 return NT_STATUS_NO_MEMORY;
2703 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2705 if (prior_val && prior_val->length) {
2706 secret.data = prior_val->data;
2707 secret.length = prior_val->length;
2710 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2711 if (!crypt_secret.length) {
2712 return NT_STATUS_NO_MEMORY;
2714 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2715 if (!r->out.old_val->buf) {
2716 return NT_STATUS_NO_MEMORY;
2718 r->out.old_val->buf->size = crypt_secret.length;
2719 r->out.old_val->buf->length = crypt_secret.length;
2720 r->out.old_val->buf->data = crypt_secret.data;
2724 if (r->in.old_mtime) {
2725 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2726 if (!r->out.old_mtime) {
2727 return NT_STATUS_NO_MEMORY;
2729 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2732 if (r->in.new_val) {
2733 const struct ldb_val *new_val;
2734 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2735 if (!r->out.new_val) {
2736 return NT_STATUS_NO_MEMORY;
2739 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2741 if (new_val && new_val->length) {
2742 secret.data = new_val->data;
2743 secret.length = new_val->length;
2746 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2747 if (!crypt_secret.length) {
2748 return NT_STATUS_NO_MEMORY;
2750 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2751 if (!r->out.new_val->buf) {
2752 return NT_STATUS_NO_MEMORY;
2754 r->out.new_val->buf->length = crypt_secret.length;
2755 r->out.new_val->buf->size = crypt_secret.length;
2756 r->out.new_val->buf->data = crypt_secret.data;
2760 if (r->in.new_mtime) {
2761 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2762 if (!r->out.new_mtime) {
2763 return NT_STATUS_NO_MEMORY;
2765 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2768 return NT_STATUS_OK;
2775 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2776 TALLOC_CTX *mem_ctx,
2777 struct lsa_LookupPrivValue *r)
2779 struct dcesrv_handle *h;
2780 struct lsa_policy_state *state;
2783 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2787 id = sec_privilege_id(r->in.name->string);
2789 return NT_STATUS_NO_SUCH_PRIVILEGE;
2792 r->out.luid->low = id;
2793 r->out.luid->high = 0;
2795 return NT_STATUS_OK;
2802 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2803 TALLOC_CTX *mem_ctx,
2804 struct lsa_LookupPrivName *r)
2806 struct dcesrv_handle *h;
2807 struct lsa_policy_state *state;
2808 struct lsa_StringLarge *name;
2809 const char *privname;
2811 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2815 if (r->in.luid->high != 0) {
2816 return NT_STATUS_NO_SUCH_PRIVILEGE;
2819 privname = sec_privilege_name(r->in.luid->low);
2820 if (privname == NULL) {
2821 return NT_STATUS_NO_SUCH_PRIVILEGE;
2824 name = talloc(mem_ctx, struct lsa_StringLarge);
2826 return NT_STATUS_NO_MEMORY;
2829 name->string = privname;
2831 *r->out.name = name;
2833 return NT_STATUS_OK;
2838 lsa_LookupPrivDisplayName
2840 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2841 TALLOC_CTX *mem_ctx,
2842 struct lsa_LookupPrivDisplayName *r)
2844 struct dcesrv_handle *h;
2845 struct lsa_policy_state *state;
2846 struct lsa_StringLarge *disp_name = NULL;
2849 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2853 id = sec_privilege_id(r->in.name->string);
2855 return NT_STATUS_NO_SUCH_PRIVILEGE;
2858 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2859 if (disp_name == NULL) {
2860 return NT_STATUS_NO_MEMORY;
2863 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
2864 if (disp_name->string == NULL) {
2865 return NT_STATUS_INTERNAL_ERROR;
2868 *r->out.disp_name = disp_name;
2869 *r->out.returned_language_id = 0;
2871 return NT_STATUS_OK;
2876 lsa_EnumAccountsWithUserRight
2878 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2879 TALLOC_CTX *mem_ctx,
2880 struct lsa_EnumAccountsWithUserRight *r)
2882 struct dcesrv_handle *h;
2883 struct lsa_policy_state *state;
2885 struct ldb_message **res;
2886 const char * const attrs[] = { "objectSid", NULL};
2887 const char *privname;
2889 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2893 if (r->in.name == NULL) {
2894 return NT_STATUS_NO_SUCH_PRIVILEGE;
2897 privname = r->in.name->string;
2898 if (sec_privilege_id(privname) == -1) {
2899 return NT_STATUS_NO_SUCH_PRIVILEGE;
2902 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2903 "privilege=%s", privname);
2905 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2908 return NT_STATUS_NO_MORE_ENTRIES;
2911 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2912 if (r->out.sids->sids == NULL) {
2913 return NT_STATUS_NO_MEMORY;
2915 for (i=0;i<ret;i++) {
2916 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2917 res[i], "objectSid");
2918 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2920 r->out.sids->num_sids = ret;
2922 return NT_STATUS_OK;
2927 lsa_AddAccountRights
2929 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2930 TALLOC_CTX *mem_ctx,
2931 struct lsa_AddAccountRights *r)
2933 struct dcesrv_handle *h;
2934 struct lsa_policy_state *state;
2936 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2940 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2942 r->in.sid, r->in.rights);
2947 lsa_RemoveAccountRights
2949 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2950 TALLOC_CTX *mem_ctx,
2951 struct lsa_RemoveAccountRights *r)
2953 struct dcesrv_handle *h;
2954 struct lsa_policy_state *state;
2956 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2960 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2961 LDB_FLAG_MOD_DELETE,
2962 r->in.sid, r->in.rights);
2967 lsa_StorePrivateData
2969 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2970 struct lsa_StorePrivateData *r)
2972 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2977 lsa_RetrievePrivateData
2979 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2980 struct lsa_RetrievePrivateData *r)
2982 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2989 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2990 struct lsa_GetUserName *r)
2992 NTSTATUS status = NT_STATUS_OK;
2993 const char *account_name;
2994 const char *authority_name;
2995 struct lsa_String *_account_name;
2996 struct lsa_String *_authority_name = NULL;
2998 /* this is what w2k3 does */
2999 r->out.account_name = r->in.account_name;
3000 r->out.authority_name = r->in.authority_name;
3002 if (r->in.account_name
3003 && *r->in.account_name
3004 /* && *(*r->in.account_name)->string */
3006 return NT_STATUS_INVALID_PARAMETER;
3009 if (r->in.authority_name
3010 && *r->in.authority_name
3011 /* && *(*r->in.authority_name)->string */
3013 return NT_STATUS_INVALID_PARAMETER;
3016 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
3017 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
3019 _account_name = talloc(mem_ctx, struct lsa_String);
3020 NT_STATUS_HAVE_NO_MEMORY(_account_name);
3021 _account_name->string = account_name;
3023 if (r->in.authority_name) {
3024 _authority_name = talloc(mem_ctx, struct lsa_String);
3025 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
3026 _authority_name->string = authority_name;
3029 *r->out.account_name = _account_name;
3030 if (r->out.authority_name) {
3031 *r->out.authority_name = _authority_name;
3040 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
3041 TALLOC_CTX *mem_ctx,
3042 struct lsa_SetInfoPolicy2 *r)
3044 /* need to support these */
3045 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3049 lsa_QueryDomainInformationPolicy
3051 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3052 TALLOC_CTX *mem_ctx,
3053 struct lsa_QueryDomainInformationPolicy *r)
3055 union lsa_DomainInformationPolicy *info;
3057 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
3059 return NT_STATUS_NO_MEMORY;
3062 switch (r->in.level) {
3063 case LSA_DOMAIN_INFO_POLICY_EFS:
3065 *r->out.info = NULL;
3066 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3067 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
3069 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
3070 struct smb_krb5_context *smb_krb5_context;
3071 int ret = smb_krb5_init_context(mem_ctx,
3072 dce_call->event_ctx,
3073 dce_call->conn->dce_ctx->lp_ctx,
3077 *r->out.info = NULL;
3078 return NT_STATUS_INTERNAL_ERROR;
3080 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
3081 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3082 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3083 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
3084 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
3085 talloc_free(smb_krb5_context);
3086 *r->out.info = info;
3087 return NT_STATUS_OK;
3091 *r->out.info = NULL;
3092 return NT_STATUS_INVALID_INFO_CLASS;
3097 lsa_SetDomInfoPolicy
3099 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3100 TALLOC_CTX *mem_ctx,
3101 struct lsa_SetDomainInformationPolicy *r)
3103 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3109 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3110 TALLOC_CTX *mem_ctx,
3111 struct lsa_TestCall *r)
3113 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3119 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3120 struct lsa_CREDRWRITE *r)
3122 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3129 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3130 struct lsa_CREDRREAD *r)
3132 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3139 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3140 struct lsa_CREDRENUMERATE *r)
3142 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3147 lsa_CREDRWRITEDOMAINCREDENTIALS
3149 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3150 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3152 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3157 lsa_CREDRREADDOMAINCREDENTIALS
3159 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3160 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3162 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3169 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3170 struct lsa_CREDRDELETE *r)
3172 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3177 lsa_CREDRGETTARGETINFO
3179 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3180 struct lsa_CREDRGETTARGETINFO *r)
3182 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3187 lsa_CREDRPROFILELOADED
3189 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3190 struct lsa_CREDRPROFILELOADED *r)
3192 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3197 lsa_CREDRGETSESSIONTYPES
3199 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3200 struct lsa_CREDRGETSESSIONTYPES *r)
3202 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3207 lsa_LSARREGISTERAUDITEVENT
3209 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3210 struct lsa_LSARREGISTERAUDITEVENT *r)
3212 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3217 lsa_LSARGENAUDITEVENT
3219 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3220 struct lsa_LSARGENAUDITEVENT *r)
3222 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3227 lsa_LSARUNREGISTERAUDITEVENT
3229 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3230 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3232 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3237 lsa_lsaRQueryForestTrustInformation
3239 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3240 struct lsa_lsaRQueryForestTrustInformation *r)
3242 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3247 lsa_LSARSETFORESTTRUSTINFORMATION
3249 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3250 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3252 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3259 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3260 struct lsa_CREDRRENAME *r)
3262 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3268 lsa_LSAROPENPOLICYSCE
3270 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3271 struct lsa_LSAROPENPOLICYSCE *r)
3273 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3278 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3280 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3281 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3283 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3288 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3290 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3291 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3293 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3298 lsa_LSARADTREPORTSECURITYEVENT
3300 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3301 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3303 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3307 /* include the generated boilerplate */
3308 #include "librpc/gen_ndr/ndr_lsa_s.c"
3312 /*****************************************
3313 NOTE! The remaining calls below were
3314 removed in w2k3, so the DCESRV_FAULT()
3315 replies are the correct implementation. Do
3316 not try and fill these in with anything else
3317 ******************************************/
3320 dssetup_DsRoleDnsNameToFlatName
3322 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3323 struct dssetup_DsRoleDnsNameToFlatName *r)
3325 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3330 dssetup_DsRoleDcAsDc
3332 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3333 struct dssetup_DsRoleDcAsDc *r)
3335 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3340 dssetup_DsRoleDcAsReplica
3342 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3343 struct dssetup_DsRoleDcAsReplica *r)
3345 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3350 dssetup_DsRoleDemoteDc
3352 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3353 struct dssetup_DsRoleDemoteDc *r)
3355 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3360 dssetup_DsRoleGetDcOperationProgress
3362 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3363 struct dssetup_DsRoleGetDcOperationProgress *r)
3365 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3370 dssetup_DsRoleGetDcOperationResults
3372 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3373 struct dssetup_DsRoleGetDcOperationResults *r)
3375 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3380 dssetup_DsRoleCancel
3382 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3383 struct dssetup_DsRoleCancel *r)
3385 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3390 dssetup_DsRoleServerSaveStateForUpgrade
3392 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3393 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3395 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3400 dssetup_DsRoleUpgradeDownlevelServer
3402 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3403 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3405 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3410 dssetup_DsRoleAbortDownlevelServerUpgrade
3412 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3413 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3415 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3419 /* include the generated boilerplate */
3420 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3422 NTSTATUS dcerpc_server_lsa_init(void)
3426 ret = dcerpc_server_dssetup_init();
3427 if (!NT_STATUS_IS_OK(ret)) {
3430 ret = dcerpc_server_lsarpc_init();
3431 if (!NT_STATUS_IS_OK(ret)) {