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 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1283 mem_ctx, policy_state->system_dn, &msgs, attrs,
1284 "(&(flatname=%s)(objectclass=trustedDomain))",
1285 ldb_binary_encode_string(mem_ctx, r->in.name.string));
1287 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1291 DEBUG(0,("Found %d records matching DN %s\n", ret,
1292 ldb_dn_get_linearized(policy_state->system_dn)));
1293 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1296 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1298 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1300 return NT_STATUS_NO_MEMORY;
1303 handle->data = talloc_steal(handle, trusted_domain_state);
1305 trusted_domain_state->access_mask = r->in.access_mask;
1306 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1308 *r->out.trustdom_handle = handle->wire_handle;
1310 return NT_STATUS_OK;
1316 lsa_SetTrustedDomainInfo
1318 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1319 struct lsa_SetTrustedDomainInfo *r)
1321 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1327 lsa_SetInfomrationTrustedDomain
1329 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1330 TALLOC_CTX *mem_ctx,
1331 struct lsa_SetInformationTrustedDomain *r)
1333 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1338 lsa_DeleteTrustedDomain
1340 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1341 struct lsa_DeleteTrustedDomain *r)
1344 struct lsa_OpenTrustedDomain opn;
1345 struct lsa_DeleteObject del;
1346 struct dcesrv_handle *h;
1348 opn.in.handle = r->in.handle;
1349 opn.in.sid = r->in.dom_sid;
1350 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1351 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1352 if (!opn.out.trustdom_handle) {
1353 return NT_STATUS_NO_MEMORY;
1355 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1356 if (!NT_STATUS_IS_OK(status)) {
1360 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1361 talloc_steal(mem_ctx, h);
1363 del.in.handle = opn.out.trustdom_handle;
1364 del.out.handle = opn.out.trustdom_handle;
1365 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
1366 if (!NT_STATUS_IS_OK(status)) {
1369 return NT_STATUS_OK;
1372 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1373 struct ldb_message *msg,
1374 struct lsa_TrustDomainInfoInfoEx *info_ex)
1376 info_ex->domain_name.string
1377 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1378 info_ex->netbios_name.string
1379 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1381 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1382 info_ex->trust_direction
1383 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1385 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1386 info_ex->trust_attributes
1387 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1388 return NT_STATUS_OK;
1392 lsa_QueryTrustedDomainInfo
1394 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1395 struct lsa_QueryTrustedDomainInfo *r)
1397 union lsa_TrustedDomainInfo *info = NULL;
1398 struct dcesrv_handle *h;
1399 struct lsa_trusted_domain_state *trusted_domain_state;
1400 struct ldb_message *msg;
1402 struct ldb_message **res;
1403 const char *attrs[] = {
1406 "securityIdentifier",
1410 "msDs-supportedEncryptionTypes",
1414 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1416 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1418 /* pull all the user attributes */
1419 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1420 trusted_domain_state->trusted_domain_dn, &res, attrs);
1422 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1426 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
1428 return NT_STATUS_NO_MEMORY;
1430 *r->out.info = info;
1432 switch (r->in.level) {
1433 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1434 info->name.netbios_name.string
1435 = samdb_result_string(msg, "flatname", NULL);
1437 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1438 info->posix_offset.posix_offset
1439 = samdb_result_uint(msg, "posixOffset", 0);
1441 #if 0 /* Win2k3 doesn't implement this */
1442 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1443 r->out.info->info_basic.netbios_name.string
1444 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1445 r->out.info->info_basic.sid
1446 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1449 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1450 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
1452 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1453 ZERO_STRUCT(info->full_info);
1454 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
1456 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1457 ZERO_STRUCT(info->full_info2_internal);
1458 info->full_info2_internal.posix_offset.posix_offset
1459 = samdb_result_uint(msg, "posixOffset", 0);
1460 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
1462 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1463 info->enc_types.enc_types
1464 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
1467 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1468 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1469 /* oops, we don't want to return the info after all */
1471 *r->out.info = NULL;
1472 return NT_STATUS_INVALID_PARAMETER;
1474 /* oops, we don't want to return the info after all */
1476 *r->out.info = NULL;
1477 return NT_STATUS_INVALID_INFO_CLASS;
1480 return NT_STATUS_OK;
1485 lsa_QueryTrustedDomainInfoBySid
1487 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1488 struct lsa_QueryTrustedDomainInfoBySid *r)
1491 struct lsa_OpenTrustedDomain opn;
1492 struct lsa_QueryTrustedDomainInfo query;
1493 struct dcesrv_handle *h;
1495 opn.in.handle = r->in.handle;
1496 opn.in.sid = r->in.dom_sid;
1497 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1498 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1499 if (!opn.out.trustdom_handle) {
1500 return NT_STATUS_NO_MEMORY;
1502 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1503 if (!NT_STATUS_IS_OK(status)) {
1507 /* Ensure this handle goes away at the end of this call */
1508 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1509 talloc_steal(mem_ctx, h);
1511 query.in.trustdom_handle = opn.out.trustdom_handle;
1512 query.in.level = r->in.level;
1513 query.out.info = r->out.info;
1514 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1515 if (!NT_STATUS_IS_OK(status)) {
1519 return NT_STATUS_OK;
1523 lsa_SetTrustedDomainInfoByName
1525 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1526 TALLOC_CTX *mem_ctx,
1527 struct lsa_SetTrustedDomainInfoByName *r)
1529 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1533 lsa_QueryTrustedDomainInfoByName
1535 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1536 TALLOC_CTX *mem_ctx,
1537 struct lsa_QueryTrustedDomainInfoByName *r)
1540 struct lsa_OpenTrustedDomainByName opn;
1541 struct lsa_QueryTrustedDomainInfo query;
1542 struct dcesrv_handle *h;
1544 opn.in.handle = r->in.handle;
1545 opn.in.name = *r->in.trusted_domain;
1546 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1547 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1548 if (!opn.out.trustdom_handle) {
1549 return NT_STATUS_NO_MEMORY;
1551 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
1552 if (!NT_STATUS_IS_OK(status)) {
1556 /* Ensure this handle goes away at the end of this call */
1557 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1558 talloc_steal(mem_ctx, h);
1560 query.in.trustdom_handle = opn.out.trustdom_handle;
1561 query.in.level = r->in.level;
1562 query.out.info = r->out.info;
1563 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1564 if (!NT_STATUS_IS_OK(status)) {
1568 return NT_STATUS_OK;
1572 lsa_CloseTrustedDomainEx
1574 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1575 TALLOC_CTX *mem_ctx,
1576 struct lsa_CloseTrustedDomainEx *r)
1578 /* The result of a bad hair day from an IDL programmer? Not
1579 * implmented in Win2k3. You should always just lsa_Close
1581 return NT_STATUS_NOT_IMPLEMENTED;
1586 comparison function for sorting lsa_DomainInformation array
1588 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1590 return strcasecmp_m(e1->name.string, e2->name.string);
1596 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1597 struct lsa_EnumTrustDom *r)
1599 struct dcesrv_handle *policy_handle;
1600 struct lsa_DomainInfo *entries;
1601 struct lsa_policy_state *policy_state;
1602 struct ldb_message **domains;
1603 const char *attrs[] = {
1605 "securityIdentifier",
1612 *r->out.resume_handle = 0;
1614 r->out.domains->domains = NULL;
1615 r->out.domains->count = 0;
1617 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1619 policy_state = policy_handle->data;
1621 /* search for all users in this domain. This could possibly be cached and
1622 resumed based on resume_key */
1623 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1624 "objectclass=trustedDomain");
1626 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1629 /* convert to lsa_TrustInformation format */
1630 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1632 return NT_STATUS_NO_MEMORY;
1634 for (i=0;i<count;i++) {
1635 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1636 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1639 /* sort the results by name */
1640 TYPESAFE_QSORT(entries, count, compare_DomainInfo);
1642 if (*r->in.resume_handle >= count) {
1643 *r->out.resume_handle = -1;
1645 return NT_STATUS_NO_MORE_ENTRIES;
1648 /* return the rest, limit by max_size. Note that we
1649 use the w2k3 element size value of 60 */
1650 r->out.domains->count = count - *r->in.resume_handle;
1651 r->out.domains->count = MIN(r->out.domains->count,
1652 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1654 r->out.domains->domains = entries + *r->in.resume_handle;
1655 r->out.domains->count = r->out.domains->count;
1657 if (r->out.domains->count < count - *r->in.resume_handle) {
1658 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1659 return STATUS_MORE_ENTRIES;
1662 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
1663 * always be larger than the previous input resume handle, in
1664 * particular when hitting the last query it is vital to set the
1665 * resume handle correctly to avoid infinite client loops, as
1666 * seen e.g. with Windows XP SP3 when resume handle is 0 and
1667 * status is NT_STATUS_OK - gd */
1669 *r->out.resume_handle = (uint32_t)-1;
1671 return NT_STATUS_OK;
1675 comparison function for sorting lsa_DomainInformation array
1677 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1679 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1683 lsa_EnumTrustedDomainsEx
1685 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1686 struct lsa_EnumTrustedDomainsEx *r)
1688 struct dcesrv_handle *policy_handle;
1689 struct lsa_TrustDomainInfoInfoEx *entries;
1690 struct lsa_policy_state *policy_state;
1691 struct ldb_message **domains;
1692 const char *attrs[] = {
1695 "securityIdentifier",
1705 *r->out.resume_handle = 0;
1707 r->out.domains->domains = NULL;
1708 r->out.domains->count = 0;
1710 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1712 policy_state = policy_handle->data;
1714 /* search for all users in this domain. This could possibly be cached and
1715 resumed based on resume_key */
1716 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1717 "objectclass=trustedDomain");
1719 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1722 /* convert to lsa_DomainInformation format */
1723 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1725 return NT_STATUS_NO_MEMORY;
1727 for (i=0;i<count;i++) {
1728 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1729 if (!NT_STATUS_IS_OK(nt_status)) {
1734 /* sort the results by name */
1735 TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
1737 if (*r->in.resume_handle >= count) {
1738 *r->out.resume_handle = -1;
1740 return NT_STATUS_NO_MORE_ENTRIES;
1743 /* return the rest, limit by max_size. Note that we
1744 use the w2k3 element size value of 60 */
1745 r->out.domains->count = count - *r->in.resume_handle;
1746 r->out.domains->count = MIN(r->out.domains->count,
1747 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1749 r->out.domains->domains = entries + *r->in.resume_handle;
1750 r->out.domains->count = r->out.domains->count;
1752 if (r->out.domains->count < count - *r->in.resume_handle) {
1753 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1754 return STATUS_MORE_ENTRIES;
1757 return NT_STATUS_OK;
1764 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1765 struct lsa_OpenAccount *r)
1767 struct dcesrv_handle *h, *ah;
1768 struct lsa_policy_state *state;
1769 struct lsa_account_state *astate;
1771 ZERO_STRUCTP(r->out.acct_handle);
1773 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1777 astate = talloc(dce_call->conn, struct lsa_account_state);
1778 if (astate == NULL) {
1779 return NT_STATUS_NO_MEMORY;
1782 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1783 if (astate->account_sid == NULL) {
1784 talloc_free(astate);
1785 return NT_STATUS_NO_MEMORY;
1788 astate->policy = talloc_reference(astate, state);
1789 astate->access_mask = r->in.access_mask;
1791 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1793 talloc_free(astate);
1794 return NT_STATUS_NO_MEMORY;
1797 ah->data = talloc_steal(ah, astate);
1799 *r->out.acct_handle = ah->wire_handle;
1801 return NT_STATUS_OK;
1806 lsa_EnumPrivsAccount
1808 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1809 TALLOC_CTX *mem_ctx,
1810 struct lsa_EnumPrivsAccount *r)
1812 struct dcesrv_handle *h;
1813 struct lsa_account_state *astate;
1815 struct ldb_message **res;
1816 const char * const attrs[] = { "privilege", NULL};
1817 struct ldb_message_element *el;
1819 struct lsa_PrivilegeSet *privs;
1821 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1825 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1826 if (privs == NULL) {
1827 return NT_STATUS_NO_MEMORY;
1833 *r->out.privs = privs;
1835 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1836 if (sidstr == NULL) {
1837 return NT_STATUS_NO_MEMORY;
1840 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
1841 "objectSid=%s", sidstr);
1843 return NT_STATUS_OK;
1846 el = ldb_msg_find_element(res[0], "privilege");
1847 if (el == NULL || el->num_values == 0) {
1848 return NT_STATUS_OK;
1851 privs->set = talloc_array(privs,
1852 struct lsa_LUIDAttribute, el->num_values);
1853 if (privs->set == NULL) {
1854 return NT_STATUS_NO_MEMORY;
1857 for (i=0;i<el->num_values;i++) {
1858 int id = sec_privilege_id((const char *)el->values[i].data);
1860 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1862 privs->set[i].attribute = 0;
1863 privs->set[i].luid.low = id;
1864 privs->set[i].luid.high = 0;
1867 privs->count = el->num_values;
1869 return NT_STATUS_OK;
1873 lsa_EnumAccountRights
1875 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1876 TALLOC_CTX *mem_ctx,
1877 struct lsa_EnumAccountRights *r)
1879 struct dcesrv_handle *h;
1880 struct lsa_policy_state *state;
1882 struct ldb_message **res;
1883 const char * const attrs[] = { "privilege", NULL};
1885 struct ldb_message_element *el;
1887 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1891 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1892 if (sidstr == NULL) {
1893 return NT_STATUS_NO_MEMORY;
1896 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
1897 "(&(objectSid=%s)(privilege=*))", sidstr);
1899 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1902 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1905 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1906 dom_sid_string(mem_ctx, r->in.sid),
1907 ldb_errstring(state->pdb)));
1908 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1911 el = ldb_msg_find_element(res[0], "privilege");
1912 if (el == NULL || el->num_values == 0) {
1913 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1916 r->out.rights->count = el->num_values;
1917 r->out.rights->names = talloc_array(r->out.rights,
1918 struct lsa_StringLarge, r->out.rights->count);
1919 if (r->out.rights->names == NULL) {
1920 return NT_STATUS_NO_MEMORY;
1923 for (i=0;i<el->num_values;i++) {
1924 r->out.rights->names[i].string = (const char *)el->values[i].data;
1927 return NT_STATUS_OK;
1933 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1935 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1936 TALLOC_CTX *mem_ctx,
1937 struct lsa_policy_state *state,
1939 struct dom_sid *sid,
1940 const struct lsa_RightSet *rights)
1942 const char *sidstr, *sidndrstr;
1943 struct ldb_message *msg;
1944 struct ldb_message_element *el;
1946 struct lsa_EnumAccountRights r2;
1949 if (security_session_user_level(dce_call->conn->auth_state.session_info) <
1950 SECURITY_ADMINISTRATOR) {
1951 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
1952 return NT_STATUS_ACCESS_DENIED;
1955 msg = ldb_msg_new(mem_ctx);
1957 return NT_STATUS_NO_MEMORY;
1960 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
1961 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg);
1963 sidstr = dom_sid_string(msg, sid);
1964 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg);
1966 dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
1967 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg);
1969 msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
1970 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg);
1972 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1975 r2.in.handle = &state->handle->wire_handle;
1977 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1979 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1980 if (!NT_STATUS_IS_OK(status)) {
1981 ZERO_STRUCTP(r2.out.rights);
1985 for (i=0;i<rights->count;i++) {
1986 if (sec_privilege_id(rights->names[i].string) == -1) {
1988 return NT_STATUS_NO_SUCH_PRIVILEGE;
1991 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1993 for (j=0;j<r2.out.rights->count;j++) {
1994 if (strcasecmp_m(r2.out.rights->names[j].string,
1995 rights->names[i].string) == 0) {
1999 if (j != r2.out.rights->count) continue;
2002 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2003 if (ret != LDB_SUCCESS) {
2005 return NT_STATUS_NO_MEMORY;
2009 el = ldb_msg_find_element(msg, "privilege");
2012 return NT_STATUS_OK;
2015 el->flags = ldb_flag;
2017 ret = ldb_modify(state->pdb, msg);
2018 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
2019 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
2021 return NT_STATUS_NO_MEMORY;
2023 samdb_msg_add_string(state->pdb, msg, msg, "comment", "added via LSA");
2024 ret = ldb_add(state->pdb, msg);
2026 if (ret != LDB_SUCCESS) {
2027 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2029 return NT_STATUS_OK;
2031 DEBUG(3, ("Could not %s attributes from %s: %s",
2032 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2033 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
2035 return NT_STATUS_UNEXPECTED_IO_ERROR;
2039 return NT_STATUS_OK;
2043 lsa_AddPrivilegesToAccount
2045 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2046 struct lsa_AddPrivilegesToAccount *r)
2048 struct lsa_RightSet rights;
2049 struct dcesrv_handle *h;
2050 struct lsa_account_state *astate;
2053 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2057 rights.count = r->in.privs->count;
2058 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2059 if (rights.names == NULL) {
2060 return NT_STATUS_NO_MEMORY;
2062 for (i=0;i<rights.count;i++) {
2063 int id = r->in.privs->set[i].luid.low;
2064 if (r->in.privs->set[i].luid.high) {
2065 return NT_STATUS_NO_SUCH_PRIVILEGE;
2067 rights.names[i].string = sec_privilege_name(id);
2068 if (rights.names[i].string == NULL) {
2069 return NT_STATUS_NO_SUCH_PRIVILEGE;
2073 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2074 LDB_FLAG_MOD_ADD, astate->account_sid,
2080 lsa_RemovePrivilegesFromAccount
2082 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2083 struct lsa_RemovePrivilegesFromAccount *r)
2085 struct lsa_RightSet *rights;
2086 struct dcesrv_handle *h;
2087 struct lsa_account_state *astate;
2090 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2094 rights = talloc(mem_ctx, struct lsa_RightSet);
2096 if (r->in.remove_all == 1 &&
2097 r->in.privs == NULL) {
2098 struct lsa_EnumAccountRights r2;
2101 r2.in.handle = &astate->policy->handle->wire_handle;
2102 r2.in.sid = astate->account_sid;
2103 r2.out.rights = rights;
2105 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2106 if (!NT_STATUS_IS_OK(status)) {
2110 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2111 LDB_FLAG_MOD_DELETE, astate->account_sid,
2115 if (r->in.remove_all != 0) {
2116 return NT_STATUS_INVALID_PARAMETER;
2119 rights->count = r->in.privs->count;
2120 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2121 if (rights->names == NULL) {
2122 return NT_STATUS_NO_MEMORY;
2124 for (i=0;i<rights->count;i++) {
2125 int id = r->in.privs->set[i].luid.low;
2126 if (r->in.privs->set[i].luid.high) {
2127 return NT_STATUS_NO_SUCH_PRIVILEGE;
2129 rights->names[i].string = sec_privilege_name(id);
2130 if (rights->names[i].string == NULL) {
2131 return NT_STATUS_NO_SUCH_PRIVILEGE;
2135 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2136 LDB_FLAG_MOD_DELETE, astate->account_sid,
2142 lsa_GetQuotasForAccount
2144 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2145 struct lsa_GetQuotasForAccount *r)
2147 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2152 lsa_SetQuotasForAccount
2154 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2155 struct lsa_SetQuotasForAccount *r)
2157 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2162 lsa_GetSystemAccessAccount
2164 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2165 struct lsa_GetSystemAccessAccount *r)
2169 struct lsa_EnumPrivsAccount enumPrivs;
2170 struct lsa_PrivilegeSet *privs;
2172 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2174 return NT_STATUS_NO_MEMORY;
2180 enumPrivs.in.handle = r->in.handle;
2181 enumPrivs.out.privs = &privs;
2183 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2184 if (!NT_STATUS_IS_OK(status)) {
2188 *(r->out.access_mask) = 0x00000000;
2190 for (i = 0; i < privs->count; i++) {
2191 int priv = privs->set[i].luid.low;
2194 case SEC_PRIV_INTERACTIVE_LOGON:
2195 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2197 case SEC_PRIV_NETWORK_LOGON:
2198 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2200 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2201 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2206 return NT_STATUS_OK;
2211 lsa_SetSystemAccessAccount
2213 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2214 struct lsa_SetSystemAccessAccount *r)
2216 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2223 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2224 struct lsa_CreateSecret *r)
2226 struct dcesrv_handle *policy_handle;
2227 struct lsa_policy_state *policy_state;
2228 struct lsa_secret_state *secret_state;
2229 struct dcesrv_handle *handle;
2230 struct ldb_message **msgs, *msg;
2231 const char *attrs[] = {
2239 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2240 ZERO_STRUCTP(r->out.sec_handle);
2242 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2244 case SECURITY_SYSTEM:
2245 case SECURITY_ADMINISTRATOR:
2248 /* Users and annonymous are not allowed create secrets */
2249 return NT_STATUS_ACCESS_DENIED;
2252 policy_state = policy_handle->data;
2254 if (!r->in.name.string) {
2255 return NT_STATUS_INVALID_PARAMETER;
2258 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2259 if (!secret_state) {
2260 return NT_STATUS_NO_MEMORY;
2262 secret_state->policy = policy_state;
2264 msg = ldb_msg_new(mem_ctx);
2266 return NT_STATUS_NO_MEMORY;
2269 if (strncmp("G$", r->in.name.string, 2) == 0) {
2271 name = &r->in.name.string[2];
2272 /* 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) */
2273 secret_state->sam_ldb = talloc_reference(secret_state,
2274 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
2275 secret_state->global = true;
2277 if (strlen(name) < 1) {
2278 return NT_STATUS_INVALID_PARAMETER;
2281 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2282 /* search for the secret record */
2283 ret = gendb_search(secret_state->sam_ldb,
2284 mem_ctx, policy_state->system_dn, &msgs, attrs,
2285 "(&(cn=%s)(objectclass=secret))",
2288 return NT_STATUS_OBJECT_NAME_COLLISION;
2292 DEBUG(0,("Failure searching for CN=%s: %s\n",
2293 name2, ldb_errstring(secret_state->sam_ldb)));
2294 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2297 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2298 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2299 return NT_STATUS_NO_MEMORY;
2302 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2305 secret_state->global = false;
2307 name = r->in.name.string;
2308 if (strlen(name) < 1) {
2309 return NT_STATUS_INVALID_PARAMETER;
2312 secret_state->sam_ldb = talloc_reference(secret_state,
2313 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2314 /* search for the secret record */
2315 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2316 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2318 "(&(cn=%s)(objectclass=secret))",
2319 ldb_binary_encode_string(mem_ctx, name));
2321 return NT_STATUS_OBJECT_NAME_COLLISION;
2325 DEBUG(0,("Failure searching for CN=%s: %s\n",
2326 name, ldb_errstring(secret_state->sam_ldb)));
2327 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2330 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2331 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2334 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2336 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2338 /* create the secret */
2339 ret = ldb_add(secret_state->sam_ldb, msg);
2340 if (ret != LDB_SUCCESS) {
2341 DEBUG(0,("Failed to create secret record %s: %s\n",
2342 ldb_dn_get_linearized(msg->dn),
2343 ldb_errstring(secret_state->sam_ldb)));
2344 return NT_STATUS_ACCESS_DENIED;
2347 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2349 return NT_STATUS_NO_MEMORY;
2352 handle->data = talloc_steal(handle, secret_state);
2354 secret_state->access_mask = r->in.access_mask;
2355 secret_state->policy = talloc_reference(secret_state, policy_state);
2357 *r->out.sec_handle = handle->wire_handle;
2359 return NT_STATUS_OK;
2366 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2367 struct lsa_OpenSecret *r)
2369 struct dcesrv_handle *policy_handle;
2371 struct lsa_policy_state *policy_state;
2372 struct lsa_secret_state *secret_state;
2373 struct dcesrv_handle *handle;
2374 struct ldb_message **msgs;
2375 const char *attrs[] = {
2383 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2384 ZERO_STRUCTP(r->out.sec_handle);
2385 policy_state = policy_handle->data;
2387 if (!r->in.name.string) {
2388 return NT_STATUS_INVALID_PARAMETER;
2391 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2393 case SECURITY_SYSTEM:
2394 case SECURITY_ADMINISTRATOR:
2397 /* Users and annonymous are not allowed to access secrets */
2398 return NT_STATUS_ACCESS_DENIED;
2401 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2402 if (!secret_state) {
2403 return NT_STATUS_NO_MEMORY;
2405 secret_state->policy = policy_state;
2407 if (strncmp("G$", r->in.name.string, 2) == 0) {
2408 name = &r->in.name.string[2];
2409 /* 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) */
2410 secret_state->sam_ldb = talloc_reference(secret_state,
2411 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx)));
2412 secret_state->global = true;
2414 if (strlen(name) < 1) {
2415 return NT_STATUS_INVALID_PARAMETER;
2418 /* search for the secret record */
2419 ret = gendb_search(secret_state->sam_ldb,
2420 mem_ctx, policy_state->system_dn, &msgs, attrs,
2421 "(&(cn=%s Secret)(objectclass=secret))",
2422 ldb_binary_encode_string(mem_ctx, name));
2424 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2428 DEBUG(0,("Found %d records matching DN %s\n", ret,
2429 ldb_dn_get_linearized(policy_state->system_dn)));
2430 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2434 secret_state->global = false;
2435 secret_state->sam_ldb = talloc_reference(secret_state,
2436 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2438 name = r->in.name.string;
2439 if (strlen(name) < 1) {
2440 return NT_STATUS_INVALID_PARAMETER;
2443 /* search for the secret record */
2444 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2445 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2447 "(&(cn=%s)(objectclass=secret))",
2448 ldb_binary_encode_string(mem_ctx, name));
2450 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2454 DEBUG(0,("Found %d records matching CN=%s\n",
2455 ret, ldb_binary_encode_string(mem_ctx, name)));
2456 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2460 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2462 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2464 return NT_STATUS_NO_MEMORY;
2467 handle->data = talloc_steal(handle, secret_state);
2469 secret_state->access_mask = r->in.access_mask;
2470 secret_state->policy = talloc_reference(secret_state, policy_state);
2472 *r->out.sec_handle = handle->wire_handle;
2474 return NT_STATUS_OK;
2481 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2482 struct lsa_SetSecret *r)
2485 struct dcesrv_handle *h;
2486 struct lsa_secret_state *secret_state;
2487 struct ldb_message *msg;
2488 DATA_BLOB session_key;
2489 DATA_BLOB crypt_secret, secret;
2492 NTSTATUS status = NT_STATUS_OK;
2494 struct timeval now = timeval_current();
2495 NTTIME nt_now = timeval_to_nttime(&now);
2497 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2499 secret_state = h->data;
2501 msg = ldb_msg_new(mem_ctx);
2503 return NT_STATUS_NO_MEMORY;
2506 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2508 return NT_STATUS_NO_MEMORY;
2510 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2511 if (!NT_STATUS_IS_OK(status)) {
2515 if (r->in.old_val) {
2517 crypt_secret.data = r->in.old_val->data;
2518 crypt_secret.length = r->in.old_val->size;
2520 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2521 if (!NT_STATUS_IS_OK(status)) {
2525 val.data = secret.data;
2526 val.length = secret.length;
2529 if (samdb_msg_add_value(secret_state->sam_ldb,
2530 mem_ctx, msg, "priorValue", &val) != LDB_SUCCESS) {
2531 return NT_STATUS_NO_MEMORY;
2534 /* set old value mtime */
2535 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2536 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
2537 return NT_STATUS_NO_MEMORY;
2541 /* If the old value is not set, then migrate the
2542 * current value to the old value */
2543 const struct ldb_val *old_val;
2544 NTTIME last_set_time;
2545 struct ldb_message **res;
2546 const char *attrs[] = {
2552 /* search for the secret record */
2553 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2554 secret_state->secret_dn, &res, attrs);
2556 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2560 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2561 ldb_dn_get_linearized(secret_state->secret_dn)));
2562 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2565 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2566 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2570 if (samdb_msg_add_value(secret_state->sam_ldb,
2571 mem_ctx, msg, "priorValue",
2573 return NT_STATUS_NO_MEMORY;
2576 if (samdb_msg_add_delete(secret_state->sam_ldb,
2577 mem_ctx, msg, "priorValue")) {
2578 return NT_STATUS_NO_MEMORY;
2583 /* set old value mtime */
2584 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2585 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2586 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
2587 return NT_STATUS_NO_MEMORY;
2590 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2591 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
2592 return NT_STATUS_NO_MEMORY;
2597 if (r->in.new_val) {
2599 crypt_secret.data = r->in.new_val->data;
2600 crypt_secret.length = r->in.new_val->size;
2602 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2603 if (!NT_STATUS_IS_OK(status)) {
2607 val.data = secret.data;
2608 val.length = secret.length;
2611 if (samdb_msg_add_value(secret_state->sam_ldb,
2612 mem_ctx, msg, "currentValue", &val) != LDB_SUCCESS) {
2613 return NT_STATUS_NO_MEMORY;
2616 /* set new value mtime */
2617 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2618 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
2619 return NT_STATUS_NO_MEMORY;
2623 /* NULL out the NEW value */
2624 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2625 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
2626 return NT_STATUS_NO_MEMORY;
2628 if (samdb_msg_add_delete(secret_state->sam_ldb,
2629 mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
2630 return NT_STATUS_NO_MEMORY;
2634 /* modify the samdb record */
2635 ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
2636 if (ret != LDB_SUCCESS) {
2637 /* we really need samdb.c to return NTSTATUS */
2638 return NT_STATUS_UNSUCCESSFUL;
2641 return NT_STATUS_OK;
2648 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2649 struct lsa_QuerySecret *r)
2651 struct dcesrv_handle *h;
2652 struct lsa_secret_state *secret_state;
2653 struct ldb_message *msg;
2654 DATA_BLOB session_key;
2655 DATA_BLOB crypt_secret, secret;
2657 struct ldb_message **res;
2658 const char *attrs[] = {
2668 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2670 /* Ensure user is permitted to read this... */
2671 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2673 case SECURITY_SYSTEM:
2674 case SECURITY_ADMINISTRATOR:
2677 /* Users and annonymous are not allowed to read secrets */
2678 return NT_STATUS_ACCESS_DENIED;
2681 secret_state = h->data;
2683 /* pull all the user attributes */
2684 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2685 secret_state->secret_dn, &res, attrs);
2687 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2691 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2692 if (!NT_STATUS_IS_OK(nt_status)) {
2696 if (r->in.old_val) {
2697 const struct ldb_val *prior_val;
2698 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2699 if (!r->out.old_val) {
2700 return NT_STATUS_NO_MEMORY;
2702 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2704 if (prior_val && prior_val->length) {
2705 secret.data = prior_val->data;
2706 secret.length = prior_val->length;
2709 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2710 if (!crypt_secret.length) {
2711 return NT_STATUS_NO_MEMORY;
2713 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2714 if (!r->out.old_val->buf) {
2715 return NT_STATUS_NO_MEMORY;
2717 r->out.old_val->buf->size = crypt_secret.length;
2718 r->out.old_val->buf->length = crypt_secret.length;
2719 r->out.old_val->buf->data = crypt_secret.data;
2723 if (r->in.old_mtime) {
2724 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2725 if (!r->out.old_mtime) {
2726 return NT_STATUS_NO_MEMORY;
2728 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2731 if (r->in.new_val) {
2732 const struct ldb_val *new_val;
2733 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2734 if (!r->out.new_val) {
2735 return NT_STATUS_NO_MEMORY;
2738 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2740 if (new_val && new_val->length) {
2741 secret.data = new_val->data;
2742 secret.length = new_val->length;
2745 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2746 if (!crypt_secret.length) {
2747 return NT_STATUS_NO_MEMORY;
2749 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2750 if (!r->out.new_val->buf) {
2751 return NT_STATUS_NO_MEMORY;
2753 r->out.new_val->buf->length = crypt_secret.length;
2754 r->out.new_val->buf->size = crypt_secret.length;
2755 r->out.new_val->buf->data = crypt_secret.data;
2759 if (r->in.new_mtime) {
2760 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2761 if (!r->out.new_mtime) {
2762 return NT_STATUS_NO_MEMORY;
2764 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2767 return NT_STATUS_OK;
2774 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2775 TALLOC_CTX *mem_ctx,
2776 struct lsa_LookupPrivValue *r)
2778 struct dcesrv_handle *h;
2779 struct lsa_policy_state *state;
2782 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2786 id = sec_privilege_id(r->in.name->string);
2788 return NT_STATUS_NO_SUCH_PRIVILEGE;
2791 r->out.luid->low = id;
2792 r->out.luid->high = 0;
2794 return NT_STATUS_OK;
2801 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2802 TALLOC_CTX *mem_ctx,
2803 struct lsa_LookupPrivName *r)
2805 struct dcesrv_handle *h;
2806 struct lsa_policy_state *state;
2807 struct lsa_StringLarge *name;
2808 const char *privname;
2810 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2814 if (r->in.luid->high != 0) {
2815 return NT_STATUS_NO_SUCH_PRIVILEGE;
2818 privname = sec_privilege_name(r->in.luid->low);
2819 if (privname == NULL) {
2820 return NT_STATUS_NO_SUCH_PRIVILEGE;
2823 name = talloc(mem_ctx, struct lsa_StringLarge);
2825 return NT_STATUS_NO_MEMORY;
2828 name->string = privname;
2830 *r->out.name = name;
2832 return NT_STATUS_OK;
2837 lsa_LookupPrivDisplayName
2839 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2840 TALLOC_CTX *mem_ctx,
2841 struct lsa_LookupPrivDisplayName *r)
2843 struct dcesrv_handle *h;
2844 struct lsa_policy_state *state;
2845 struct lsa_StringLarge *disp_name = NULL;
2848 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2852 id = sec_privilege_id(r->in.name->string);
2854 return NT_STATUS_NO_SUCH_PRIVILEGE;
2857 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2858 if (disp_name == NULL) {
2859 return NT_STATUS_NO_MEMORY;
2862 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
2863 if (disp_name->string == NULL) {
2864 return NT_STATUS_INTERNAL_ERROR;
2867 *r->out.disp_name = disp_name;
2868 *r->out.returned_language_id = 0;
2870 return NT_STATUS_OK;
2875 lsa_EnumAccountsWithUserRight
2877 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2878 TALLOC_CTX *mem_ctx,
2879 struct lsa_EnumAccountsWithUserRight *r)
2881 struct dcesrv_handle *h;
2882 struct lsa_policy_state *state;
2884 struct ldb_message **res;
2885 const char * const attrs[] = { "objectSid", NULL};
2886 const char *privname;
2888 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2892 if (r->in.name == NULL) {
2893 return NT_STATUS_NO_SUCH_PRIVILEGE;
2896 privname = r->in.name->string;
2897 if (sec_privilege_id(privname) == -1) {
2898 return NT_STATUS_NO_SUCH_PRIVILEGE;
2901 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2902 "privilege=%s", privname);
2904 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2907 return NT_STATUS_NO_MORE_ENTRIES;
2910 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2911 if (r->out.sids->sids == NULL) {
2912 return NT_STATUS_NO_MEMORY;
2914 for (i=0;i<ret;i++) {
2915 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2916 res[i], "objectSid");
2917 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2919 r->out.sids->num_sids = ret;
2921 return NT_STATUS_OK;
2926 lsa_AddAccountRights
2928 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2929 TALLOC_CTX *mem_ctx,
2930 struct lsa_AddAccountRights *r)
2932 struct dcesrv_handle *h;
2933 struct lsa_policy_state *state;
2935 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2939 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2941 r->in.sid, r->in.rights);
2946 lsa_RemoveAccountRights
2948 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2949 TALLOC_CTX *mem_ctx,
2950 struct lsa_RemoveAccountRights *r)
2952 struct dcesrv_handle *h;
2953 struct lsa_policy_state *state;
2955 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2959 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2960 LDB_FLAG_MOD_DELETE,
2961 r->in.sid, r->in.rights);
2966 lsa_StorePrivateData
2968 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2969 struct lsa_StorePrivateData *r)
2971 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2976 lsa_RetrievePrivateData
2978 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2979 struct lsa_RetrievePrivateData *r)
2981 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2988 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2989 struct lsa_GetUserName *r)
2991 NTSTATUS status = NT_STATUS_OK;
2992 const char *account_name;
2993 const char *authority_name;
2994 struct lsa_String *_account_name;
2995 struct lsa_String *_authority_name = NULL;
2997 /* this is what w2k3 does */
2998 r->out.account_name = r->in.account_name;
2999 r->out.authority_name = r->in.authority_name;
3001 if (r->in.account_name
3002 && *r->in.account_name
3003 /* && *(*r->in.account_name)->string */
3005 return NT_STATUS_INVALID_PARAMETER;
3008 if (r->in.authority_name
3009 && *r->in.authority_name
3010 /* && *(*r->in.authority_name)->string */
3012 return NT_STATUS_INVALID_PARAMETER;
3015 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
3016 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
3018 _account_name = talloc(mem_ctx, struct lsa_String);
3019 NT_STATUS_HAVE_NO_MEMORY(_account_name);
3020 _account_name->string = account_name;
3022 if (r->in.authority_name) {
3023 _authority_name = talloc(mem_ctx, struct lsa_String);
3024 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
3025 _authority_name->string = authority_name;
3028 *r->out.account_name = _account_name;
3029 if (r->out.authority_name) {
3030 *r->out.authority_name = _authority_name;
3039 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
3040 TALLOC_CTX *mem_ctx,
3041 struct lsa_SetInfoPolicy2 *r)
3043 /* need to support these */
3044 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3048 lsa_QueryDomainInformationPolicy
3050 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3051 TALLOC_CTX *mem_ctx,
3052 struct lsa_QueryDomainInformationPolicy *r)
3054 union lsa_DomainInformationPolicy *info;
3056 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
3058 return NT_STATUS_NO_MEMORY;
3061 switch (r->in.level) {
3062 case LSA_DOMAIN_INFO_POLICY_EFS:
3064 *r->out.info = NULL;
3065 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3066 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
3068 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
3069 struct smb_krb5_context *smb_krb5_context;
3070 int ret = smb_krb5_init_context(mem_ctx,
3071 dce_call->event_ctx,
3072 dce_call->conn->dce_ctx->lp_ctx,
3076 *r->out.info = NULL;
3077 return NT_STATUS_INTERNAL_ERROR;
3079 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
3080 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3081 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
3082 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
3083 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
3084 talloc_free(smb_krb5_context);
3085 *r->out.info = info;
3086 return NT_STATUS_OK;
3090 *r->out.info = NULL;
3091 return NT_STATUS_INVALID_INFO_CLASS;
3096 lsa_SetDomInfoPolicy
3098 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3099 TALLOC_CTX *mem_ctx,
3100 struct lsa_SetDomainInformationPolicy *r)
3102 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3108 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3109 TALLOC_CTX *mem_ctx,
3110 struct lsa_TestCall *r)
3112 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3118 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3119 struct lsa_CREDRWRITE *r)
3121 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3128 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3129 struct lsa_CREDRREAD *r)
3131 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3138 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3139 struct lsa_CREDRENUMERATE *r)
3141 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3146 lsa_CREDRWRITEDOMAINCREDENTIALS
3148 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3149 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3151 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3156 lsa_CREDRREADDOMAINCREDENTIALS
3158 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3159 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3161 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3168 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3169 struct lsa_CREDRDELETE *r)
3171 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3176 lsa_CREDRGETTARGETINFO
3178 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3179 struct lsa_CREDRGETTARGETINFO *r)
3181 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3186 lsa_CREDRPROFILELOADED
3188 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3189 struct lsa_CREDRPROFILELOADED *r)
3191 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3196 lsa_CREDRGETSESSIONTYPES
3198 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3199 struct lsa_CREDRGETSESSIONTYPES *r)
3201 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3206 lsa_LSARREGISTERAUDITEVENT
3208 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3209 struct lsa_LSARREGISTERAUDITEVENT *r)
3211 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3216 lsa_LSARGENAUDITEVENT
3218 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3219 struct lsa_LSARGENAUDITEVENT *r)
3221 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3226 lsa_LSARUNREGISTERAUDITEVENT
3228 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3229 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3231 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3236 lsa_lsaRQueryForestTrustInformation
3238 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3239 struct lsa_lsaRQueryForestTrustInformation *r)
3241 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3246 lsa_LSARSETFORESTTRUSTINFORMATION
3248 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3249 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3251 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3258 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3259 struct lsa_CREDRRENAME *r)
3261 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3267 lsa_LSAROPENPOLICYSCE
3269 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3270 struct lsa_LSAROPENPOLICYSCE *r)
3272 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3277 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3279 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3280 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3282 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3287 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3289 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3290 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3292 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3297 lsa_LSARADTREPORTSECURITYEVENT
3299 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3300 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3302 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3306 /* include the generated boilerplate */
3307 #include "librpc/gen_ndr/ndr_lsa_s.c"
3311 /*****************************************
3312 NOTE! The remaining calls below were
3313 removed in w2k3, so the DCESRV_FAULT()
3314 replies are the correct implementation. Do
3315 not try and fill these in with anything else
3316 ******************************************/
3319 dssetup_DsRoleDnsNameToFlatName
3321 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3322 struct dssetup_DsRoleDnsNameToFlatName *r)
3324 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3329 dssetup_DsRoleDcAsDc
3331 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3332 struct dssetup_DsRoleDcAsDc *r)
3334 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3339 dssetup_DsRoleDcAsReplica
3341 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3342 struct dssetup_DsRoleDcAsReplica *r)
3344 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3349 dssetup_DsRoleDemoteDc
3351 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3352 struct dssetup_DsRoleDemoteDc *r)
3354 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3359 dssetup_DsRoleGetDcOperationProgress
3361 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3362 struct dssetup_DsRoleGetDcOperationProgress *r)
3364 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3369 dssetup_DsRoleGetDcOperationResults
3371 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3372 struct dssetup_DsRoleGetDcOperationResults *r)
3374 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3379 dssetup_DsRoleCancel
3381 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3382 struct dssetup_DsRoleCancel *r)
3384 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3389 dssetup_DsRoleServerSaveStateForUpgrade
3391 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3392 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3394 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3399 dssetup_DsRoleUpgradeDownlevelServer
3401 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3402 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3404 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3409 dssetup_DsRoleAbortDownlevelServerUpgrade
3411 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3412 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3414 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3418 /* include the generated boilerplate */
3419 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3421 NTSTATUS dcerpc_server_lsa_init(void)
3425 ret = dcerpc_server_dssetup_init();
3426 if (!NT_STATUS_IS_OK(ret)) {
3429 ret = dcerpc_server_lsarpc_init();
3430 if (!NT_STATUS_IS_OK(ret)) {