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);
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_INTERNAL_DB_CORRUPTION;
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;
736 /* This decrypts and returns Trusted Domain Auth Information Internal data */
737 static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
738 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
739 struct trustDomainPasswords *auth_struct)
741 DATA_BLOB session_key = data_blob(NULL, 0);
742 enum ndr_err_code ndr_err;
745 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
746 if (!NT_STATUS_IS_OK(nt_status)) {
750 arcfour_crypt_blob(auth_blob->data, auth_blob->length, &session_key);
751 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
752 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
754 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
755 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
756 return NT_STATUS_INVALID_PARAMETER;
762 static NTSTATUS get_trustauth_inout_blob(struct dcesrv_call_state *dce_call,
764 struct trustCurrentPasswords *iopw,
765 DATA_BLOB *trustauth_blob)
768 struct trustAuthInOutBlob ioblob;
769 enum ndr_err_code ndr_err;
771 ioblob.count = iopw->count;
772 ioblob.current = talloc(mem_ctx,
773 struct AuthenticationInformationArray);
774 if (!ioblob.current) {
775 return NT_STATUS_NO_MEMORY;
778 ioblob.current->array = *iopw->current;
779 if (!ioblob.current->array) {
780 return NT_STATUS_NO_MEMORY;
783 ioblob.previous = talloc(mem_ctx,
784 struct AuthenticationInformationArray);
785 if (!ioblob.previous) {
786 return NT_STATUS_NO_MEMORY;
788 ioblob.previous->array = talloc_array(mem_ctx,
789 struct AuthenticationInformation,
791 if (!ioblob.previous->array) {
792 return NT_STATUS_NO_MEMORY;
795 for (i = 0; i < ioblob.count; i++) {
796 ioblob.previous->array[i].LastUpdateTime = 0;
797 ioblob.previous->array[i].AuthType = 0;
799 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
800 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
802 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
803 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
804 return NT_STATUS_INVALID_PARAMETER;
811 lsa_CreateTrustedDomainEx2
813 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
815 struct lsa_CreateTrustedDomainEx2 *r,
818 struct dcesrv_handle *policy_handle;
819 struct lsa_policy_state *policy_state;
820 struct lsa_trusted_domain_state *trusted_domain_state;
821 struct dcesrv_handle *handle;
822 struct ldb_message **msgs, *msg, *msg_user;
823 const char *attrs[] = {
826 const char *netbios_name;
827 const char *dns_name;
829 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
830 struct trustDomainPasswords auth_struct;
833 struct ldb_context *sam_ldb;
835 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
836 ZERO_STRUCTP(r->out.trustdom_handle);
838 policy_state = policy_handle->data;
839 sam_ldb = policy_state->sam_ldb;
841 netbios_name = r->in.info->netbios_name.string;
843 return NT_STATUS_INVALID_PARAMETER;
846 dns_name = r->in.info->domain_name.string;
848 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
849 if (!trusted_domain_state) {
850 return NT_STATUS_NO_MEMORY;
852 trusted_domain_state->policy = policy_state;
854 if (strcasecmp(netbios_name, "BUILTIN") == 0
855 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
856 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
857 return NT_STATUS_INVALID_PARAMETER;;
860 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
861 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
862 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
863 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
864 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
865 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
868 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
869 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
870 /* No secrets are created at this time, for this function */
871 auth_struct.outgoing.count = 0;
872 auth_struct.incoming.count = 0;
874 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data,
875 r->in.auth_info->auth_blob.size);
876 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
877 &auth_blob, &auth_struct);
878 if (!NT_STATUS_IS_OK(nt_status)) {
882 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
883 if (auth_struct.incoming.count > 1) {
884 return NT_STATUS_INVALID_PARAMETER;
889 if (auth_struct.incoming.count) {
890 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
891 &auth_struct.incoming,
893 if (!NT_STATUS_IS_OK(nt_status)) {
897 trustAuthIncoming = data_blob(NULL, 0);
900 if (auth_struct.outgoing.count) {
901 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
902 &auth_struct.outgoing,
904 if (!NT_STATUS_IS_OK(nt_status)) {
908 trustAuthOutgoing = data_blob(NULL, 0);
911 ret = ldb_transaction_start(sam_ldb);
912 if (ret != LDB_SUCCESS) {
913 return NT_STATUS_INTERNAL_DB_CORRUPTION;
917 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
918 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
919 /* search for the trusted_domain record */
920 ret = gendb_search(sam_ldb,
921 mem_ctx, policy_state->system_dn, &msgs, attrs,
922 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
923 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
925 ldb_transaction_cancel(sam_ldb);
926 return NT_STATUS_OBJECT_NAME_COLLISION;
929 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
930 /* search for the trusted_domain record */
931 ret = gendb_search(sam_ldb,
932 mem_ctx, policy_state->system_dn, &msgs, attrs,
933 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
934 netbios_encoded, netbios_encoded, netbios_encoded);
936 ldb_transaction_cancel(sam_ldb);
937 return NT_STATUS_OBJECT_NAME_COLLISION;
942 ldb_transaction_cancel(sam_ldb);
943 return NT_STATUS_INTERNAL_DB_CORRUPTION;
946 name = dns_name ? dns_name : netbios_name;
948 msg = ldb_msg_new(mem_ctx);
950 return NT_STATUS_NO_MEMORY;
953 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
954 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
955 ldb_transaction_cancel(sam_ldb);
956 return NT_STATUS_NO_MEMORY;
959 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "flatname", netbios_name);
961 if (r->in.info->sid) {
962 ret = samdb_msg_add_dom_sid(sam_ldb, mem_ctx, msg, "securityIdentifier", r->in.info->sid);
963 if (ret != LDB_SUCCESS) {
964 ldb_transaction_cancel(sam_ldb);
965 return NT_STATUS_INVALID_PARAMETER;
969 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
971 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
973 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
975 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
978 samdb_msg_add_string(sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
981 if (trustAuthIncoming.data) {
982 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
983 if (ret != LDB_SUCCESS) {
984 ldb_transaction_cancel(sam_ldb);
985 return NT_STATUS_NO_MEMORY;
988 if (trustAuthOutgoing.data) {
989 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
990 if (ret != LDB_SUCCESS) {
991 ldb_transaction_cancel(sam_ldb);
992 return NT_STATUS_NO_MEMORY;
996 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
998 /* create the trusted_domain */
999 ret = ldb_add(sam_ldb, msg);
1003 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1004 ldb_transaction_cancel(sam_ldb);
1005 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1006 ldb_dn_get_linearized(msg->dn),
1007 ldb_errstring(sam_ldb)));
1008 return NT_STATUS_DOMAIN_EXISTS;
1009 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1010 ldb_transaction_cancel(sam_ldb);
1011 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1012 ldb_dn_get_linearized(msg->dn),
1013 ldb_errstring(sam_ldb)));
1014 return NT_STATUS_ACCESS_DENIED;
1016 ldb_transaction_cancel(sam_ldb);
1017 DEBUG(0,("Failed to create user record %s: %s\n",
1018 ldb_dn_get_linearized(msg->dn),
1019 ldb_errstring(sam_ldb)));
1020 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1023 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1024 msg_user = ldb_msg_new(mem_ctx);
1025 if (msg_user == NULL) {
1026 ldb_transaction_cancel(sam_ldb);
1027 return NT_STATUS_NO_MEMORY;
1030 /* Inbound trusts must also create a cn=users object to match */
1032 trusted_domain_state->trusted_domain_user_dn = msg_user->dn
1033 = ldb_dn_copy(trusted_domain_state, policy_state->domain_dn);
1034 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=users")) {
1035 ldb_transaction_cancel(sam_ldb);
1036 return NT_STATUS_NO_MEMORY;
1039 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=%s", netbios_name)) {
1040 ldb_transaction_cancel(sam_ldb);
1041 return NT_STATUS_NO_MEMORY;
1044 ldb_msg_add_string(msg_user, "objectClass", "user");
1046 ldb_msg_add_steal_string(msg_user, "samAccountName",
1047 talloc_asprintf(mem_ctx, "%s$", netbios_name));
1049 if (samdb_msg_add_uint(sam_ldb, mem_ctx, msg_user,
1050 "userAccountControl",
1051 UF_INTERDOMAIN_TRUST_ACCOUNT) != 0) {
1052 ldb_transaction_cancel(sam_ldb);
1053 return NT_STATUS_NO_MEMORY;
1056 if (auth_struct.incoming.count) {
1058 for (i=0; i < auth_struct.incoming.count; i++ ) {
1059 if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_NT4OWF) {
1060 samdb_msg_add_hash(sam_ldb,
1061 mem_ctx, msg_user, "unicodePwd",
1062 &auth_struct.incoming.current[i]->AuthInfo.nt4owf.password);
1063 } else if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_CLEAR) {
1064 DATA_BLOB new_password = data_blob_const(auth_struct.incoming.current[i]->AuthInfo.clear.password,
1065 auth_struct.incoming.current[i]->AuthInfo.clear.size);
1066 ret = ldb_msg_add_value(msg_user, "clearTextPassword", &new_password, NULL);
1067 if (ret != LDB_SUCCESS) {
1068 ldb_transaction_cancel(sam_ldb);
1069 return NT_STATUS_NO_MEMORY;
1075 /* create the cn=users trusted_domain account */
1076 ret = ldb_add(sam_ldb, msg_user);
1080 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1081 ldb_transaction_cancel(sam_ldb);
1082 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1083 ldb_dn_get_linearized(msg_user->dn),
1084 ldb_errstring(sam_ldb)));
1085 return NT_STATUS_DOMAIN_EXISTS;
1086 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1087 ldb_transaction_cancel(sam_ldb);
1088 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1089 ldb_dn_get_linearized(msg_user->dn),
1090 ldb_errstring(sam_ldb)));
1091 return NT_STATUS_ACCESS_DENIED;
1093 ldb_transaction_cancel(sam_ldb);
1094 DEBUG(0,("Failed to create user record %s: %s\n",
1095 ldb_dn_get_linearized(msg_user->dn),
1096 ldb_errstring(sam_ldb)));
1097 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1101 ret = ldb_transaction_commit(sam_ldb);
1102 if (ret != LDB_SUCCESS) {
1103 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1106 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1108 return NT_STATUS_NO_MEMORY;
1111 handle->data = talloc_steal(handle, trusted_domain_state);
1113 trusted_domain_state->access_mask = r->in.access_mask;
1114 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1116 *r->out.trustdom_handle = handle->wire_handle;
1118 return NT_STATUS_OK;
1122 lsa_CreateTrustedDomainEx2
1124 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1125 TALLOC_CTX *mem_ctx,
1126 struct lsa_CreateTrustedDomainEx2 *r)
1128 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
1131 lsa_CreateTrustedDomainEx
1133 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1134 TALLOC_CTX *mem_ctx,
1135 struct lsa_CreateTrustedDomainEx *r)
1137 struct lsa_CreateTrustedDomainEx2 r2;
1139 r2.in.policy_handle = r->in.policy_handle;
1140 r2.in.info = r->in.info;
1141 r2.in.auth_info = r->in.auth_info;
1142 r2.out.trustdom_handle = r->out.trustdom_handle;
1143 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
1147 lsa_CreateTrustedDomain
1149 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1150 struct lsa_CreateTrustedDomain *r)
1152 struct lsa_CreateTrustedDomainEx2 r2;
1154 r2.in.policy_handle = r->in.policy_handle;
1155 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1157 return NT_STATUS_NO_MEMORY;
1160 r2.in.info->domain_name.string = NULL;
1161 r2.in.info->netbios_name = r->in.info->name;
1162 r2.in.info->sid = r->in.info->sid;
1163 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1164 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1165 r2.in.info->trust_attributes = 0;
1167 r2.in.access_mask = r->in.access_mask;
1168 r2.out.trustdom_handle = r->out.trustdom_handle;
1170 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1175 lsa_OpenTrustedDomain
1177 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1178 struct lsa_OpenTrustedDomain *r)
1180 struct dcesrv_handle *policy_handle;
1182 struct lsa_policy_state *policy_state;
1183 struct lsa_trusted_domain_state *trusted_domain_state;
1184 struct dcesrv_handle *handle;
1185 struct ldb_message **msgs;
1186 const char *attrs[] = {
1192 const char *sid_string;
1195 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1196 ZERO_STRUCTP(r->out.trustdom_handle);
1197 policy_state = policy_handle->data;
1199 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1200 if (!trusted_domain_state) {
1201 return NT_STATUS_NO_MEMORY;
1203 trusted_domain_state->policy = policy_state;
1205 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1207 return NT_STATUS_NO_MEMORY;
1210 /* search for the trusted_domain record */
1211 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1212 mem_ctx, policy_state->system_dn, &msgs, attrs,
1213 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
1216 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1220 DEBUG(0,("Found %d records matching DN %s\n", ret,
1221 ldb_dn_get_linearized(policy_state->system_dn)));
1222 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1225 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1227 trusted_domain_state->trusted_domain_user_dn = NULL;
1229 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1230 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1231 /* search for the trusted_domain record */
1232 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1233 mem_ctx, policy_state->domain_dn, &msgs, attrs,
1234 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%d))",
1235 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1237 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1240 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1242 return NT_STATUS_NO_MEMORY;
1245 handle->data = talloc_steal(handle, trusted_domain_state);
1247 trusted_domain_state->access_mask = r->in.access_mask;
1248 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1250 *r->out.trustdom_handle = handle->wire_handle;
1252 return NT_STATUS_OK;
1257 lsa_OpenTrustedDomainByName
1259 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1260 TALLOC_CTX *mem_ctx,
1261 struct lsa_OpenTrustedDomainByName *r)
1263 struct dcesrv_handle *policy_handle;
1265 struct lsa_policy_state *policy_state;
1266 struct lsa_trusted_domain_state *trusted_domain_state;
1267 struct dcesrv_handle *handle;
1268 struct ldb_message **msgs;
1269 const char *attrs[] = {
1275 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1276 ZERO_STRUCTP(r->out.trustdom_handle);
1277 policy_state = policy_handle->data;
1279 if (!r->in.name.string) {
1280 return NT_STATUS_INVALID_PARAMETER;
1283 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1284 if (!trusted_domain_state) {
1285 return NT_STATUS_NO_MEMORY;
1287 trusted_domain_state->policy = policy_state;
1289 /* search for the trusted_domain record */
1290 td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string);
1291 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1292 mem_ctx, policy_state->system_dn, &msgs, attrs,
1293 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))"
1294 "(objectclass=trustedDomain))",
1295 td_name, td_name, td_name);
1297 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1301 DEBUG(0,("Found %d records matching DN %s\n", ret,
1302 ldb_dn_get_linearized(policy_state->system_dn)));
1303 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1306 /* TODO: perform access checks */
1308 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1310 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1312 return NT_STATUS_NO_MEMORY;
1315 handle->data = talloc_steal(handle, trusted_domain_state);
1317 trusted_domain_state->access_mask = r->in.access_mask;
1318 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1320 *r->out.trustdom_handle = handle->wire_handle;
1322 return NT_STATUS_OK;
1328 lsa_SetTrustedDomainInfo
1330 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1331 struct lsa_SetTrustedDomainInfo *r)
1333 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1339 lsa_SetInfomrationTrustedDomain
1341 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1342 TALLOC_CTX *mem_ctx,
1343 struct lsa_SetInformationTrustedDomain *r)
1345 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1350 lsa_DeleteTrustedDomain
1352 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1353 struct lsa_DeleteTrustedDomain *r)
1356 struct lsa_OpenTrustedDomain opn;
1357 struct lsa_DeleteObject del;
1358 struct dcesrv_handle *h;
1360 opn.in.handle = r->in.handle;
1361 opn.in.sid = r->in.dom_sid;
1362 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1363 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1364 if (!opn.out.trustdom_handle) {
1365 return NT_STATUS_NO_MEMORY;
1367 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1368 if (!NT_STATUS_IS_OK(status)) {
1372 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1373 talloc_steal(mem_ctx, h);
1375 del.in.handle = opn.out.trustdom_handle;
1376 del.out.handle = opn.out.trustdom_handle;
1377 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
1378 if (!NT_STATUS_IS_OK(status)) {
1381 return NT_STATUS_OK;
1384 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1385 struct ldb_message *msg,
1386 struct lsa_TrustDomainInfoInfoEx *info_ex)
1388 info_ex->domain_name.string
1389 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1390 info_ex->netbios_name.string
1391 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1393 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1394 info_ex->trust_direction
1395 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1397 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1398 info_ex->trust_attributes
1399 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1400 return NT_STATUS_OK;
1404 lsa_QueryTrustedDomainInfo
1406 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1407 struct lsa_QueryTrustedDomainInfo *r)
1409 union lsa_TrustedDomainInfo *info = NULL;
1410 struct dcesrv_handle *h;
1411 struct lsa_trusted_domain_state *trusted_domain_state;
1412 struct ldb_message *msg;
1414 struct ldb_message **res;
1415 const char *attrs[] = {
1418 "securityIdentifier",
1422 "msDs-supportedEncryptionTypes",
1426 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1428 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1430 /* pull all the user attributes */
1431 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1432 trusted_domain_state->trusted_domain_dn, &res, attrs);
1434 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1438 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
1440 return NT_STATUS_NO_MEMORY;
1442 *r->out.info = info;
1444 switch (r->in.level) {
1445 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1446 info->name.netbios_name.string
1447 = samdb_result_string(msg, "flatname", NULL);
1449 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1450 info->posix_offset.posix_offset
1451 = samdb_result_uint(msg, "posixOffset", 0);
1453 #if 0 /* Win2k3 doesn't implement this */
1454 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1455 r->out.info->info_basic.netbios_name.string
1456 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1457 r->out.info->info_basic.sid
1458 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1461 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1462 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
1464 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1465 ZERO_STRUCT(info->full_info);
1466 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
1468 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1469 ZERO_STRUCT(info->full_info2_internal);
1470 info->full_info2_internal.posix_offset.posix_offset
1471 = samdb_result_uint(msg, "posixOffset", 0);
1472 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
1474 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1475 info->enc_types.enc_types
1476 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
1479 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1480 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1481 /* oops, we don't want to return the info after all */
1483 *r->out.info = NULL;
1484 return NT_STATUS_INVALID_PARAMETER;
1486 /* oops, we don't want to return the info after all */
1488 *r->out.info = NULL;
1489 return NT_STATUS_INVALID_INFO_CLASS;
1492 return NT_STATUS_OK;
1497 lsa_QueryTrustedDomainInfoBySid
1499 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1500 struct lsa_QueryTrustedDomainInfoBySid *r)
1503 struct lsa_OpenTrustedDomain opn;
1504 struct lsa_QueryTrustedDomainInfo query;
1505 struct dcesrv_handle *h;
1507 opn.in.handle = r->in.handle;
1508 opn.in.sid = r->in.dom_sid;
1509 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1510 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1511 if (!opn.out.trustdom_handle) {
1512 return NT_STATUS_NO_MEMORY;
1514 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1515 if (!NT_STATUS_IS_OK(status)) {
1519 /* Ensure this handle goes away at the end of this call */
1520 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1521 talloc_steal(mem_ctx, h);
1523 query.in.trustdom_handle = opn.out.trustdom_handle;
1524 query.in.level = r->in.level;
1525 query.out.info = r->out.info;
1526 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1527 if (!NT_STATUS_IS_OK(status)) {
1531 return NT_STATUS_OK;
1535 lsa_SetTrustedDomainInfoByName
1537 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1538 TALLOC_CTX *mem_ctx,
1539 struct lsa_SetTrustedDomainInfoByName *r)
1541 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1545 lsa_QueryTrustedDomainInfoByName
1547 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1548 TALLOC_CTX *mem_ctx,
1549 struct lsa_QueryTrustedDomainInfoByName *r)
1552 struct lsa_OpenTrustedDomainByName opn;
1553 struct lsa_QueryTrustedDomainInfo query;
1554 struct dcesrv_handle *h;
1556 opn.in.handle = r->in.handle;
1557 opn.in.name = *r->in.trusted_domain;
1558 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1559 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1560 if (!opn.out.trustdom_handle) {
1561 return NT_STATUS_NO_MEMORY;
1563 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
1564 if (!NT_STATUS_IS_OK(status)) {
1568 /* Ensure this handle goes away at the end of this call */
1569 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1570 talloc_steal(mem_ctx, h);
1572 query.in.trustdom_handle = opn.out.trustdom_handle;
1573 query.in.level = r->in.level;
1574 query.out.info = r->out.info;
1575 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1576 if (!NT_STATUS_IS_OK(status)) {
1580 return NT_STATUS_OK;
1584 lsa_CloseTrustedDomainEx
1586 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1587 TALLOC_CTX *mem_ctx,
1588 struct lsa_CloseTrustedDomainEx *r)
1590 /* The result of a bad hair day from an IDL programmer? Not
1591 * implmented in Win2k3. You should always just lsa_Close
1593 return NT_STATUS_NOT_IMPLEMENTED;
1598 comparison function for sorting lsa_DomainInformation array
1600 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1602 return strcasecmp_m(e1->name.string, e2->name.string);
1608 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1609 struct lsa_EnumTrustDom *r)
1611 struct dcesrv_handle *policy_handle;
1612 struct lsa_DomainInfo *entries;
1613 struct lsa_policy_state *policy_state;
1614 struct ldb_message **domains;
1615 const char *attrs[] = {
1617 "securityIdentifier",
1624 *r->out.resume_handle = 0;
1626 r->out.domains->domains = NULL;
1627 r->out.domains->count = 0;
1629 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1631 policy_state = policy_handle->data;
1633 /* search for all users in this domain. This could possibly be cached and
1634 resumed based on resume_key */
1635 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1636 "objectclass=trustedDomain");
1638 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1641 /* convert to lsa_TrustInformation format */
1642 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1644 return NT_STATUS_NO_MEMORY;
1646 for (i=0;i<count;i++) {
1647 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1648 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1651 /* sort the results by name */
1652 TYPESAFE_QSORT(entries, count, compare_DomainInfo);
1654 if (*r->in.resume_handle >= count) {
1655 *r->out.resume_handle = -1;
1657 return NT_STATUS_NO_MORE_ENTRIES;
1660 /* return the rest, limit by max_size. Note that we
1661 use the w2k3 element size value of 60 */
1662 r->out.domains->count = count - *r->in.resume_handle;
1663 r->out.domains->count = MIN(r->out.domains->count,
1664 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1666 r->out.domains->domains = entries + *r->in.resume_handle;
1667 r->out.domains->count = r->out.domains->count;
1669 if (r->out.domains->count < count - *r->in.resume_handle) {
1670 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1671 return STATUS_MORE_ENTRIES;
1674 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
1675 * always be larger than the previous input resume handle, in
1676 * particular when hitting the last query it is vital to set the
1677 * resume handle correctly to avoid infinite client loops, as
1678 * seen e.g. with Windows XP SP3 when resume handle is 0 and
1679 * status is NT_STATUS_OK - gd */
1681 *r->out.resume_handle = (uint32_t)-1;
1683 return NT_STATUS_OK;
1687 comparison function for sorting lsa_DomainInformation array
1689 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1691 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1695 lsa_EnumTrustedDomainsEx
1697 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1698 struct lsa_EnumTrustedDomainsEx *r)
1700 struct dcesrv_handle *policy_handle;
1701 struct lsa_TrustDomainInfoInfoEx *entries;
1702 struct lsa_policy_state *policy_state;
1703 struct ldb_message **domains;
1704 const char *attrs[] = {
1707 "securityIdentifier",
1717 *r->out.resume_handle = 0;
1719 r->out.domains->domains = NULL;
1720 r->out.domains->count = 0;
1722 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1724 policy_state = policy_handle->data;
1726 /* search for all users in this domain. This could possibly be cached and
1727 resumed based on resume_key */
1728 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1729 "objectclass=trustedDomain");
1731 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1734 /* convert to lsa_DomainInformation format */
1735 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1737 return NT_STATUS_NO_MEMORY;
1739 for (i=0;i<count;i++) {
1740 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1741 if (!NT_STATUS_IS_OK(nt_status)) {
1746 /* sort the results by name */
1747 TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
1749 if (*r->in.resume_handle >= count) {
1750 *r->out.resume_handle = -1;
1752 return NT_STATUS_NO_MORE_ENTRIES;
1755 /* return the rest, limit by max_size. Note that we
1756 use the w2k3 element size value of 60 */
1757 r->out.domains->count = count - *r->in.resume_handle;
1758 r->out.domains->count = MIN(r->out.domains->count,
1759 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1761 r->out.domains->domains = entries + *r->in.resume_handle;
1762 r->out.domains->count = r->out.domains->count;
1764 if (r->out.domains->count < count - *r->in.resume_handle) {
1765 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1766 return STATUS_MORE_ENTRIES;
1769 return NT_STATUS_OK;
1776 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1777 struct lsa_OpenAccount *r)
1779 struct dcesrv_handle *h, *ah;
1780 struct lsa_policy_state *state;
1781 struct lsa_account_state *astate;
1783 ZERO_STRUCTP(r->out.acct_handle);
1785 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1789 astate = talloc(dce_call->conn, struct lsa_account_state);
1790 if (astate == NULL) {
1791 return NT_STATUS_NO_MEMORY;
1794 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1795 if (astate->account_sid == NULL) {
1796 talloc_free(astate);
1797 return NT_STATUS_NO_MEMORY;
1800 astate->policy = talloc_reference(astate, state);
1801 astate->access_mask = r->in.access_mask;
1803 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1805 talloc_free(astate);
1806 return NT_STATUS_NO_MEMORY;
1809 ah->data = talloc_steal(ah, astate);
1811 *r->out.acct_handle = ah->wire_handle;
1813 return NT_STATUS_OK;
1818 lsa_EnumPrivsAccount
1820 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1821 TALLOC_CTX *mem_ctx,
1822 struct lsa_EnumPrivsAccount *r)
1824 struct dcesrv_handle *h;
1825 struct lsa_account_state *astate;
1828 struct ldb_message **res;
1829 const char * const attrs[] = { "privilege", NULL};
1830 struct ldb_message_element *el;
1832 struct lsa_PrivilegeSet *privs;
1834 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1838 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1839 if (privs == NULL) {
1840 return NT_STATUS_NO_MEMORY;
1846 *r->out.privs = privs;
1848 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1849 if (sidstr == NULL) {
1850 return NT_STATUS_NO_MEMORY;
1853 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
1854 "objectSid=%s", sidstr);
1856 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1859 return NT_STATUS_OK;
1862 el = ldb_msg_find_element(res[0], "privilege");
1863 if (el == NULL || el->num_values == 0) {
1864 return NT_STATUS_OK;
1867 privs->set = talloc_array(privs,
1868 struct lsa_LUIDAttribute, el->num_values);
1869 if (privs->set == NULL) {
1870 return NT_STATUS_NO_MEMORY;
1873 for (i=0;i<el->num_values;i++) {
1874 int id = sec_privilege_id((const char *)el->values[i].data);
1876 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1878 privs->set[i].attribute = 0;
1879 privs->set[i].luid.low = id;
1880 privs->set[i].luid.high = 0;
1883 privs->count = el->num_values;
1885 return NT_STATUS_OK;
1889 lsa_EnumAccountRights
1891 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1892 TALLOC_CTX *mem_ctx,
1893 struct lsa_EnumAccountRights *r)
1895 struct dcesrv_handle *h;
1896 struct lsa_policy_state *state;
1899 struct ldb_message **res;
1900 const char * const attrs[] = { "privilege", NULL};
1902 struct ldb_message_element *el;
1904 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1908 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1909 if (sidstr == NULL) {
1910 return NT_STATUS_NO_MEMORY;
1913 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
1914 "(&(objectSid=%s)(privilege=*))", sidstr);
1916 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1919 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1920 dom_sid_string(mem_ctx, r->in.sid),
1921 ldb_errstring(state->pdb)));
1922 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1925 el = ldb_msg_find_element(res[0], "privilege");
1926 if (el == NULL || el->num_values == 0) {
1927 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1930 r->out.rights->count = el->num_values;
1931 r->out.rights->names = talloc_array(r->out.rights,
1932 struct lsa_StringLarge, r->out.rights->count);
1933 if (r->out.rights->names == NULL) {
1934 return NT_STATUS_NO_MEMORY;
1937 for (i=0;i<el->num_values;i++) {
1938 r->out.rights->names[i].string = (const char *)el->values[i].data;
1941 return NT_STATUS_OK;
1947 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1949 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1950 TALLOC_CTX *mem_ctx,
1951 struct lsa_policy_state *state,
1953 struct dom_sid *sid,
1954 const struct lsa_RightSet *rights)
1956 const char *sidstr, *sidndrstr;
1957 struct ldb_message *msg;
1958 struct ldb_message_element *el;
1961 struct lsa_EnumAccountRights r2;
1964 if (security_session_user_level(dce_call->conn->auth_state.session_info) <
1965 SECURITY_ADMINISTRATOR) {
1966 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
1967 return NT_STATUS_ACCESS_DENIED;
1970 msg = ldb_msg_new(mem_ctx);
1972 return NT_STATUS_NO_MEMORY;
1975 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
1976 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg);
1978 sidstr = dom_sid_string(msg, sid);
1979 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg);
1981 dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
1982 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg);
1984 msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
1985 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg);
1987 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1990 r2.in.handle = &state->handle->wire_handle;
1992 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1994 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1995 if (!NT_STATUS_IS_OK(status)) {
1996 ZERO_STRUCTP(r2.out.rights);
2000 for (i=0;i<rights->count;i++) {
2001 if (sec_privilege_id(rights->names[i].string) == -1) {
2003 return NT_STATUS_NO_SUCH_PRIVILEGE;
2006 if (ldb_flag == LDB_FLAG_MOD_ADD) {
2008 for (j=0;j<r2.out.rights->count;j++) {
2009 if (strcasecmp_m(r2.out.rights->names[j].string,
2010 rights->names[i].string) == 0) {
2014 if (j != r2.out.rights->count) continue;
2017 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2018 if (ret != LDB_SUCCESS) {
2020 return NT_STATUS_NO_MEMORY;
2024 el = ldb_msg_find_element(msg, "privilege");
2027 return NT_STATUS_OK;
2030 el->flags = ldb_flag;
2032 ret = ldb_modify(state->pdb, msg);
2033 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
2034 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
2036 return NT_STATUS_NO_MEMORY;
2038 samdb_msg_add_string(state->pdb, msg, msg, "comment", "added via LSA");
2039 ret = ldb_add(state->pdb, msg);
2041 if (ret != LDB_SUCCESS) {
2042 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2044 return NT_STATUS_OK;
2046 DEBUG(3, ("Could not %s attributes from %s: %s",
2047 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2048 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
2050 return NT_STATUS_UNEXPECTED_IO_ERROR;
2054 return NT_STATUS_OK;
2058 lsa_AddPrivilegesToAccount
2060 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2061 struct lsa_AddPrivilegesToAccount *r)
2063 struct lsa_RightSet rights;
2064 struct dcesrv_handle *h;
2065 struct lsa_account_state *astate;
2068 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2072 rights.count = r->in.privs->count;
2073 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2074 if (rights.names == NULL) {
2075 return NT_STATUS_NO_MEMORY;
2077 for (i=0;i<rights.count;i++) {
2078 int id = r->in.privs->set[i].luid.low;
2079 if (r->in.privs->set[i].luid.high) {
2080 return NT_STATUS_NO_SUCH_PRIVILEGE;
2082 rights.names[i].string = sec_privilege_name(id);
2083 if (rights.names[i].string == NULL) {
2084 return NT_STATUS_NO_SUCH_PRIVILEGE;
2088 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2089 LDB_FLAG_MOD_ADD, astate->account_sid,
2095 lsa_RemovePrivilegesFromAccount
2097 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2098 struct lsa_RemovePrivilegesFromAccount *r)
2100 struct lsa_RightSet *rights;
2101 struct dcesrv_handle *h;
2102 struct lsa_account_state *astate;
2105 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2109 rights = talloc(mem_ctx, struct lsa_RightSet);
2111 if (r->in.remove_all == 1 &&
2112 r->in.privs == NULL) {
2113 struct lsa_EnumAccountRights r2;
2116 r2.in.handle = &astate->policy->handle->wire_handle;
2117 r2.in.sid = astate->account_sid;
2118 r2.out.rights = rights;
2120 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2121 if (!NT_STATUS_IS_OK(status)) {
2125 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2126 LDB_FLAG_MOD_DELETE, astate->account_sid,
2130 if (r->in.remove_all != 0) {
2131 return NT_STATUS_INVALID_PARAMETER;
2134 rights->count = r->in.privs->count;
2135 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2136 if (rights->names == NULL) {
2137 return NT_STATUS_NO_MEMORY;
2139 for (i=0;i<rights->count;i++) {
2140 int id = r->in.privs->set[i].luid.low;
2141 if (r->in.privs->set[i].luid.high) {
2142 return NT_STATUS_NO_SUCH_PRIVILEGE;
2144 rights->names[i].string = sec_privilege_name(id);
2145 if (rights->names[i].string == NULL) {
2146 return NT_STATUS_NO_SUCH_PRIVILEGE;
2150 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2151 LDB_FLAG_MOD_DELETE, astate->account_sid,
2157 lsa_GetQuotasForAccount
2159 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2160 struct lsa_GetQuotasForAccount *r)
2162 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2167 lsa_SetQuotasForAccount
2169 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2170 struct lsa_SetQuotasForAccount *r)
2172 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2177 lsa_GetSystemAccessAccount
2179 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2180 struct lsa_GetSystemAccessAccount *r)
2184 struct lsa_EnumPrivsAccount enumPrivs;
2185 struct lsa_PrivilegeSet *privs;
2187 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2189 return NT_STATUS_NO_MEMORY;
2195 enumPrivs.in.handle = r->in.handle;
2196 enumPrivs.out.privs = &privs;
2198 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2199 if (!NT_STATUS_IS_OK(status)) {
2203 *(r->out.access_mask) = 0x00000000;
2205 for (i = 0; i < privs->count; i++) {
2206 int priv = privs->set[i].luid.low;
2209 case SEC_PRIV_INTERACTIVE_LOGON:
2210 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2212 case SEC_PRIV_NETWORK_LOGON:
2213 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2215 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2216 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2221 return NT_STATUS_OK;
2226 lsa_SetSystemAccessAccount
2228 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2229 struct lsa_SetSystemAccessAccount *r)
2231 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2238 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2239 struct lsa_CreateSecret *r)
2241 struct dcesrv_handle *policy_handle;
2242 struct lsa_policy_state *policy_state;
2243 struct lsa_secret_state *secret_state;
2244 struct dcesrv_handle *handle;
2245 struct ldb_message **msgs, *msg;
2246 const char *attrs[] = {
2254 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2255 ZERO_STRUCTP(r->out.sec_handle);
2257 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2259 case SECURITY_SYSTEM:
2260 case SECURITY_ADMINISTRATOR:
2263 /* Users and annonymous are not allowed create secrets */
2264 return NT_STATUS_ACCESS_DENIED;
2267 policy_state = policy_handle->data;
2269 if (!r->in.name.string) {
2270 return NT_STATUS_INVALID_PARAMETER;
2273 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2274 if (!secret_state) {
2275 return NT_STATUS_NO_MEMORY;
2277 secret_state->policy = policy_state;
2279 msg = ldb_msg_new(mem_ctx);
2281 return NT_STATUS_NO_MEMORY;
2284 if (strncmp("G$", r->in.name.string, 2) == 0) {
2286 name = &r->in.name.string[2];
2287 /* 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) */
2288 secret_state->sam_ldb = talloc_reference(secret_state,
2289 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
2290 secret_state->global = true;
2292 if (strlen(name) < 1) {
2293 return NT_STATUS_INVALID_PARAMETER;
2296 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2297 /* search for the secret record */
2298 ret = gendb_search(secret_state->sam_ldb,
2299 mem_ctx, policy_state->system_dn, &msgs, attrs,
2300 "(&(cn=%s)(objectclass=secret))",
2303 return NT_STATUS_OBJECT_NAME_COLLISION;
2307 DEBUG(0,("Failure searching for CN=%s: %s\n",
2308 name2, ldb_errstring(secret_state->sam_ldb)));
2309 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2312 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2313 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2314 return NT_STATUS_NO_MEMORY;
2317 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2320 secret_state->global = false;
2322 name = r->in.name.string;
2323 if (strlen(name) < 1) {
2324 return NT_STATUS_INVALID_PARAMETER;
2327 secret_state->sam_ldb = talloc_reference(secret_state,
2328 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2329 /* search for the secret record */
2330 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2331 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2333 "(&(cn=%s)(objectclass=secret))",
2334 ldb_binary_encode_string(mem_ctx, name));
2336 return NT_STATUS_OBJECT_NAME_COLLISION;
2340 DEBUG(0,("Failure searching for CN=%s: %s\n",
2341 name, ldb_errstring(secret_state->sam_ldb)));
2342 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2345 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2346 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2349 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2351 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2353 /* create the secret */
2354 ret = ldb_add(secret_state->sam_ldb, msg);
2355 if (ret != LDB_SUCCESS) {
2356 DEBUG(0,("Failed to create secret record %s: %s\n",
2357 ldb_dn_get_linearized(msg->dn),
2358 ldb_errstring(secret_state->sam_ldb)));
2359 return NT_STATUS_ACCESS_DENIED;
2362 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2364 return NT_STATUS_NO_MEMORY;
2367 handle->data = talloc_steal(handle, secret_state);
2369 secret_state->access_mask = r->in.access_mask;
2370 secret_state->policy = talloc_reference(secret_state, policy_state);
2372 *r->out.sec_handle = handle->wire_handle;
2374 return NT_STATUS_OK;
2381 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2382 struct lsa_OpenSecret *r)
2384 struct dcesrv_handle *policy_handle;
2386 struct lsa_policy_state *policy_state;
2387 struct lsa_secret_state *secret_state;
2388 struct dcesrv_handle *handle;
2389 struct ldb_message **msgs;
2390 const char *attrs[] = {
2398 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2399 ZERO_STRUCTP(r->out.sec_handle);
2400 policy_state = policy_handle->data;
2402 if (!r->in.name.string) {
2403 return NT_STATUS_INVALID_PARAMETER;
2406 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2408 case SECURITY_SYSTEM:
2409 case SECURITY_ADMINISTRATOR:
2412 /* Users and annonymous are not allowed to access secrets */
2413 return NT_STATUS_ACCESS_DENIED;
2416 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2417 if (!secret_state) {
2418 return NT_STATUS_NO_MEMORY;
2420 secret_state->policy = policy_state;
2422 if (strncmp("G$", r->in.name.string, 2) == 0) {
2423 name = &r->in.name.string[2];
2424 /* 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) */
2425 secret_state->sam_ldb = talloc_reference(secret_state,
2426 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
2427 secret_state->global = true;
2429 if (strlen(name) < 1) {
2430 return NT_STATUS_INVALID_PARAMETER;
2433 /* search for the secret record */
2434 ret = gendb_search(secret_state->sam_ldb,
2435 mem_ctx, policy_state->system_dn, &msgs, attrs,
2436 "(&(cn=%s Secret)(objectclass=secret))",
2437 ldb_binary_encode_string(mem_ctx, name));
2439 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2443 DEBUG(0,("Found %d records matching DN %s\n", ret,
2444 ldb_dn_get_linearized(policy_state->system_dn)));
2445 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2449 secret_state->global = false;
2450 secret_state->sam_ldb = talloc_reference(secret_state,
2451 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2453 name = r->in.name.string;
2454 if (strlen(name) < 1) {
2455 return NT_STATUS_INVALID_PARAMETER;
2458 /* search for the secret record */
2459 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2460 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2462 "(&(cn=%s)(objectclass=secret))",
2463 ldb_binary_encode_string(mem_ctx, name));
2465 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2469 DEBUG(0,("Found %d records matching CN=%s\n",
2470 ret, ldb_binary_encode_string(mem_ctx, name)));
2471 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2475 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2477 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2479 return NT_STATUS_NO_MEMORY;
2482 handle->data = talloc_steal(handle, secret_state);
2484 secret_state->access_mask = r->in.access_mask;
2485 secret_state->policy = talloc_reference(secret_state, policy_state);
2487 *r->out.sec_handle = handle->wire_handle;
2489 return NT_STATUS_OK;
2496 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2497 struct lsa_SetSecret *r)
2500 struct dcesrv_handle *h;
2501 struct lsa_secret_state *secret_state;
2502 struct ldb_message *msg;
2503 DATA_BLOB session_key;
2504 DATA_BLOB crypt_secret, secret;
2507 NTSTATUS status = NT_STATUS_OK;
2509 struct timeval now = timeval_current();
2510 NTTIME nt_now = timeval_to_nttime(&now);
2512 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2514 secret_state = h->data;
2516 msg = ldb_msg_new(mem_ctx);
2518 return NT_STATUS_NO_MEMORY;
2521 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2523 return NT_STATUS_NO_MEMORY;
2525 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2526 if (!NT_STATUS_IS_OK(status)) {
2530 if (r->in.old_val) {
2532 crypt_secret.data = r->in.old_val->data;
2533 crypt_secret.length = r->in.old_val->size;
2535 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2536 if (!NT_STATUS_IS_OK(status)) {
2540 val.data = secret.data;
2541 val.length = secret.length;
2544 if (samdb_msg_add_value(secret_state->sam_ldb,
2545 mem_ctx, msg, "priorValue", &val) != LDB_SUCCESS) {
2546 return NT_STATUS_NO_MEMORY;
2549 /* set old value mtime */
2550 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2551 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
2552 return NT_STATUS_NO_MEMORY;
2556 /* If the old value is not set, then migrate the
2557 * current value to the old value */
2558 const struct ldb_val *old_val;
2559 NTTIME last_set_time;
2560 struct ldb_message **res;
2561 const char *attrs[] = {
2567 /* search for the secret record */
2568 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2569 secret_state->secret_dn, &res, attrs);
2571 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2575 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2576 ldb_dn_get_linearized(secret_state->secret_dn)));
2577 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2580 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2581 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2585 if (samdb_msg_add_value(secret_state->sam_ldb,
2586 mem_ctx, msg, "priorValue",
2588 return NT_STATUS_NO_MEMORY;
2591 if (samdb_msg_add_delete(secret_state->sam_ldb,
2592 mem_ctx, msg, "priorValue")) {
2593 return NT_STATUS_NO_MEMORY;
2598 /* set old value mtime */
2599 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2600 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2601 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
2602 return NT_STATUS_NO_MEMORY;
2605 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2606 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
2607 return NT_STATUS_NO_MEMORY;
2612 if (r->in.new_val) {
2614 crypt_secret.data = r->in.new_val->data;
2615 crypt_secret.length = r->in.new_val->size;
2617 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2618 if (!NT_STATUS_IS_OK(status)) {
2622 val.data = secret.data;
2623 val.length = secret.length;
2626 if (samdb_msg_add_value(secret_state->sam_ldb,
2627 mem_ctx, msg, "currentValue", &val) != LDB_SUCCESS) {
2628 return NT_STATUS_NO_MEMORY;
2631 /* set new value mtime */
2632 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2633 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
2634 return NT_STATUS_NO_MEMORY;
2638 /* NULL out the NEW value */
2639 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2640 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
2641 return NT_STATUS_NO_MEMORY;
2643 if (samdb_msg_add_delete(secret_state->sam_ldb,
2644 mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
2645 return NT_STATUS_NO_MEMORY;
2649 /* modify the samdb record */
2650 ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
2651 if (ret != LDB_SUCCESS) {
2652 /* we really need samdb.c to return NTSTATUS */
2653 return NT_STATUS_UNSUCCESSFUL;
2656 return NT_STATUS_OK;
2663 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2664 struct lsa_QuerySecret *r)
2666 struct dcesrv_handle *h;
2667 struct lsa_secret_state *secret_state;
2668 struct ldb_message *msg;
2669 DATA_BLOB session_key;
2670 DATA_BLOB crypt_secret, secret;
2672 struct ldb_message **res;
2673 const char *attrs[] = {
2683 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2685 /* Ensure user is permitted to read this... */
2686 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2688 case SECURITY_SYSTEM:
2689 case SECURITY_ADMINISTRATOR:
2692 /* Users and annonymous are not allowed to read secrets */
2693 return NT_STATUS_ACCESS_DENIED;
2696 secret_state = h->data;
2698 /* pull all the user attributes */
2699 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2700 secret_state->secret_dn, &res, attrs);
2702 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2706 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2707 if (!NT_STATUS_IS_OK(nt_status)) {
2711 if (r->in.old_val) {
2712 const struct ldb_val *prior_val;
2713 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2714 if (!r->out.old_val) {
2715 return NT_STATUS_NO_MEMORY;
2717 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2719 if (prior_val && prior_val->length) {
2720 secret.data = prior_val->data;
2721 secret.length = prior_val->length;
2724 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2725 if (!crypt_secret.length) {
2726 return NT_STATUS_NO_MEMORY;
2728 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2729 if (!r->out.old_val->buf) {
2730 return NT_STATUS_NO_MEMORY;
2732 r->out.old_val->buf->size = crypt_secret.length;
2733 r->out.old_val->buf->length = crypt_secret.length;
2734 r->out.old_val->buf->data = crypt_secret.data;
2738 if (r->in.old_mtime) {
2739 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2740 if (!r->out.old_mtime) {
2741 return NT_STATUS_NO_MEMORY;
2743 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2746 if (r->in.new_val) {
2747 const struct ldb_val *new_val;
2748 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2749 if (!r->out.new_val) {
2750 return NT_STATUS_NO_MEMORY;
2753 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2755 if (new_val && new_val->length) {
2756 secret.data = new_val->data;
2757 secret.length = new_val->length;
2760 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2761 if (!crypt_secret.length) {
2762 return NT_STATUS_NO_MEMORY;
2764 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2765 if (!r->out.new_val->buf) {
2766 return NT_STATUS_NO_MEMORY;
2768 r->out.new_val->buf->length = crypt_secret.length;
2769 r->out.new_val->buf->size = crypt_secret.length;
2770 r->out.new_val->buf->data = crypt_secret.data;
2774 if (r->in.new_mtime) {
2775 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2776 if (!r->out.new_mtime) {
2777 return NT_STATUS_NO_MEMORY;
2779 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2782 return NT_STATUS_OK;
2789 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2790 TALLOC_CTX *mem_ctx,
2791 struct lsa_LookupPrivValue *r)
2793 struct dcesrv_handle *h;
2794 struct lsa_policy_state *state;
2797 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2801 id = sec_privilege_id(r->in.name->string);
2803 return NT_STATUS_NO_SUCH_PRIVILEGE;
2806 r->out.luid->low = id;
2807 r->out.luid->high = 0;
2809 return NT_STATUS_OK;
2816 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2817 TALLOC_CTX *mem_ctx,
2818 struct lsa_LookupPrivName *r)
2820 struct dcesrv_handle *h;
2821 struct lsa_policy_state *state;
2822 struct lsa_StringLarge *name;
2823 const char *privname;
2825 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2829 if (r->in.luid->high != 0) {
2830 return NT_STATUS_NO_SUCH_PRIVILEGE;
2833 privname = sec_privilege_name(r->in.luid->low);
2834 if (privname == NULL) {
2835 return NT_STATUS_NO_SUCH_PRIVILEGE;
2838 name = talloc(mem_ctx, struct lsa_StringLarge);
2840 return NT_STATUS_NO_MEMORY;
2843 name->string = privname;
2845 *r->out.name = name;
2847 return NT_STATUS_OK;
2852 lsa_LookupPrivDisplayName
2854 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2855 TALLOC_CTX *mem_ctx,
2856 struct lsa_LookupPrivDisplayName *r)
2858 struct dcesrv_handle *h;
2859 struct lsa_policy_state *state;
2860 struct lsa_StringLarge *disp_name = NULL;
2863 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2867 id = sec_privilege_id(r->in.name->string);
2869 return NT_STATUS_NO_SUCH_PRIVILEGE;
2872 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2873 if (disp_name == NULL) {
2874 return NT_STATUS_NO_MEMORY;
2877 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
2878 if (disp_name->string == NULL) {
2879 return NT_STATUS_INTERNAL_ERROR;
2882 *r->out.disp_name = disp_name;
2883 *r->out.returned_language_id = 0;
2885 return NT_STATUS_OK;
2890 lsa_EnumAccountsWithUserRight
2892 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2893 TALLOC_CTX *mem_ctx,
2894 struct lsa_EnumAccountsWithUserRight *r)
2896 struct dcesrv_handle *h;
2897 struct lsa_policy_state *state;
2899 struct ldb_message **res;
2900 const char * const attrs[] = { "objectSid", NULL};
2901 const char *privname;
2903 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2907 if (r->in.name == NULL) {
2908 return NT_STATUS_NO_SUCH_PRIVILEGE;
2911 privname = r->in.name->string;
2912 if (sec_privilege_id(privname) == -1) {
2913 return NT_STATUS_NO_SUCH_PRIVILEGE;
2916 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2917 "privilege=%s", privname);
2919 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2922 return NT_STATUS_NO_MORE_ENTRIES;
2925 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2926 if (r->out.sids->sids == NULL) {
2927 return NT_STATUS_NO_MEMORY;
2929 for (i=0;i<ret;i++) {
2930 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2931 res[i], "objectSid");
2932 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2934 r->out.sids->num_sids = ret;
2936 return NT_STATUS_OK;
2941 lsa_AddAccountRights
2943 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2944 TALLOC_CTX *mem_ctx,
2945 struct lsa_AddAccountRights *r)
2947 struct dcesrv_handle *h;
2948 struct lsa_policy_state *state;
2950 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2954 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2956 r->in.sid, r->in.rights);
2961 lsa_RemoveAccountRights
2963 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2964 TALLOC_CTX *mem_ctx,
2965 struct lsa_RemoveAccountRights *r)
2967 struct dcesrv_handle *h;
2968 struct lsa_policy_state *state;
2970 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2974 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2975 LDB_FLAG_MOD_DELETE,
2976 r->in.sid, r->in.rights);
2981 lsa_StorePrivateData
2983 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2984 struct lsa_StorePrivateData *r)
2986 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2991 lsa_RetrievePrivateData
2993 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2994 struct lsa_RetrievePrivateData *r)
2996 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3003 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3004 struct lsa_GetUserName *r)
3006 NTSTATUS status = NT_STATUS_OK;
3007 const char *account_name;
3008 const char *authority_name;
3009 struct lsa_String *_account_name;
3010 struct lsa_String *_authority_name = NULL;
3012 /* this is what w2k3 does */
3013 r->out.account_name = r->in.account_name;
3014 r->out.authority_name = r->in.authority_name;
3016 if (r->in.account_name
3017 && *r->in.account_name
3018 /* && *(*r->in.account_name)->string */
3020 return NT_STATUS_INVALID_PARAMETER;
3023 if (r->in.authority_name
3024 && *r->in.authority_name
3025 /* && *(*r->in.authority_name)->string */
3027 return NT_STATUS_INVALID_PARAMETER;
3030 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
3031 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
3033 _account_name = talloc(mem_ctx, struct lsa_String);
3034 NT_STATUS_HAVE_NO_MEMORY(_account_name);
3035 _account_name->string = account_name;
3037 if (r->in.authority_name) {
3038 _authority_name = talloc(mem_ctx, struct lsa_String);
3039 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
3040 _authority_name->string = authority_name;
3043 *r->out.account_name = _account_name;
3044 if (r->out.authority_name) {
3045 *r->out.authority_name = _authority_name;
3054 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
3055 TALLOC_CTX *mem_ctx,
3056 struct lsa_SetInfoPolicy2 *r)
3058 /* need to support these */
3059 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3063 lsa_QueryDomainInformationPolicy
3065 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3066 TALLOC_CTX *mem_ctx,
3067 struct lsa_QueryDomainInformationPolicy *r)
3069 union lsa_DomainInformationPolicy *info;
3071 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
3073 return NT_STATUS_NO_MEMORY;
3076 switch (r->in.level) {
3077 case LSA_DOMAIN_INFO_POLICY_EFS:
3079 *r->out.info = NULL;
3080 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3081 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
3083 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
3084 struct smb_krb5_context *smb_krb5_context;
3085 int ret = smb_krb5_init_context(mem_ctx,
3086 dce_call->event_ctx,
3087 dce_call->conn->dce_ctx->lp_ctx,
3091 *r->out.info = NULL;
3092 return NT_STATUS_INTERNAL_ERROR;
3094 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
3095 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3096 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3097 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
3098 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
3099 talloc_free(smb_krb5_context);
3100 *r->out.info = info;
3101 return NT_STATUS_OK;
3105 *r->out.info = NULL;
3106 return NT_STATUS_INVALID_INFO_CLASS;
3111 lsa_SetDomInfoPolicy
3113 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3114 TALLOC_CTX *mem_ctx,
3115 struct lsa_SetDomainInformationPolicy *r)
3117 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3123 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3124 TALLOC_CTX *mem_ctx,
3125 struct lsa_TestCall *r)
3127 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3133 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3134 struct lsa_CREDRWRITE *r)
3136 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3143 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3144 struct lsa_CREDRREAD *r)
3146 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3153 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3154 struct lsa_CREDRENUMERATE *r)
3156 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3161 lsa_CREDRWRITEDOMAINCREDENTIALS
3163 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3164 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3166 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3171 lsa_CREDRREADDOMAINCREDENTIALS
3173 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3174 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3176 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3183 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3184 struct lsa_CREDRDELETE *r)
3186 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3191 lsa_CREDRGETTARGETINFO
3193 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3194 struct lsa_CREDRGETTARGETINFO *r)
3196 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3201 lsa_CREDRPROFILELOADED
3203 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3204 struct lsa_CREDRPROFILELOADED *r)
3206 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3211 lsa_CREDRGETSESSIONTYPES
3213 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3214 struct lsa_CREDRGETSESSIONTYPES *r)
3216 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3221 lsa_LSARREGISTERAUDITEVENT
3223 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3224 struct lsa_LSARREGISTERAUDITEVENT *r)
3226 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3231 lsa_LSARGENAUDITEVENT
3233 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3234 struct lsa_LSARGENAUDITEVENT *r)
3236 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3241 lsa_LSARUNREGISTERAUDITEVENT
3243 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3244 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3246 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3251 lsa_lsaRQueryForestTrustInformation
3253 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3254 struct lsa_lsaRQueryForestTrustInformation *r)
3256 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3261 lsa_lsaRSetForestTrustInformation
3263 static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3264 struct lsa_lsaRSetForestTrustInformation *r)
3266 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3273 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3274 struct lsa_CREDRRENAME *r)
3276 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3282 lsa_LSAROPENPOLICYSCE
3284 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3285 struct lsa_LSAROPENPOLICYSCE *r)
3287 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3292 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3294 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3295 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3297 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3302 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3304 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3305 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3307 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3312 lsa_LSARADTREPORTSECURITYEVENT
3314 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3315 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3317 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3321 /* include the generated boilerplate */
3322 #include "librpc/gen_ndr/ndr_lsa_s.c"
3326 /*****************************************
3327 NOTE! The remaining calls below were
3328 removed in w2k3, so the DCESRV_FAULT()
3329 replies are the correct implementation. Do
3330 not try and fill these in with anything else
3331 ******************************************/
3334 dssetup_DsRoleDnsNameToFlatName
3336 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3337 struct dssetup_DsRoleDnsNameToFlatName *r)
3339 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3344 dssetup_DsRoleDcAsDc
3346 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3347 struct dssetup_DsRoleDcAsDc *r)
3349 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3354 dssetup_DsRoleDcAsReplica
3356 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3357 struct dssetup_DsRoleDcAsReplica *r)
3359 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3364 dssetup_DsRoleDemoteDc
3366 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3367 struct dssetup_DsRoleDemoteDc *r)
3369 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3374 dssetup_DsRoleGetDcOperationProgress
3376 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3377 struct dssetup_DsRoleGetDcOperationProgress *r)
3379 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3384 dssetup_DsRoleGetDcOperationResults
3386 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3387 struct dssetup_DsRoleGetDcOperationResults *r)
3389 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3394 dssetup_DsRoleCancel
3396 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3397 struct dssetup_DsRoleCancel *r)
3399 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3404 dssetup_DsRoleServerSaveStateForUpgrade
3406 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3407 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3409 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3414 dssetup_DsRoleUpgradeDownlevelServer
3416 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3417 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3419 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3424 dssetup_DsRoleAbortDownlevelServerUpgrade
3426 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3427 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3429 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3433 /* include the generated boilerplate */
3434 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3436 NTSTATUS dcerpc_server_lsa_init(void)
3440 ret = dcerpc_server_dssetup_init();
3441 if (!NT_STATUS_IS_OK(ret)) {
3444 ret = dcerpc_server_lsarpc_init();
3445 if (!NT_STATUS_IS_OK(ret)) {