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_NO_SUCH_USER;
703 if (*r->in.resume_handle >= ret) {
704 return NT_STATUS_NO_MORE_ENTRIES;
707 count = ret - *r->in.resume_handle;
708 if (count > r->in.num_entries) {
709 count = r->in.num_entries;
713 return NT_STATUS_NO_MORE_ENTRIES;
716 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
717 if (r->out.sids->sids == NULL) {
718 return NT_STATUS_NO_MEMORY;
721 for (i=0;i<count;i++) {
722 r->out.sids->sids[i].sid =
723 samdb_result_dom_sid(r->out.sids->sids,
724 res[i + *r->in.resume_handle],
726 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
729 r->out.sids->num_sids = count;
730 *r->out.resume_handle = count + *r->in.resume_handle;
738 lsa_CreateTrustedDomainEx2
740 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
742 struct lsa_CreateTrustedDomainEx2 *r,
745 struct dcesrv_handle *policy_handle;
746 struct lsa_policy_state *policy_state;
747 struct lsa_trusted_domain_state *trusted_domain_state;
748 struct dcesrv_handle *handle;
749 struct ldb_message **msgs, *msg, *msg_user;
750 const char *attrs[] = {
753 const char *netbios_name;
754 const char *dns_name;
756 DATA_BLOB session_key = data_blob(NULL, 0);
757 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
758 struct trustDomainPasswords auth_struct;
761 enum ndr_err_code ndr_err;
763 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
764 ZERO_STRUCTP(r->out.trustdom_handle);
766 policy_state = policy_handle->data;
768 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
769 if (!NT_STATUS_IS_OK(nt_status)) {
773 netbios_name = r->in.info->netbios_name.string;
775 return NT_STATUS_INVALID_PARAMETER;
778 dns_name = r->in.info->domain_name.string;
780 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
781 if (!trusted_domain_state) {
782 return NT_STATUS_NO_MEMORY;
784 trusted_domain_state->policy = policy_state;
786 if (strcasecmp(netbios_name, "BUILTIN") == 0
787 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
788 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
789 return NT_STATUS_INVALID_PARAMETER;;
792 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
793 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
794 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
795 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
796 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
797 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
800 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
801 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
802 /* No secrets are created at this time, for this function */
803 auth_struct.outgoing.count = 0;
804 auth_struct.incoming.count = 0;
806 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data, r->in.auth_info->auth_blob.size);
807 arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key);
808 ndr_err = ndr_pull_struct_blob(&auth_blob, mem_ctx,
809 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
811 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
812 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
813 return NT_STATUS_INVALID_PARAMETER;
816 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
817 if (auth_struct.incoming.count > 1) {
818 return NT_STATUS_INVALID_PARAMETER;
823 if (auth_struct.incoming.count) {
825 struct trustAuthInOutBlob incoming;
827 incoming.count = auth_struct.incoming.count;
828 incoming.current = talloc(mem_ctx, struct AuthenticationInformationArray);
829 if (!incoming.current) {
830 return NT_STATUS_NO_MEMORY;
833 incoming.current->array = *auth_struct.incoming.current;
834 if (!incoming.current->array) {
835 return NT_STATUS_NO_MEMORY;
838 incoming.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
839 if (!incoming.previous) {
840 return NT_STATUS_NO_MEMORY;
842 incoming.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, incoming.count);
843 if (!incoming.previous->array) {
844 return NT_STATUS_NO_MEMORY;
847 for (i = 0; i < incoming.count; i++) {
848 incoming.previous->array[i].LastUpdateTime = 0;
849 incoming.previous->array[i].AuthType = 0;
851 ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx,
852 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
854 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
855 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
856 return NT_STATUS_INVALID_PARAMETER;
859 trustAuthIncoming = data_blob(NULL, 0);
862 if (auth_struct.outgoing.count) {
864 struct trustAuthInOutBlob outgoing;
866 outgoing.count = auth_struct.outgoing.count;
867 outgoing.current = talloc(mem_ctx, struct AuthenticationInformationArray);
868 if (!outgoing.current) {
869 return NT_STATUS_NO_MEMORY;
872 outgoing.current->array = *auth_struct.outgoing.current;
873 if (!outgoing.current->array) {
874 return NT_STATUS_NO_MEMORY;
877 outgoing.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
878 if (!outgoing.previous) {
879 return NT_STATUS_NO_MEMORY;
881 outgoing.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, outgoing.count);
882 if (!outgoing.previous->array) {
883 return NT_STATUS_NO_MEMORY;
886 for (i = 0; i < outgoing.count; i++) {
887 outgoing.previous->array[i].LastUpdateTime = 0;
888 outgoing.previous->array[i].AuthType = 0;
890 ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx,
891 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
893 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
894 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
895 return NT_STATUS_INVALID_PARAMETER;
898 trustAuthOutgoing = data_blob(NULL, 0);
901 ret = ldb_transaction_start(policy_state->sam_ldb);
902 if (ret != LDB_SUCCESS) {
903 return NT_STATUS_INTERNAL_DB_CORRUPTION;
907 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
908 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
909 /* search for the trusted_domain record */
910 ret = gendb_search(policy_state->sam_ldb,
911 mem_ctx, policy_state->system_dn, &msgs, attrs,
912 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
913 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
915 ldb_transaction_cancel(policy_state->sam_ldb);
916 return NT_STATUS_OBJECT_NAME_COLLISION;
919 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
920 /* search for the trusted_domain record */
921 ret = gendb_search(policy_state->sam_ldb,
922 mem_ctx, policy_state->system_dn, &msgs, attrs,
923 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
924 netbios_encoded, netbios_encoded, netbios_encoded);
926 ldb_transaction_cancel(policy_state->sam_ldb);
927 return NT_STATUS_OBJECT_NAME_COLLISION;
932 ldb_transaction_cancel(policy_state->sam_ldb);
933 return NT_STATUS_INTERNAL_DB_CORRUPTION;
936 name = dns_name ? dns_name : netbios_name;
938 msg = ldb_msg_new(mem_ctx);
940 return NT_STATUS_NO_MEMORY;
943 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
944 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
945 ldb_transaction_cancel(policy_state->sam_ldb);
946 return NT_STATUS_NO_MEMORY;
949 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", netbios_name);
951 if (r->in.info->sid) {
952 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
954 ldb_transaction_cancel(policy_state->sam_ldb);
955 return NT_STATUS_NO_MEMORY;
958 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
961 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
963 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
965 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
967 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
970 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
973 if (trustAuthIncoming.data) {
974 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
975 if (ret != LDB_SUCCESS) {
976 ldb_transaction_cancel(policy_state->sam_ldb);
977 return NT_STATUS_NO_MEMORY;
980 if (trustAuthOutgoing.data) {
981 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
982 if (ret != LDB_SUCCESS) {
983 ldb_transaction_cancel(policy_state->sam_ldb);
984 return NT_STATUS_NO_MEMORY;
988 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
990 /* create the trusted_domain */
991 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
995 case LDB_ERR_ENTRY_ALREADY_EXISTS:
996 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
997 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
998 ldb_dn_get_linearized(msg->dn),
999 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1000 return NT_STATUS_DOMAIN_EXISTS;
1001 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1002 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1003 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1004 ldb_dn_get_linearized(msg->dn),
1005 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1006 return NT_STATUS_ACCESS_DENIED;
1008 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1009 DEBUG(0,("Failed to create user record %s: %s\n",
1010 ldb_dn_get_linearized(msg->dn),
1011 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1012 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1015 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1016 msg_user = ldb_msg_new(mem_ctx);
1017 if (msg_user == NULL) {
1018 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1019 return NT_STATUS_NO_MEMORY;
1022 /* Inbound trusts must also create a cn=users object to match */
1024 trusted_domain_state->trusted_domain_user_dn = msg_user->dn
1025 = ldb_dn_copy(trusted_domain_state, policy_state->domain_dn);
1026 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=users")) {
1027 ldb_transaction_cancel(policy_state->sam_ldb);
1028 return NT_STATUS_NO_MEMORY;
1031 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=%s", netbios_name)) {
1032 ldb_transaction_cancel(policy_state->sam_ldb);
1033 return NT_STATUS_NO_MEMORY;
1036 ldb_msg_add_string(msg_user, "objectClass", "user");
1038 ldb_msg_add_steal_string(msg_user, "samAccountName",
1039 talloc_asprintf(mem_ctx, "%s$", netbios_name));
1041 if (samdb_msg_add_uint(trusted_domain_state->policy->sam_ldb, mem_ctx, msg_user,
1042 "userAccountControl",
1043 UF_INTERDOMAIN_TRUST_ACCOUNT) != 0) {
1044 ldb_transaction_cancel(policy_state->sam_ldb);
1045 return NT_STATUS_NO_MEMORY;
1048 if (auth_struct.incoming.count) {
1050 for (i=0; i < auth_struct.incoming.count; i++ ) {
1051 if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_NT4OWF) {
1052 samdb_msg_add_hash(trusted_domain_state->policy->sam_ldb,
1053 mem_ctx, msg_user, "unicodePwd",
1054 &auth_struct.incoming.current[i]->AuthInfo.nt4owf.password);
1055 } else if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_CLEAR) {
1056 DATA_BLOB new_password = data_blob_const(auth_struct.incoming.current[i]->AuthInfo.clear.password,
1057 auth_struct.incoming.current[i]->AuthInfo.clear.size);
1058 ret = ldb_msg_add_value(msg_user, "clearTextPassword", &new_password, NULL);
1059 if (ret != LDB_SUCCESS) {
1060 ldb_transaction_cancel(policy_state->sam_ldb);
1061 return NT_STATUS_NO_MEMORY;
1067 /* create the cn=users trusted_domain account */
1068 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg_user);
1072 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1073 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1074 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1075 ldb_dn_get_linearized(msg_user->dn),
1076 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1077 return NT_STATUS_DOMAIN_EXISTS;
1078 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1079 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1080 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1081 ldb_dn_get_linearized(msg_user->dn),
1082 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1083 return NT_STATUS_ACCESS_DENIED;
1085 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1086 DEBUG(0,("Failed to create user record %s: %s\n",
1087 ldb_dn_get_linearized(msg_user->dn),
1088 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1089 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1093 ret = ldb_transaction_commit(policy_state->sam_ldb);
1094 if (ret != LDB_SUCCESS) {
1095 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1098 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1100 return NT_STATUS_NO_MEMORY;
1103 handle->data = talloc_steal(handle, trusted_domain_state);
1105 trusted_domain_state->access_mask = r->in.access_mask;
1106 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1108 *r->out.trustdom_handle = handle->wire_handle;
1110 return NT_STATUS_OK;
1114 lsa_CreateTrustedDomainEx2
1116 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1117 TALLOC_CTX *mem_ctx,
1118 struct lsa_CreateTrustedDomainEx2 *r)
1120 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
1123 lsa_CreateTrustedDomainEx
1125 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1126 TALLOC_CTX *mem_ctx,
1127 struct lsa_CreateTrustedDomainEx *r)
1129 struct lsa_CreateTrustedDomainEx2 r2;
1131 r2.in.policy_handle = r->in.policy_handle;
1132 r2.in.info = r->in.info;
1133 r2.in.auth_info = r->in.auth_info;
1134 r2.out.trustdom_handle = r->out.trustdom_handle;
1135 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
1139 lsa_CreateTrustedDomain
1141 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1142 struct lsa_CreateTrustedDomain *r)
1144 struct lsa_CreateTrustedDomainEx2 r2;
1146 r2.in.policy_handle = r->in.policy_handle;
1147 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1149 return NT_STATUS_NO_MEMORY;
1152 r2.in.info->domain_name.string = NULL;
1153 r2.in.info->netbios_name = r->in.info->name;
1154 r2.in.info->sid = r->in.info->sid;
1155 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1156 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1157 r2.in.info->trust_attributes = 0;
1159 r2.in.access_mask = r->in.access_mask;
1160 r2.out.trustdom_handle = r->out.trustdom_handle;
1162 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1167 lsa_OpenTrustedDomain
1169 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1170 struct lsa_OpenTrustedDomain *r)
1172 struct dcesrv_handle *policy_handle;
1174 struct lsa_policy_state *policy_state;
1175 struct lsa_trusted_domain_state *trusted_domain_state;
1176 struct dcesrv_handle *handle;
1177 struct ldb_message **msgs;
1178 const char *attrs[] = {
1184 const char *sid_string;
1187 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1188 ZERO_STRUCTP(r->out.trustdom_handle);
1189 policy_state = policy_handle->data;
1191 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1192 if (!trusted_domain_state) {
1193 return NT_STATUS_NO_MEMORY;
1195 trusted_domain_state->policy = policy_state;
1197 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1199 return NT_STATUS_NO_MEMORY;
1202 /* search for the trusted_domain record */
1203 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1204 mem_ctx, policy_state->system_dn, &msgs, attrs,
1205 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
1208 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1212 DEBUG(0,("Found %d records matching DN %s\n", ret,
1213 ldb_dn_get_linearized(policy_state->system_dn)));
1214 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1217 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1219 trusted_domain_state->trusted_domain_user_dn = NULL;
1221 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1222 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1223 /* search for the trusted_domain record */
1224 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1225 mem_ctx, policy_state->domain_dn, &msgs, attrs,
1226 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%d))",
1227 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1229 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1232 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1234 return NT_STATUS_NO_MEMORY;
1237 handle->data = talloc_steal(handle, trusted_domain_state);
1239 trusted_domain_state->access_mask = r->in.access_mask;
1240 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1242 *r->out.trustdom_handle = handle->wire_handle;
1244 return NT_STATUS_OK;
1249 lsa_OpenTrustedDomainByName
1251 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1252 TALLOC_CTX *mem_ctx,
1253 struct lsa_OpenTrustedDomainByName *r)
1255 struct dcesrv_handle *policy_handle;
1257 struct lsa_policy_state *policy_state;
1258 struct lsa_trusted_domain_state *trusted_domain_state;
1259 struct dcesrv_handle *handle;
1260 struct ldb_message **msgs;
1261 const char *attrs[] = {
1267 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1268 ZERO_STRUCTP(r->out.trustdom_handle);
1269 policy_state = policy_handle->data;
1271 if (!r->in.name.string) {
1272 return NT_STATUS_INVALID_PARAMETER;
1275 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1276 if (!trusted_domain_state) {
1277 return NT_STATUS_NO_MEMORY;
1279 trusted_domain_state->policy = policy_state;
1281 /* search for the trusted_domain record */
1282 td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string);
1283 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1284 mem_ctx, policy_state->system_dn, &msgs, attrs,
1285 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))"
1286 "(objectclass=trustedDomain))",
1287 td_name, td_name, td_name);
1289 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1293 DEBUG(0,("Found %d records matching DN %s\n", ret,
1294 ldb_dn_get_linearized(policy_state->system_dn)));
1295 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1298 /* TODO: perform access checks */
1300 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1302 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1304 return NT_STATUS_NO_MEMORY;
1307 handle->data = talloc_steal(handle, trusted_domain_state);
1309 trusted_domain_state->access_mask = r->in.access_mask;
1310 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1312 *r->out.trustdom_handle = handle->wire_handle;
1314 return NT_STATUS_OK;
1320 lsa_SetTrustedDomainInfo
1322 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1323 struct lsa_SetTrustedDomainInfo *r)
1325 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1331 lsa_SetInfomrationTrustedDomain
1333 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1334 TALLOC_CTX *mem_ctx,
1335 struct lsa_SetInformationTrustedDomain *r)
1337 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1342 lsa_DeleteTrustedDomain
1344 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1345 struct lsa_DeleteTrustedDomain *r)
1348 struct lsa_OpenTrustedDomain opn;
1349 struct lsa_DeleteObject del;
1350 struct dcesrv_handle *h;
1352 opn.in.handle = r->in.handle;
1353 opn.in.sid = r->in.dom_sid;
1354 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1355 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1356 if (!opn.out.trustdom_handle) {
1357 return NT_STATUS_NO_MEMORY;
1359 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1360 if (!NT_STATUS_IS_OK(status)) {
1364 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1365 talloc_steal(mem_ctx, h);
1367 del.in.handle = opn.out.trustdom_handle;
1368 del.out.handle = opn.out.trustdom_handle;
1369 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
1370 if (!NT_STATUS_IS_OK(status)) {
1373 return NT_STATUS_OK;
1376 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1377 struct ldb_message *msg,
1378 struct lsa_TrustDomainInfoInfoEx *info_ex)
1380 info_ex->domain_name.string
1381 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1382 info_ex->netbios_name.string
1383 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1385 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1386 info_ex->trust_direction
1387 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1389 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1390 info_ex->trust_attributes
1391 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1392 return NT_STATUS_OK;
1396 lsa_QueryTrustedDomainInfo
1398 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1399 struct lsa_QueryTrustedDomainInfo *r)
1401 union lsa_TrustedDomainInfo *info = NULL;
1402 struct dcesrv_handle *h;
1403 struct lsa_trusted_domain_state *trusted_domain_state;
1404 struct ldb_message *msg;
1406 struct ldb_message **res;
1407 const char *attrs[] = {
1410 "securityIdentifier",
1414 "msDs-supportedEncryptionTypes",
1418 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1420 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1422 /* pull all the user attributes */
1423 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1424 trusted_domain_state->trusted_domain_dn, &res, attrs);
1426 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1430 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
1432 return NT_STATUS_NO_MEMORY;
1434 *r->out.info = info;
1436 switch (r->in.level) {
1437 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1438 info->name.netbios_name.string
1439 = samdb_result_string(msg, "flatname", NULL);
1441 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1442 info->posix_offset.posix_offset
1443 = samdb_result_uint(msg, "posixOffset", 0);
1445 #if 0 /* Win2k3 doesn't implement this */
1446 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1447 r->out.info->info_basic.netbios_name.string
1448 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1449 r->out.info->info_basic.sid
1450 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1453 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1454 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
1456 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1457 ZERO_STRUCT(info->full_info);
1458 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
1460 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1461 ZERO_STRUCT(info->full_info2_internal);
1462 info->full_info2_internal.posix_offset.posix_offset
1463 = samdb_result_uint(msg, "posixOffset", 0);
1464 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
1466 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1467 info->enc_types.enc_types
1468 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
1471 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1472 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1473 /* oops, we don't want to return the info after all */
1475 *r->out.info = NULL;
1476 return NT_STATUS_INVALID_PARAMETER;
1478 /* oops, we don't want to return the info after all */
1480 *r->out.info = NULL;
1481 return NT_STATUS_INVALID_INFO_CLASS;
1484 return NT_STATUS_OK;
1489 lsa_QueryTrustedDomainInfoBySid
1491 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1492 struct lsa_QueryTrustedDomainInfoBySid *r)
1495 struct lsa_OpenTrustedDomain opn;
1496 struct lsa_QueryTrustedDomainInfo query;
1497 struct dcesrv_handle *h;
1499 opn.in.handle = r->in.handle;
1500 opn.in.sid = r->in.dom_sid;
1501 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1502 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1503 if (!opn.out.trustdom_handle) {
1504 return NT_STATUS_NO_MEMORY;
1506 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1507 if (!NT_STATUS_IS_OK(status)) {
1511 /* Ensure this handle goes away at the end of this call */
1512 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1513 talloc_steal(mem_ctx, h);
1515 query.in.trustdom_handle = opn.out.trustdom_handle;
1516 query.in.level = r->in.level;
1517 query.out.info = r->out.info;
1518 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1519 if (!NT_STATUS_IS_OK(status)) {
1523 return NT_STATUS_OK;
1527 lsa_SetTrustedDomainInfoByName
1529 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1530 TALLOC_CTX *mem_ctx,
1531 struct lsa_SetTrustedDomainInfoByName *r)
1533 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1537 lsa_QueryTrustedDomainInfoByName
1539 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1540 TALLOC_CTX *mem_ctx,
1541 struct lsa_QueryTrustedDomainInfoByName *r)
1544 struct lsa_OpenTrustedDomainByName opn;
1545 struct lsa_QueryTrustedDomainInfo query;
1546 struct dcesrv_handle *h;
1548 opn.in.handle = r->in.handle;
1549 opn.in.name = *r->in.trusted_domain;
1550 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1551 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1552 if (!opn.out.trustdom_handle) {
1553 return NT_STATUS_NO_MEMORY;
1555 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
1556 if (!NT_STATUS_IS_OK(status)) {
1560 /* Ensure this handle goes away at the end of this call */
1561 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1562 talloc_steal(mem_ctx, h);
1564 query.in.trustdom_handle = opn.out.trustdom_handle;
1565 query.in.level = r->in.level;
1566 query.out.info = r->out.info;
1567 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1568 if (!NT_STATUS_IS_OK(status)) {
1572 return NT_STATUS_OK;
1576 lsa_CloseTrustedDomainEx
1578 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1579 TALLOC_CTX *mem_ctx,
1580 struct lsa_CloseTrustedDomainEx *r)
1582 /* The result of a bad hair day from an IDL programmer? Not
1583 * implmented in Win2k3. You should always just lsa_Close
1585 return NT_STATUS_NOT_IMPLEMENTED;
1590 comparison function for sorting lsa_DomainInformation array
1592 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1594 return strcasecmp_m(e1->name.string, e2->name.string);
1600 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1601 struct lsa_EnumTrustDom *r)
1603 struct dcesrv_handle *policy_handle;
1604 struct lsa_DomainInfo *entries;
1605 struct lsa_policy_state *policy_state;
1606 struct ldb_message **domains;
1607 const char *attrs[] = {
1609 "securityIdentifier",
1616 *r->out.resume_handle = 0;
1618 r->out.domains->domains = NULL;
1619 r->out.domains->count = 0;
1621 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1623 policy_state = policy_handle->data;
1625 /* search for all users in this domain. This could possibly be cached and
1626 resumed based on resume_key */
1627 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1628 "objectclass=trustedDomain");
1630 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1633 /* convert to lsa_TrustInformation format */
1634 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1636 return NT_STATUS_NO_MEMORY;
1638 for (i=0;i<count;i++) {
1639 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1640 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1643 /* sort the results by name */
1644 TYPESAFE_QSORT(entries, count, compare_DomainInfo);
1646 if (*r->in.resume_handle >= count) {
1647 *r->out.resume_handle = -1;
1649 return NT_STATUS_NO_MORE_ENTRIES;
1652 /* return the rest, limit by max_size. Note that we
1653 use the w2k3 element size value of 60 */
1654 r->out.domains->count = count - *r->in.resume_handle;
1655 r->out.domains->count = MIN(r->out.domains->count,
1656 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1658 r->out.domains->domains = entries + *r->in.resume_handle;
1659 r->out.domains->count = r->out.domains->count;
1661 if (r->out.domains->count < count - *r->in.resume_handle) {
1662 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1663 return STATUS_MORE_ENTRIES;
1666 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
1667 * always be larger than the previous input resume handle, in
1668 * particular when hitting the last query it is vital to set the
1669 * resume handle correctly to avoid infinite client loops, as
1670 * seen e.g. with Windows XP SP3 when resume handle is 0 and
1671 * status is NT_STATUS_OK - gd */
1673 *r->out.resume_handle = (uint32_t)-1;
1675 return NT_STATUS_OK;
1679 comparison function for sorting lsa_DomainInformation array
1681 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1683 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1687 lsa_EnumTrustedDomainsEx
1689 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1690 struct lsa_EnumTrustedDomainsEx *r)
1692 struct dcesrv_handle *policy_handle;
1693 struct lsa_TrustDomainInfoInfoEx *entries;
1694 struct lsa_policy_state *policy_state;
1695 struct ldb_message **domains;
1696 const char *attrs[] = {
1699 "securityIdentifier",
1709 *r->out.resume_handle = 0;
1711 r->out.domains->domains = NULL;
1712 r->out.domains->count = 0;
1714 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1716 policy_state = policy_handle->data;
1718 /* search for all users in this domain. This could possibly be cached and
1719 resumed based on resume_key */
1720 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1721 "objectclass=trustedDomain");
1723 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1726 /* convert to lsa_DomainInformation format */
1727 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1729 return NT_STATUS_NO_MEMORY;
1731 for (i=0;i<count;i++) {
1732 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1733 if (!NT_STATUS_IS_OK(nt_status)) {
1738 /* sort the results by name */
1739 TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
1741 if (*r->in.resume_handle >= count) {
1742 *r->out.resume_handle = -1;
1744 return NT_STATUS_NO_MORE_ENTRIES;
1747 /* return the rest, limit by max_size. Note that we
1748 use the w2k3 element size value of 60 */
1749 r->out.domains->count = count - *r->in.resume_handle;
1750 r->out.domains->count = MIN(r->out.domains->count,
1751 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1753 r->out.domains->domains = entries + *r->in.resume_handle;
1754 r->out.domains->count = r->out.domains->count;
1756 if (r->out.domains->count < count - *r->in.resume_handle) {
1757 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1758 return STATUS_MORE_ENTRIES;
1761 return NT_STATUS_OK;
1768 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1769 struct lsa_OpenAccount *r)
1771 struct dcesrv_handle *h, *ah;
1772 struct lsa_policy_state *state;
1773 struct lsa_account_state *astate;
1775 ZERO_STRUCTP(r->out.acct_handle);
1777 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1781 astate = talloc(dce_call->conn, struct lsa_account_state);
1782 if (astate == NULL) {
1783 return NT_STATUS_NO_MEMORY;
1786 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1787 if (astate->account_sid == NULL) {
1788 talloc_free(astate);
1789 return NT_STATUS_NO_MEMORY;
1792 astate->policy = talloc_reference(astate, state);
1793 astate->access_mask = r->in.access_mask;
1795 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1797 talloc_free(astate);
1798 return NT_STATUS_NO_MEMORY;
1801 ah->data = talloc_steal(ah, astate);
1803 *r->out.acct_handle = ah->wire_handle;
1805 return NT_STATUS_OK;
1810 lsa_EnumPrivsAccount
1812 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1813 TALLOC_CTX *mem_ctx,
1814 struct lsa_EnumPrivsAccount *r)
1816 struct dcesrv_handle *h;
1817 struct lsa_account_state *astate;
1819 struct ldb_message **res;
1820 const char * const attrs[] = { "privilege", NULL};
1821 struct ldb_message_element *el;
1823 struct lsa_PrivilegeSet *privs;
1825 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1829 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1830 if (privs == NULL) {
1831 return NT_STATUS_NO_MEMORY;
1837 *r->out.privs = privs;
1839 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1840 if (sidstr == NULL) {
1841 return NT_STATUS_NO_MEMORY;
1844 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
1845 "objectSid=%s", sidstr);
1847 return NT_STATUS_OK;
1850 el = ldb_msg_find_element(res[0], "privilege");
1851 if (el == NULL || el->num_values == 0) {
1852 return NT_STATUS_OK;
1855 privs->set = talloc_array(privs,
1856 struct lsa_LUIDAttribute, el->num_values);
1857 if (privs->set == NULL) {
1858 return NT_STATUS_NO_MEMORY;
1861 for (i=0;i<el->num_values;i++) {
1862 int id = sec_privilege_id((const char *)el->values[i].data);
1864 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1866 privs->set[i].attribute = 0;
1867 privs->set[i].luid.low = id;
1868 privs->set[i].luid.high = 0;
1871 privs->count = el->num_values;
1873 return NT_STATUS_OK;
1877 lsa_EnumAccountRights
1879 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1880 TALLOC_CTX *mem_ctx,
1881 struct lsa_EnumAccountRights *r)
1883 struct dcesrv_handle *h;
1884 struct lsa_policy_state *state;
1886 struct ldb_message **res;
1887 const char * const attrs[] = { "privilege", NULL};
1889 struct ldb_message_element *el;
1891 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1895 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1896 if (sidstr == NULL) {
1897 return NT_STATUS_NO_MEMORY;
1900 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
1901 "(&(objectSid=%s)(privilege=*))", sidstr);
1903 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1906 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1909 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1910 dom_sid_string(mem_ctx, r->in.sid),
1911 ldb_errstring(state->pdb)));
1912 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1915 el = ldb_msg_find_element(res[0], "privilege");
1916 if (el == NULL || el->num_values == 0) {
1917 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1920 r->out.rights->count = el->num_values;
1921 r->out.rights->names = talloc_array(r->out.rights,
1922 struct lsa_StringLarge, r->out.rights->count);
1923 if (r->out.rights->names == NULL) {
1924 return NT_STATUS_NO_MEMORY;
1927 for (i=0;i<el->num_values;i++) {
1928 r->out.rights->names[i].string = (const char *)el->values[i].data;
1931 return NT_STATUS_OK;
1937 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1939 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1940 TALLOC_CTX *mem_ctx,
1941 struct lsa_policy_state *state,
1943 struct dom_sid *sid,
1944 const struct lsa_RightSet *rights)
1946 const char *sidstr, *sidndrstr;
1947 struct ldb_message *msg;
1948 struct ldb_message_element *el;
1950 struct lsa_EnumAccountRights r2;
1953 if (security_session_user_level(dce_call->conn->auth_state.session_info) <
1954 SECURITY_ADMINISTRATOR) {
1955 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
1956 return NT_STATUS_ACCESS_DENIED;
1959 msg = ldb_msg_new(mem_ctx);
1961 return NT_STATUS_NO_MEMORY;
1964 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
1965 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg);
1967 sidstr = dom_sid_string(msg, sid);
1968 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg);
1970 dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
1971 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg);
1973 msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
1974 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg);
1976 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1979 r2.in.handle = &state->handle->wire_handle;
1981 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1983 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1984 if (!NT_STATUS_IS_OK(status)) {
1985 ZERO_STRUCTP(r2.out.rights);
1989 for (i=0;i<rights->count;i++) {
1990 if (sec_privilege_id(rights->names[i].string) == -1) {
1992 return NT_STATUS_NO_SUCH_PRIVILEGE;
1995 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1997 for (j=0;j<r2.out.rights->count;j++) {
1998 if (strcasecmp_m(r2.out.rights->names[j].string,
1999 rights->names[i].string) == 0) {
2003 if (j != r2.out.rights->count) continue;
2006 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2007 if (ret != LDB_SUCCESS) {
2009 return NT_STATUS_NO_MEMORY;
2013 el = ldb_msg_find_element(msg, "privilege");
2016 return NT_STATUS_OK;
2019 el->flags = ldb_flag;
2021 ret = ldb_modify(state->pdb, msg);
2022 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
2023 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
2025 return NT_STATUS_NO_MEMORY;
2027 samdb_msg_add_string(state->pdb, msg, msg, "comment", "added via LSA");
2028 ret = ldb_add(state->pdb, msg);
2030 if (ret != LDB_SUCCESS) {
2031 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2033 return NT_STATUS_OK;
2035 DEBUG(3, ("Could not %s attributes from %s: %s",
2036 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2037 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
2039 return NT_STATUS_UNEXPECTED_IO_ERROR;
2043 return NT_STATUS_OK;
2047 lsa_AddPrivilegesToAccount
2049 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2050 struct lsa_AddPrivilegesToAccount *r)
2052 struct lsa_RightSet rights;
2053 struct dcesrv_handle *h;
2054 struct lsa_account_state *astate;
2057 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2061 rights.count = r->in.privs->count;
2062 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2063 if (rights.names == NULL) {
2064 return NT_STATUS_NO_MEMORY;
2066 for (i=0;i<rights.count;i++) {
2067 int id = r->in.privs->set[i].luid.low;
2068 if (r->in.privs->set[i].luid.high) {
2069 return NT_STATUS_NO_SUCH_PRIVILEGE;
2071 rights.names[i].string = sec_privilege_name(id);
2072 if (rights.names[i].string == NULL) {
2073 return NT_STATUS_NO_SUCH_PRIVILEGE;
2077 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2078 LDB_FLAG_MOD_ADD, astate->account_sid,
2084 lsa_RemovePrivilegesFromAccount
2086 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2087 struct lsa_RemovePrivilegesFromAccount *r)
2089 struct lsa_RightSet *rights;
2090 struct dcesrv_handle *h;
2091 struct lsa_account_state *astate;
2094 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2098 rights = talloc(mem_ctx, struct lsa_RightSet);
2100 if (r->in.remove_all == 1 &&
2101 r->in.privs == NULL) {
2102 struct lsa_EnumAccountRights r2;
2105 r2.in.handle = &astate->policy->handle->wire_handle;
2106 r2.in.sid = astate->account_sid;
2107 r2.out.rights = rights;
2109 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2110 if (!NT_STATUS_IS_OK(status)) {
2114 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2115 LDB_FLAG_MOD_DELETE, astate->account_sid,
2119 if (r->in.remove_all != 0) {
2120 return NT_STATUS_INVALID_PARAMETER;
2123 rights->count = r->in.privs->count;
2124 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2125 if (rights->names == NULL) {
2126 return NT_STATUS_NO_MEMORY;
2128 for (i=0;i<rights->count;i++) {
2129 int id = r->in.privs->set[i].luid.low;
2130 if (r->in.privs->set[i].luid.high) {
2131 return NT_STATUS_NO_SUCH_PRIVILEGE;
2133 rights->names[i].string = sec_privilege_name(id);
2134 if (rights->names[i].string == NULL) {
2135 return NT_STATUS_NO_SUCH_PRIVILEGE;
2139 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2140 LDB_FLAG_MOD_DELETE, astate->account_sid,
2146 lsa_GetQuotasForAccount
2148 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2149 struct lsa_GetQuotasForAccount *r)
2151 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2156 lsa_SetQuotasForAccount
2158 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2159 struct lsa_SetQuotasForAccount *r)
2161 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2166 lsa_GetSystemAccessAccount
2168 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2169 struct lsa_GetSystemAccessAccount *r)
2173 struct lsa_EnumPrivsAccount enumPrivs;
2174 struct lsa_PrivilegeSet *privs;
2176 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2178 return NT_STATUS_NO_MEMORY;
2184 enumPrivs.in.handle = r->in.handle;
2185 enumPrivs.out.privs = &privs;
2187 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2188 if (!NT_STATUS_IS_OK(status)) {
2192 *(r->out.access_mask) = 0x00000000;
2194 for (i = 0; i < privs->count; i++) {
2195 int priv = privs->set[i].luid.low;
2198 case SEC_PRIV_INTERACTIVE_LOGON:
2199 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2201 case SEC_PRIV_NETWORK_LOGON:
2202 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2204 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2205 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2210 return NT_STATUS_OK;
2215 lsa_SetSystemAccessAccount
2217 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2218 struct lsa_SetSystemAccessAccount *r)
2220 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2227 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2228 struct lsa_CreateSecret *r)
2230 struct dcesrv_handle *policy_handle;
2231 struct lsa_policy_state *policy_state;
2232 struct lsa_secret_state *secret_state;
2233 struct dcesrv_handle *handle;
2234 struct ldb_message **msgs, *msg;
2235 const char *attrs[] = {
2243 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2244 ZERO_STRUCTP(r->out.sec_handle);
2246 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2248 case SECURITY_SYSTEM:
2249 case SECURITY_ADMINISTRATOR:
2252 /* Users and annonymous are not allowed create secrets */
2253 return NT_STATUS_ACCESS_DENIED;
2256 policy_state = policy_handle->data;
2258 if (!r->in.name.string) {
2259 return NT_STATUS_INVALID_PARAMETER;
2262 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2263 if (!secret_state) {
2264 return NT_STATUS_NO_MEMORY;
2266 secret_state->policy = policy_state;
2268 msg = ldb_msg_new(mem_ctx);
2270 return NT_STATUS_NO_MEMORY;
2273 if (strncmp("G$", r->in.name.string, 2) == 0) {
2275 name = &r->in.name.string[2];
2276 /* 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) */
2277 secret_state->sam_ldb = talloc_reference(secret_state,
2278 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
2279 secret_state->global = true;
2281 if (strlen(name) < 1) {
2282 return NT_STATUS_INVALID_PARAMETER;
2285 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2286 /* search for the secret record */
2287 ret = gendb_search(secret_state->sam_ldb,
2288 mem_ctx, policy_state->system_dn, &msgs, attrs,
2289 "(&(cn=%s)(objectclass=secret))",
2292 return NT_STATUS_OBJECT_NAME_COLLISION;
2296 DEBUG(0,("Failure searching for CN=%s: %s\n",
2297 name2, ldb_errstring(secret_state->sam_ldb)));
2298 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2301 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2302 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2303 return NT_STATUS_NO_MEMORY;
2306 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2309 secret_state->global = false;
2311 name = r->in.name.string;
2312 if (strlen(name) < 1) {
2313 return NT_STATUS_INVALID_PARAMETER;
2316 secret_state->sam_ldb = talloc_reference(secret_state,
2317 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2318 /* search for the secret record */
2319 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2320 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2322 "(&(cn=%s)(objectclass=secret))",
2323 ldb_binary_encode_string(mem_ctx, name));
2325 return NT_STATUS_OBJECT_NAME_COLLISION;
2329 DEBUG(0,("Failure searching for CN=%s: %s\n",
2330 name, ldb_errstring(secret_state->sam_ldb)));
2331 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2334 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2335 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2338 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2340 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2342 /* create the secret */
2343 ret = ldb_add(secret_state->sam_ldb, msg);
2344 if (ret != LDB_SUCCESS) {
2345 DEBUG(0,("Failed to create secret record %s: %s\n",
2346 ldb_dn_get_linearized(msg->dn),
2347 ldb_errstring(secret_state->sam_ldb)));
2348 return NT_STATUS_ACCESS_DENIED;
2351 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2353 return NT_STATUS_NO_MEMORY;
2356 handle->data = talloc_steal(handle, secret_state);
2358 secret_state->access_mask = r->in.access_mask;
2359 secret_state->policy = talloc_reference(secret_state, policy_state);
2361 *r->out.sec_handle = handle->wire_handle;
2363 return NT_STATUS_OK;
2370 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2371 struct lsa_OpenSecret *r)
2373 struct dcesrv_handle *policy_handle;
2375 struct lsa_policy_state *policy_state;
2376 struct lsa_secret_state *secret_state;
2377 struct dcesrv_handle *handle;
2378 struct ldb_message **msgs;
2379 const char *attrs[] = {
2387 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2388 ZERO_STRUCTP(r->out.sec_handle);
2389 policy_state = policy_handle->data;
2391 if (!r->in.name.string) {
2392 return NT_STATUS_INVALID_PARAMETER;
2395 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2397 case SECURITY_SYSTEM:
2398 case SECURITY_ADMINISTRATOR:
2401 /* Users and annonymous are not allowed to access secrets */
2402 return NT_STATUS_ACCESS_DENIED;
2405 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2406 if (!secret_state) {
2407 return NT_STATUS_NO_MEMORY;
2409 secret_state->policy = policy_state;
2411 if (strncmp("G$", r->in.name.string, 2) == 0) {
2412 name = &r->in.name.string[2];
2413 /* 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) */
2414 secret_state->sam_ldb = talloc_reference(secret_state,
2415 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
2416 secret_state->global = true;
2418 if (strlen(name) < 1) {
2419 return NT_STATUS_INVALID_PARAMETER;
2422 /* search for the secret record */
2423 ret = gendb_search(secret_state->sam_ldb,
2424 mem_ctx, policy_state->system_dn, &msgs, attrs,
2425 "(&(cn=%s Secret)(objectclass=secret))",
2426 ldb_binary_encode_string(mem_ctx, name));
2428 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2432 DEBUG(0,("Found %d records matching DN %s\n", ret,
2433 ldb_dn_get_linearized(policy_state->system_dn)));
2434 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2438 secret_state->global = false;
2439 secret_state->sam_ldb = talloc_reference(secret_state,
2440 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2442 name = r->in.name.string;
2443 if (strlen(name) < 1) {
2444 return NT_STATUS_INVALID_PARAMETER;
2447 /* search for the secret record */
2448 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2449 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2451 "(&(cn=%s)(objectclass=secret))",
2452 ldb_binary_encode_string(mem_ctx, name));
2454 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2458 DEBUG(0,("Found %d records matching CN=%s\n",
2459 ret, ldb_binary_encode_string(mem_ctx, name)));
2460 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2464 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2466 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2468 return NT_STATUS_NO_MEMORY;
2471 handle->data = talloc_steal(handle, secret_state);
2473 secret_state->access_mask = r->in.access_mask;
2474 secret_state->policy = talloc_reference(secret_state, policy_state);
2476 *r->out.sec_handle = handle->wire_handle;
2478 return NT_STATUS_OK;
2485 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2486 struct lsa_SetSecret *r)
2489 struct dcesrv_handle *h;
2490 struct lsa_secret_state *secret_state;
2491 struct ldb_message *msg;
2492 DATA_BLOB session_key;
2493 DATA_BLOB crypt_secret, secret;
2496 NTSTATUS status = NT_STATUS_OK;
2498 struct timeval now = timeval_current();
2499 NTTIME nt_now = timeval_to_nttime(&now);
2501 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2503 secret_state = h->data;
2505 msg = ldb_msg_new(mem_ctx);
2507 return NT_STATUS_NO_MEMORY;
2510 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2512 return NT_STATUS_NO_MEMORY;
2514 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2515 if (!NT_STATUS_IS_OK(status)) {
2519 if (r->in.old_val) {
2521 crypt_secret.data = r->in.old_val->data;
2522 crypt_secret.length = r->in.old_val->size;
2524 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2525 if (!NT_STATUS_IS_OK(status)) {
2529 val.data = secret.data;
2530 val.length = secret.length;
2533 if (samdb_msg_add_value(secret_state->sam_ldb,
2534 mem_ctx, msg, "priorValue", &val) != LDB_SUCCESS) {
2535 return NT_STATUS_NO_MEMORY;
2538 /* set old value mtime */
2539 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2540 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
2541 return NT_STATUS_NO_MEMORY;
2545 /* If the old value is not set, then migrate the
2546 * current value to the old value */
2547 const struct ldb_val *old_val;
2548 NTTIME last_set_time;
2549 struct ldb_message **res;
2550 const char *attrs[] = {
2556 /* search for the secret record */
2557 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2558 secret_state->secret_dn, &res, attrs);
2560 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2564 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2565 ldb_dn_get_linearized(secret_state->secret_dn)));
2566 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2569 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2570 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2574 if (samdb_msg_add_value(secret_state->sam_ldb,
2575 mem_ctx, msg, "priorValue",
2577 return NT_STATUS_NO_MEMORY;
2580 if (samdb_msg_add_delete(secret_state->sam_ldb,
2581 mem_ctx, msg, "priorValue")) {
2582 return NT_STATUS_NO_MEMORY;
2587 /* set old value mtime */
2588 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2589 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2590 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
2591 return NT_STATUS_NO_MEMORY;
2594 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2595 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
2596 return NT_STATUS_NO_MEMORY;
2601 if (r->in.new_val) {
2603 crypt_secret.data = r->in.new_val->data;
2604 crypt_secret.length = r->in.new_val->size;
2606 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2607 if (!NT_STATUS_IS_OK(status)) {
2611 val.data = secret.data;
2612 val.length = secret.length;
2615 if (samdb_msg_add_value(secret_state->sam_ldb,
2616 mem_ctx, msg, "currentValue", &val) != LDB_SUCCESS) {
2617 return NT_STATUS_NO_MEMORY;
2620 /* set new value mtime */
2621 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2622 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
2623 return NT_STATUS_NO_MEMORY;
2627 /* NULL out the NEW value */
2628 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2629 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
2630 return NT_STATUS_NO_MEMORY;
2632 if (samdb_msg_add_delete(secret_state->sam_ldb,
2633 mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
2634 return NT_STATUS_NO_MEMORY;
2638 /* modify the samdb record */
2639 ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
2640 if (ret != LDB_SUCCESS) {
2641 /* we really need samdb.c to return NTSTATUS */
2642 return NT_STATUS_UNSUCCESSFUL;
2645 return NT_STATUS_OK;
2652 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2653 struct lsa_QuerySecret *r)
2655 struct dcesrv_handle *h;
2656 struct lsa_secret_state *secret_state;
2657 struct ldb_message *msg;
2658 DATA_BLOB session_key;
2659 DATA_BLOB crypt_secret, secret;
2661 struct ldb_message **res;
2662 const char *attrs[] = {
2672 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2674 /* Ensure user is permitted to read this... */
2675 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2677 case SECURITY_SYSTEM:
2678 case SECURITY_ADMINISTRATOR:
2681 /* Users and annonymous are not allowed to read secrets */
2682 return NT_STATUS_ACCESS_DENIED;
2685 secret_state = h->data;
2687 /* pull all the user attributes */
2688 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2689 secret_state->secret_dn, &res, attrs);
2691 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2695 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2696 if (!NT_STATUS_IS_OK(nt_status)) {
2700 if (r->in.old_val) {
2701 const struct ldb_val *prior_val;
2702 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2703 if (!r->out.old_val) {
2704 return NT_STATUS_NO_MEMORY;
2706 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2708 if (prior_val && prior_val->length) {
2709 secret.data = prior_val->data;
2710 secret.length = prior_val->length;
2713 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2714 if (!crypt_secret.length) {
2715 return NT_STATUS_NO_MEMORY;
2717 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2718 if (!r->out.old_val->buf) {
2719 return NT_STATUS_NO_MEMORY;
2721 r->out.old_val->buf->size = crypt_secret.length;
2722 r->out.old_val->buf->length = crypt_secret.length;
2723 r->out.old_val->buf->data = crypt_secret.data;
2727 if (r->in.old_mtime) {
2728 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2729 if (!r->out.old_mtime) {
2730 return NT_STATUS_NO_MEMORY;
2732 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2735 if (r->in.new_val) {
2736 const struct ldb_val *new_val;
2737 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2738 if (!r->out.new_val) {
2739 return NT_STATUS_NO_MEMORY;
2742 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2744 if (new_val && new_val->length) {
2745 secret.data = new_val->data;
2746 secret.length = new_val->length;
2749 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2750 if (!crypt_secret.length) {
2751 return NT_STATUS_NO_MEMORY;
2753 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2754 if (!r->out.new_val->buf) {
2755 return NT_STATUS_NO_MEMORY;
2757 r->out.new_val->buf->length = crypt_secret.length;
2758 r->out.new_val->buf->size = crypt_secret.length;
2759 r->out.new_val->buf->data = crypt_secret.data;
2763 if (r->in.new_mtime) {
2764 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2765 if (!r->out.new_mtime) {
2766 return NT_STATUS_NO_MEMORY;
2768 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2771 return NT_STATUS_OK;
2778 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2779 TALLOC_CTX *mem_ctx,
2780 struct lsa_LookupPrivValue *r)
2782 struct dcesrv_handle *h;
2783 struct lsa_policy_state *state;
2786 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2790 id = sec_privilege_id(r->in.name->string);
2792 return NT_STATUS_NO_SUCH_PRIVILEGE;
2795 r->out.luid->low = id;
2796 r->out.luid->high = 0;
2798 return NT_STATUS_OK;
2805 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2806 TALLOC_CTX *mem_ctx,
2807 struct lsa_LookupPrivName *r)
2809 struct dcesrv_handle *h;
2810 struct lsa_policy_state *state;
2811 struct lsa_StringLarge *name;
2812 const char *privname;
2814 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2818 if (r->in.luid->high != 0) {
2819 return NT_STATUS_NO_SUCH_PRIVILEGE;
2822 privname = sec_privilege_name(r->in.luid->low);
2823 if (privname == NULL) {
2824 return NT_STATUS_NO_SUCH_PRIVILEGE;
2827 name = talloc(mem_ctx, struct lsa_StringLarge);
2829 return NT_STATUS_NO_MEMORY;
2832 name->string = privname;
2834 *r->out.name = name;
2836 return NT_STATUS_OK;
2841 lsa_LookupPrivDisplayName
2843 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2844 TALLOC_CTX *mem_ctx,
2845 struct lsa_LookupPrivDisplayName *r)
2847 struct dcesrv_handle *h;
2848 struct lsa_policy_state *state;
2849 struct lsa_StringLarge *disp_name = NULL;
2852 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2856 id = sec_privilege_id(r->in.name->string);
2858 return NT_STATUS_NO_SUCH_PRIVILEGE;
2861 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2862 if (disp_name == NULL) {
2863 return NT_STATUS_NO_MEMORY;
2866 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
2867 if (disp_name->string == NULL) {
2868 return NT_STATUS_INTERNAL_ERROR;
2871 *r->out.disp_name = disp_name;
2872 *r->out.returned_language_id = 0;
2874 return NT_STATUS_OK;
2879 lsa_EnumAccountsWithUserRight
2881 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2882 TALLOC_CTX *mem_ctx,
2883 struct lsa_EnumAccountsWithUserRight *r)
2885 struct dcesrv_handle *h;
2886 struct lsa_policy_state *state;
2888 struct ldb_message **res;
2889 const char * const attrs[] = { "objectSid", NULL};
2890 const char *privname;
2892 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2896 if (r->in.name == NULL) {
2897 return NT_STATUS_NO_SUCH_PRIVILEGE;
2900 privname = r->in.name->string;
2901 if (sec_privilege_id(privname) == -1) {
2902 return NT_STATUS_NO_SUCH_PRIVILEGE;
2905 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2906 "privilege=%s", privname);
2908 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2911 return NT_STATUS_NO_MORE_ENTRIES;
2914 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2915 if (r->out.sids->sids == NULL) {
2916 return NT_STATUS_NO_MEMORY;
2918 for (i=0;i<ret;i++) {
2919 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2920 res[i], "objectSid");
2921 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2923 r->out.sids->num_sids = ret;
2925 return NT_STATUS_OK;
2930 lsa_AddAccountRights
2932 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2933 TALLOC_CTX *mem_ctx,
2934 struct lsa_AddAccountRights *r)
2936 struct dcesrv_handle *h;
2937 struct lsa_policy_state *state;
2939 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2943 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2945 r->in.sid, r->in.rights);
2950 lsa_RemoveAccountRights
2952 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2953 TALLOC_CTX *mem_ctx,
2954 struct lsa_RemoveAccountRights *r)
2956 struct dcesrv_handle *h;
2957 struct lsa_policy_state *state;
2959 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2963 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2964 LDB_FLAG_MOD_DELETE,
2965 r->in.sid, r->in.rights);
2970 lsa_StorePrivateData
2972 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2973 struct lsa_StorePrivateData *r)
2975 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2980 lsa_RetrievePrivateData
2982 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2983 struct lsa_RetrievePrivateData *r)
2985 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2992 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2993 struct lsa_GetUserName *r)
2995 NTSTATUS status = NT_STATUS_OK;
2996 const char *account_name;
2997 const char *authority_name;
2998 struct lsa_String *_account_name;
2999 struct lsa_String *_authority_name = NULL;
3001 /* this is what w2k3 does */
3002 r->out.account_name = r->in.account_name;
3003 r->out.authority_name = r->in.authority_name;
3005 if (r->in.account_name
3006 && *r->in.account_name
3007 /* && *(*r->in.account_name)->string */
3009 return NT_STATUS_INVALID_PARAMETER;
3012 if (r->in.authority_name
3013 && *r->in.authority_name
3014 /* && *(*r->in.authority_name)->string */
3016 return NT_STATUS_INVALID_PARAMETER;
3019 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
3020 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
3022 _account_name = talloc(mem_ctx, struct lsa_String);
3023 NT_STATUS_HAVE_NO_MEMORY(_account_name);
3024 _account_name->string = account_name;
3026 if (r->in.authority_name) {
3027 _authority_name = talloc(mem_ctx, struct lsa_String);
3028 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
3029 _authority_name->string = authority_name;
3032 *r->out.account_name = _account_name;
3033 if (r->out.authority_name) {
3034 *r->out.authority_name = _authority_name;
3043 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
3044 TALLOC_CTX *mem_ctx,
3045 struct lsa_SetInfoPolicy2 *r)
3047 /* need to support these */
3048 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3052 lsa_QueryDomainInformationPolicy
3054 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3055 TALLOC_CTX *mem_ctx,
3056 struct lsa_QueryDomainInformationPolicy *r)
3058 union lsa_DomainInformationPolicy *info;
3060 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
3062 return NT_STATUS_NO_MEMORY;
3065 switch (r->in.level) {
3066 case LSA_DOMAIN_INFO_POLICY_EFS:
3068 *r->out.info = NULL;
3069 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3070 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
3072 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
3073 struct smb_krb5_context *smb_krb5_context;
3074 int ret = smb_krb5_init_context(mem_ctx,
3075 dce_call->event_ctx,
3076 dce_call->conn->dce_ctx->lp_ctx,
3080 *r->out.info = NULL;
3081 return NT_STATUS_INTERNAL_ERROR;
3083 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
3084 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3085 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3086 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
3087 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
3088 talloc_free(smb_krb5_context);
3089 *r->out.info = info;
3090 return NT_STATUS_OK;
3094 *r->out.info = NULL;
3095 return NT_STATUS_INVALID_INFO_CLASS;
3100 lsa_SetDomInfoPolicy
3102 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3103 TALLOC_CTX *mem_ctx,
3104 struct lsa_SetDomainInformationPolicy *r)
3106 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3112 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3113 TALLOC_CTX *mem_ctx,
3114 struct lsa_TestCall *r)
3116 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3122 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3123 struct lsa_CREDRWRITE *r)
3125 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3132 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3133 struct lsa_CREDRREAD *r)
3135 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3142 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3143 struct lsa_CREDRENUMERATE *r)
3145 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3150 lsa_CREDRWRITEDOMAINCREDENTIALS
3152 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3153 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3155 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3160 lsa_CREDRREADDOMAINCREDENTIALS
3162 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3163 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3165 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3172 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3173 struct lsa_CREDRDELETE *r)
3175 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3180 lsa_CREDRGETTARGETINFO
3182 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3183 struct lsa_CREDRGETTARGETINFO *r)
3185 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3190 lsa_CREDRPROFILELOADED
3192 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3193 struct lsa_CREDRPROFILELOADED *r)
3195 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3200 lsa_CREDRGETSESSIONTYPES
3202 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3203 struct lsa_CREDRGETSESSIONTYPES *r)
3205 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3210 lsa_LSARREGISTERAUDITEVENT
3212 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3213 struct lsa_LSARREGISTERAUDITEVENT *r)
3215 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3220 lsa_LSARGENAUDITEVENT
3222 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3223 struct lsa_LSARGENAUDITEVENT *r)
3225 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3230 lsa_LSARUNREGISTERAUDITEVENT
3232 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3233 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3235 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3240 lsa_lsaRQueryForestTrustInformation
3242 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3243 struct lsa_lsaRQueryForestTrustInformation *r)
3245 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3250 lsa_LSARSETFORESTTRUSTINFORMATION
3252 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3253 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3255 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3262 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3263 struct lsa_CREDRRENAME *r)
3265 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3271 lsa_LSAROPENPOLICYSCE
3273 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3274 struct lsa_LSAROPENPOLICYSCE *r)
3276 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3281 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3283 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3284 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3286 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3291 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3293 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3294 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3296 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3301 lsa_LSARADTREPORTSECURITYEVENT
3303 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3304 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3306 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3310 /* include the generated boilerplate */
3311 #include "librpc/gen_ndr/ndr_lsa_s.c"
3315 /*****************************************
3316 NOTE! The remaining calls below were
3317 removed in w2k3, so the DCESRV_FAULT()
3318 replies are the correct implementation. Do
3319 not try and fill these in with anything else
3320 ******************************************/
3323 dssetup_DsRoleDnsNameToFlatName
3325 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3326 struct dssetup_DsRoleDnsNameToFlatName *r)
3328 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3333 dssetup_DsRoleDcAsDc
3335 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3336 struct dssetup_DsRoleDcAsDc *r)
3338 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3343 dssetup_DsRoleDcAsReplica
3345 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3346 struct dssetup_DsRoleDcAsReplica *r)
3348 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3353 dssetup_DsRoleDemoteDc
3355 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3356 struct dssetup_DsRoleDemoteDc *r)
3358 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3363 dssetup_DsRoleGetDcOperationProgress
3365 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3366 struct dssetup_DsRoleGetDcOperationProgress *r)
3368 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3373 dssetup_DsRoleGetDcOperationResults
3375 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3376 struct dssetup_DsRoleGetDcOperationResults *r)
3378 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3383 dssetup_DsRoleCancel
3385 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3386 struct dssetup_DsRoleCancel *r)
3388 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3393 dssetup_DsRoleServerSaveStateForUpgrade
3395 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3396 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3398 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3403 dssetup_DsRoleUpgradeDownlevelServer
3405 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3406 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3408 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3413 dssetup_DsRoleAbortDownlevelServerUpgrade
3415 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3416 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3418 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3422 /* include the generated boilerplate */
3423 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3425 NTSTATUS dcerpc_server_lsa_init(void)
3429 ret = dcerpc_server_dssetup_init();
3430 if (!NT_STATUS_IS_OK(ret)) {
3433 ret = dcerpc_server_lsarpc_init();
3434 if (!NT_STATUS_IS_OK(ret)) {