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 "../lib/util/util_ldb.h"
27 #include "libcli/ldap/ldap_ndr.h"
28 #include "system/kerberos.h"
29 #include "auth/kerberos/kerberos.h"
30 #include "librpc/gen_ndr/ndr_drsblobs.h"
31 #include "librpc/gen_ndr/ndr_lsa.h"
32 #include "../lib/crypto/crypto.h"
35 this type allows us to distinguish handle types
39 state associated with a lsa_OpenAccount() operation
41 struct lsa_account_state {
42 struct lsa_policy_state *policy;
44 struct dom_sid *account_sid;
49 state associated with a lsa_OpenSecret() operation
51 struct lsa_secret_state {
52 struct lsa_policy_state *policy;
54 struct ldb_dn *secret_dn;
55 struct ldb_context *sam_ldb;
60 state associated with a lsa_OpenTrustedDomain() operation
62 struct lsa_trusted_domain_state {
63 struct lsa_policy_state *policy;
65 struct ldb_dn *trusted_domain_dn;
66 struct ldb_dn *trusted_domain_user_dn;
69 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
71 struct lsa_EnumAccountRights *r);
73 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
75 struct lsa_policy_state *state,
78 const struct lsa_RightSet *rights);
83 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
86 struct dcesrv_handle *h;
88 *r->out.handle = *r->in.handle;
90 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
94 ZERO_STRUCTP(r->out.handle);
103 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
104 struct lsa_Delete *r)
106 return NT_STATUS_NOT_SUPPORTED;
113 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
114 struct lsa_DeleteObject *r)
116 struct dcesrv_handle *h;
119 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
121 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
122 struct lsa_secret_state *secret_state = h->data;
124 /* Ensure user is permitted to delete this... */
125 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
127 case SECURITY_SYSTEM:
128 case SECURITY_ADMINISTRATOR:
131 /* Users and annonymous are not allowed delete things */
132 return NT_STATUS_ACCESS_DENIED;
135 ret = ldb_delete(secret_state->sam_ldb,
136 secret_state->secret_dn);
139 return NT_STATUS_INVALID_HANDLE;
142 ZERO_STRUCTP(r->out.handle);
145 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
146 struct lsa_trusted_domain_state *trusted_domain_state =
147 talloc_get_type(h->data, struct lsa_trusted_domain_state);
148 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
150 return NT_STATUS_INTERNAL_DB_CORRUPTION;
153 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
154 trusted_domain_state->trusted_domain_dn);
156 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
157 return NT_STATUS_INVALID_HANDLE;
160 if (trusted_domain_state->trusted_domain_user_dn) {
161 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
162 trusted_domain_state->trusted_domain_user_dn);
164 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
165 return NT_STATUS_INVALID_HANDLE;
169 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
171 return NT_STATUS_INTERNAL_DB_CORRUPTION;
174 ZERO_STRUCTP(r->out.handle);
177 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
178 struct lsa_RightSet *rights;
179 struct lsa_account_state *astate;
180 struct lsa_EnumAccountRights r2;
183 rights = talloc(mem_ctx, struct lsa_RightSet);
185 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
189 r2.in.handle = &astate->policy->handle->wire_handle;
190 r2.in.sid = astate->account_sid;
191 r2.out.rights = rights;
193 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
194 but we have a LSA_HANDLE_ACCOUNT here, so this call
196 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
197 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
201 if (!NT_STATUS_IS_OK(status)) {
205 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
206 LDB_FLAG_MOD_DELETE, astate->account_sid,
208 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
212 if (!NT_STATUS_IS_OK(status)) {
216 ZERO_STRUCTP(r->out.handle);
219 return NT_STATUS_INVALID_HANDLE;
226 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
227 struct lsa_EnumPrivs *r)
229 struct dcesrv_handle *h;
230 struct lsa_policy_state *state;
232 const char *privname;
234 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
238 i = *r->in.resume_handle;
241 while ((privname = sec_privilege_name(i)) &&
242 r->out.privs->count < r->in.max_count) {
243 struct lsa_PrivEntry *e;
245 r->out.privs->privs = talloc_realloc(r->out.privs,
247 struct lsa_PrivEntry,
248 r->out.privs->count+1);
249 if (r->out.privs->privs == NULL) {
250 return NT_STATUS_NO_MEMORY;
252 e = &r->out.privs->privs[r->out.privs->count];
255 e->name.string = privname;
256 r->out.privs->count++;
260 *r->out.resume_handle = i;
269 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
270 struct lsa_QuerySecurity *r)
272 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
279 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
280 struct lsa_SetSecObj *r)
282 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
289 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
290 struct lsa_ChangePassword *r)
292 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
296 dssetup_DsRoleGetPrimaryDomainInformation
298 This is not an LSA call, but is the only call left on the DSSETUP
299 pipe (after the pipe was truncated), and needs lsa_get_policy_state
301 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
303 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
305 union dssetup_DsRoleInfo *info;
307 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
308 W_ERROR_HAVE_NO_MEMORY(info);
310 switch (r->in.level) {
311 case DS_ROLE_BASIC_INFORMATION:
313 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
315 const char *domain = NULL;
316 const char *dns_domain = NULL;
317 const char *forest = NULL;
318 struct GUID domain_guid;
319 struct lsa_policy_state *state;
321 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
322 if (!NT_STATUS_IS_OK(status)) {
323 return ntstatus_to_werror(status);
326 ZERO_STRUCT(domain_guid);
328 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
329 case ROLE_STANDALONE:
330 role = DS_ROLE_STANDALONE_SERVER;
332 case ROLE_DOMAIN_MEMBER:
333 role = DS_ROLE_MEMBER_SERVER;
335 case ROLE_DOMAIN_CONTROLLER:
336 if (samdb_is_pdc(state->sam_ldb)) {
337 role = DS_ROLE_PRIMARY_DC;
339 role = DS_ROLE_BACKUP_DC;
344 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
345 case ROLE_STANDALONE:
346 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
347 W_ERROR_HAVE_NO_MEMORY(domain);
349 case ROLE_DOMAIN_MEMBER:
350 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
351 W_ERROR_HAVE_NO_MEMORY(domain);
352 /* TODO: what is with dns_domain and forest and guid? */
354 case ROLE_DOMAIN_CONTROLLER:
355 flags = DS_ROLE_PRIMARY_DS_RUNNING;
357 if (state->mixed_domain == 1) {
358 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
361 domain = state->domain_name;
362 dns_domain = state->domain_dns;
363 forest = state->forest_dns;
365 domain_guid = state->domain_guid;
366 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
370 info->basic.role = role;
371 info->basic.flags = flags;
372 info->basic.domain = domain;
373 info->basic.dns_domain = dns_domain;
374 info->basic.forest = forest;
375 info->basic.domain_guid = domain_guid;
380 case DS_ROLE_UPGRADE_STATUS:
382 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
383 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
388 case DS_ROLE_OP_STATUS:
390 info->opstatus.status = DS_ROLE_OP_IDLE;
396 return WERR_INVALID_PARAM;
399 return WERR_INVALID_PARAM;
403 fill in the AccountDomain info
405 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
406 struct lsa_DomainInfo *info)
408 info->name.string = state->domain_name;
409 info->sid = state->domain_sid;
415 fill in the DNS domain info
417 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
418 struct lsa_DnsDomainInfo *info)
420 info->name.string = state->domain_name;
421 info->sid = state->domain_sid;
422 info->dns_domain.string = state->domain_dns;
423 info->dns_forest.string = state->forest_dns;
424 info->domain_guid = state->domain_guid;
432 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
433 struct lsa_QueryInfoPolicy2 *r)
435 struct lsa_policy_state *state;
436 struct dcesrv_handle *h;
440 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
444 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
446 return NT_STATUS_NO_MEMORY;
449 ZERO_STRUCTP(r->out.info);
451 switch (r->in.level) {
452 case LSA_POLICY_INFO_AUDIT_LOG:
453 /* we don't need to fill in any of this */
454 ZERO_STRUCT(r->out.info->audit_log);
456 case LSA_POLICY_INFO_AUDIT_EVENTS:
457 /* we don't need to fill in any of this */
458 ZERO_STRUCT(r->out.info->audit_events);
460 case LSA_POLICY_INFO_PD:
461 /* we don't need to fill in any of this */
462 ZERO_STRUCT(r->out.info->pd);
465 case LSA_POLICY_INFO_DOMAIN:
466 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->domain);
467 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
468 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
469 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
470 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->l_account_domain);
473 case LSA_POLICY_INFO_ROLE:
474 r->out.info->role.role = LSA_ROLE_PRIMARY;
477 case LSA_POLICY_INFO_DNS:
478 case LSA_POLICY_INFO_DNS_INT:
479 return dcesrv_lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
481 case LSA_POLICY_INFO_REPLICA:
482 ZERO_STRUCT(r->out.info->replica);
485 case LSA_POLICY_INFO_QUOTA:
486 ZERO_STRUCT(r->out.info->quota);
489 case LSA_POLICY_INFO_MOD:
490 case LSA_POLICY_INFO_AUDIT_FULL_SET:
491 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
492 /* windows gives INVALID_PARAMETER */
494 return NT_STATUS_INVALID_PARAMETER;
498 return NT_STATUS_INVALID_INFO_CLASS;
504 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
505 struct lsa_QueryInfoPolicy *r)
507 struct lsa_QueryInfoPolicy2 r2;
512 r2.in.handle = r->in.handle;
513 r2.in.level = r->in.level;
515 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
517 r->out.info = r2.out.info;
525 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
526 struct lsa_SetInfoPolicy *r)
528 /* need to support this */
529 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
536 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
537 struct lsa_ClearAuditLog *r)
539 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
546 This call does not seem to have any long-term effects, hence no database operations
548 we need to talk to the MS product group to find out what this account database means!
550 answer is that the lsa database is totally separate from the SAM and
551 ldap databases. We are going to need a separate ldb to store these
552 accounts. The SIDs on this account bear no relation to the SIDs in
555 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
556 struct lsa_CreateAccount *r)
558 struct lsa_account_state *astate;
560 struct lsa_policy_state *state;
561 struct dcesrv_handle *h, *ah;
563 ZERO_STRUCTP(r->out.acct_handle);
565 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
569 astate = talloc(dce_call->conn, struct lsa_account_state);
570 if (astate == NULL) {
571 return NT_STATUS_NO_MEMORY;
574 astate->account_sid = dom_sid_dup(astate, r->in.sid);
575 if (astate->account_sid == NULL) {
577 return NT_STATUS_NO_MEMORY;
580 astate->policy = talloc_reference(astate, state);
581 astate->access_mask = r->in.access_mask;
583 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
586 return NT_STATUS_NO_MEMORY;
589 ah->data = talloc_steal(ah, astate);
591 *r->out.acct_handle = ah->wire_handle;
600 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
601 struct lsa_EnumAccounts *r)
603 struct dcesrv_handle *h;
604 struct lsa_policy_state *state;
606 struct ldb_message **res;
607 const char * const attrs[] = { "objectSid", NULL};
610 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
614 /* NOTE: This call must only return accounts that have at least
617 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
618 "(&(objectSid=*)(privilege=*))");
620 return NT_STATUS_NO_SUCH_USER;
623 if (*r->in.resume_handle >= ret) {
624 return NT_STATUS_NO_MORE_ENTRIES;
627 count = ret - *r->in.resume_handle;
628 if (count > r->in.num_entries) {
629 count = r->in.num_entries;
633 return NT_STATUS_NO_MORE_ENTRIES;
636 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
637 if (r->out.sids->sids == NULL) {
638 return NT_STATUS_NO_MEMORY;
641 for (i=0;i<count;i++) {
642 r->out.sids->sids[i].sid =
643 samdb_result_dom_sid(r->out.sids->sids,
644 res[i + *r->in.resume_handle],
646 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
649 r->out.sids->num_sids = count;
650 *r->out.resume_handle = count + *r->in.resume_handle;
658 lsa_CreateTrustedDomainEx2
660 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
662 struct lsa_CreateTrustedDomainEx2 *r,
665 struct dcesrv_handle *policy_handle;
666 struct lsa_policy_state *policy_state;
667 struct lsa_trusted_domain_state *trusted_domain_state;
668 struct dcesrv_handle *handle;
669 struct ldb_message **msgs, *msg, *msg_user;
670 const char *attrs[] = {
673 const char *netbios_name;
674 const char *dns_name;
676 DATA_BLOB session_key = data_blob(NULL, 0);
677 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
678 struct trustDomainPasswords auth_struct;
681 enum ndr_err_code ndr_err;
683 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
684 ZERO_STRUCTP(r->out.trustdom_handle);
686 policy_state = policy_handle->data;
688 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
689 if (!NT_STATUS_IS_OK(nt_status)) {
693 netbios_name = r->in.info->netbios_name.string;
695 return NT_STATUS_INVALID_PARAMETER;
698 dns_name = r->in.info->domain_name.string;
700 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
701 if (!trusted_domain_state) {
702 return NT_STATUS_NO_MEMORY;
704 trusted_domain_state->policy = policy_state;
706 if (strcasecmp(netbios_name, "BUILTIN") == 0
707 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
708 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
709 return NT_STATUS_INVALID_PARAMETER;;
712 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
713 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
714 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
715 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
716 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
717 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
720 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
721 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
722 /* No secrets are created at this time, for this function */
723 auth_struct.outgoing.count = 0;
724 auth_struct.incoming.count = 0;
726 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data, r->in.auth_info->auth_blob.size);
727 arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key);
728 ndr_err = ndr_pull_struct_blob(&auth_blob, mem_ctx,
729 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
731 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
732 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
733 return NT_STATUS_INVALID_PARAMETER;
736 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
737 if (auth_struct.incoming.count > 1) {
738 return NT_STATUS_INVALID_PARAMETER;
743 if (auth_struct.incoming.count) {
745 struct trustAuthInOutBlob incoming;
747 incoming.count = auth_struct.incoming.count;
748 incoming.current = talloc(mem_ctx, struct AuthenticationInformationArray);
749 if (!incoming.current) {
750 return NT_STATUS_NO_MEMORY;
753 incoming.current->array = *auth_struct.incoming.current;
754 if (!incoming.current->array) {
755 return NT_STATUS_NO_MEMORY;
758 incoming.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
759 if (!incoming.previous) {
760 return NT_STATUS_NO_MEMORY;
762 incoming.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, incoming.count);
763 if (!incoming.previous->array) {
764 return NT_STATUS_NO_MEMORY;
767 for (i = 0; i < incoming.count; i++) {
768 incoming.previous->array[i].LastUpdateTime = 0;
769 incoming.previous->array[i].AuthType = 0;
771 ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx,
772 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
774 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
775 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
776 return NT_STATUS_INVALID_PARAMETER;
779 trustAuthIncoming = data_blob(NULL, 0);
782 if (auth_struct.outgoing.count) {
784 struct trustAuthInOutBlob outgoing;
786 outgoing.count = auth_struct.outgoing.count;
787 outgoing.current = talloc(mem_ctx, struct AuthenticationInformationArray);
788 if (!outgoing.current) {
789 return NT_STATUS_NO_MEMORY;
792 outgoing.current->array = *auth_struct.outgoing.current;
793 if (!outgoing.current->array) {
794 return NT_STATUS_NO_MEMORY;
797 outgoing.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
798 if (!outgoing.previous) {
799 return NT_STATUS_NO_MEMORY;
801 outgoing.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, outgoing.count);
802 if (!outgoing.previous->array) {
803 return NT_STATUS_NO_MEMORY;
806 for (i = 0; i < outgoing.count; i++) {
807 outgoing.previous->array[i].LastUpdateTime = 0;
808 outgoing.previous->array[i].AuthType = 0;
810 ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx,
811 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
813 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
814 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
815 return NT_STATUS_INVALID_PARAMETER;
818 trustAuthOutgoing = data_blob(NULL, 0);
821 ret = ldb_transaction_start(policy_state->sam_ldb);
822 if (ret != LDB_SUCCESS) {
823 return NT_STATUS_INTERNAL_DB_CORRUPTION;
827 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
828 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
829 /* search for the trusted_domain record */
830 ret = gendb_search(policy_state->sam_ldb,
831 mem_ctx, policy_state->system_dn, &msgs, attrs,
832 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
833 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
835 ldb_transaction_cancel(policy_state->sam_ldb);
836 return NT_STATUS_OBJECT_NAME_COLLISION;
839 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
840 /* search for the trusted_domain record */
841 ret = gendb_search(policy_state->sam_ldb,
842 mem_ctx, policy_state->system_dn, &msgs, attrs,
843 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
844 netbios_encoded, netbios_encoded, netbios_encoded);
846 ldb_transaction_cancel(policy_state->sam_ldb);
847 return NT_STATUS_OBJECT_NAME_COLLISION;
852 ldb_transaction_cancel(policy_state->sam_ldb);
853 return NT_STATUS_INTERNAL_DB_CORRUPTION;
856 name = dns_name ? dns_name : netbios_name;
858 msg = ldb_msg_new(mem_ctx);
860 return NT_STATUS_NO_MEMORY;
863 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
864 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
865 ldb_transaction_cancel(policy_state->sam_ldb);
866 return NT_STATUS_NO_MEMORY;
869 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", netbios_name);
871 if (r->in.info->sid) {
872 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
874 ldb_transaction_cancel(policy_state->sam_ldb);
875 return NT_STATUS_NO_MEMORY;
878 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
881 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
883 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
885 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
887 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
890 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
893 if (trustAuthIncoming.data) {
894 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
895 if (ret != LDB_SUCCESS) {
896 ldb_transaction_cancel(policy_state->sam_ldb);
897 return NT_STATUS_NO_MEMORY;
900 if (trustAuthOutgoing.data) {
901 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
902 if (ret != LDB_SUCCESS) {
903 ldb_transaction_cancel(policy_state->sam_ldb);
904 return NT_STATUS_NO_MEMORY;
908 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
910 /* create the trusted_domain */
911 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
915 case LDB_ERR_ENTRY_ALREADY_EXISTS:
916 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
917 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
918 ldb_dn_get_linearized(msg->dn),
919 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
920 return NT_STATUS_DOMAIN_EXISTS;
921 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
922 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
923 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
924 ldb_dn_get_linearized(msg->dn),
925 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
926 return NT_STATUS_ACCESS_DENIED;
928 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
929 DEBUG(0,("Failed to create user record %s: %s\n",
930 ldb_dn_get_linearized(msg->dn),
931 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
932 return NT_STATUS_INTERNAL_DB_CORRUPTION;
935 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
936 msg_user = ldb_msg_new(mem_ctx);
938 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
939 return NT_STATUS_NO_MEMORY;
942 /* Inbound trusts must also create a cn=users object to match */
944 trusted_domain_state->trusted_domain_user_dn = msg_user->dn
945 = ldb_dn_copy(trusted_domain_state, policy_state->domain_dn);
946 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=users")) {
947 ldb_transaction_cancel(policy_state->sam_ldb);
948 return NT_STATUS_NO_MEMORY;
951 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=%s", netbios_name)) {
952 ldb_transaction_cancel(policy_state->sam_ldb);
953 return NT_STATUS_NO_MEMORY;
956 ldb_msg_add_string(msg_user, "objectClass", "user");
958 ldb_msg_add_steal_string(msg_user, "samAccountName",
959 talloc_asprintf(mem_ctx, "%s$", netbios_name));
961 if (samdb_msg_add_uint(trusted_domain_state->policy->sam_ldb, mem_ctx, msg_user,
962 "userAccountControl",
963 UF_INTERDOMAIN_TRUST_ACCOUNT) != 0) {
964 ldb_transaction_cancel(policy_state->sam_ldb);
965 return NT_STATUS_NO_MEMORY;
968 if (auth_struct.incoming.count) {
970 for (i=0; i < auth_struct.incoming.count; i++ ) {
971 if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_NT4OWF) {
972 samdb_msg_add_hash(trusted_domain_state->policy->sam_ldb,
973 mem_ctx, msg_user, "unicodePwd",
974 &auth_struct.incoming.current[i]->AuthInfo.nt4owf.password);
975 } else if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_CLEAR) {
976 DATA_BLOB new_password = data_blob_const(auth_struct.incoming.current[i]->AuthInfo.clear.password,
977 auth_struct.incoming.current[i]->AuthInfo.clear.size);
978 ret = ldb_msg_add_value(msg_user, "clearTextPassword", &new_password, NULL);
979 if (ret != LDB_SUCCESS) {
980 ldb_transaction_cancel(policy_state->sam_ldb);
981 return NT_STATUS_NO_MEMORY;
987 /* create the cn=users trusted_domain account */
988 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg_user);
992 case LDB_ERR_ENTRY_ALREADY_EXISTS:
993 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
994 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
995 ldb_dn_get_linearized(msg_user->dn),
996 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
997 return NT_STATUS_DOMAIN_EXISTS;
998 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
999 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1000 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1001 ldb_dn_get_linearized(msg_user->dn),
1002 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1003 return NT_STATUS_ACCESS_DENIED;
1005 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1006 DEBUG(0,("Failed to create user record %s: %s\n",
1007 ldb_dn_get_linearized(msg_user->dn),
1008 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1009 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1013 ret = ldb_transaction_commit(policy_state->sam_ldb);
1014 if (ret != LDB_SUCCESS) {
1015 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1018 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1020 return NT_STATUS_NO_MEMORY;
1023 handle->data = talloc_steal(handle, trusted_domain_state);
1025 trusted_domain_state->access_mask = r->in.access_mask;
1026 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1028 *r->out.trustdom_handle = handle->wire_handle;
1030 return NT_STATUS_OK;
1034 lsa_CreateTrustedDomainEx2
1036 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1037 TALLOC_CTX *mem_ctx,
1038 struct lsa_CreateTrustedDomainEx2 *r)
1040 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
1043 lsa_CreateTrustedDomainEx
1045 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1046 TALLOC_CTX *mem_ctx,
1047 struct lsa_CreateTrustedDomainEx *r)
1049 struct lsa_CreateTrustedDomainEx2 r2;
1051 r2.in.policy_handle = r->in.policy_handle;
1052 r2.in.info = r->in.info;
1053 r2.in.auth_info = r->in.auth_info;
1054 r2.out.trustdom_handle = r->out.trustdom_handle;
1055 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
1059 lsa_CreateTrustedDomain
1061 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1062 struct lsa_CreateTrustedDomain *r)
1064 struct lsa_CreateTrustedDomainEx2 r2;
1066 r2.in.policy_handle = r->in.policy_handle;
1067 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1069 return NT_STATUS_NO_MEMORY;
1072 r2.in.info->domain_name.string = NULL;
1073 r2.in.info->netbios_name = r->in.info->name;
1074 r2.in.info->sid = r->in.info->sid;
1075 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1076 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1077 r2.in.info->trust_attributes = 0;
1079 r2.in.access_mask = r->in.access_mask;
1080 r2.out.trustdom_handle = r->out.trustdom_handle;
1082 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1087 lsa_OpenTrustedDomain
1089 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1090 struct lsa_OpenTrustedDomain *r)
1092 struct dcesrv_handle *policy_handle;
1094 struct lsa_policy_state *policy_state;
1095 struct lsa_trusted_domain_state *trusted_domain_state;
1096 struct dcesrv_handle *handle;
1097 struct ldb_message **msgs;
1098 const char *attrs[] = {
1104 const char *sid_string;
1107 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1108 ZERO_STRUCTP(r->out.trustdom_handle);
1109 policy_state = policy_handle->data;
1111 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1112 if (!trusted_domain_state) {
1113 return NT_STATUS_NO_MEMORY;
1115 trusted_domain_state->policy = policy_state;
1117 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1119 return NT_STATUS_NO_MEMORY;
1122 /* search for the trusted_domain record */
1123 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1124 mem_ctx, policy_state->system_dn, &msgs, attrs,
1125 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
1128 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1132 DEBUG(0,("Found %d records matching DN %s\n", ret,
1133 ldb_dn_get_linearized(policy_state->system_dn)));
1134 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1137 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1139 trusted_domain_state->trusted_domain_user_dn = NULL;
1141 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1142 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1143 /* search for the trusted_domain record */
1144 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1145 mem_ctx, policy_state->domain_dn, &msgs, attrs,
1146 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%d))",
1147 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1149 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1152 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1154 return NT_STATUS_NO_MEMORY;
1157 handle->data = talloc_steal(handle, trusted_domain_state);
1159 trusted_domain_state->access_mask = r->in.access_mask;
1160 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1162 *r->out.trustdom_handle = handle->wire_handle;
1164 return NT_STATUS_OK;
1169 lsa_OpenTrustedDomainByName
1171 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1172 TALLOC_CTX *mem_ctx,
1173 struct lsa_OpenTrustedDomainByName *r)
1175 struct dcesrv_handle *policy_handle;
1177 struct lsa_policy_state *policy_state;
1178 struct lsa_trusted_domain_state *trusted_domain_state;
1179 struct dcesrv_handle *handle;
1180 struct ldb_message **msgs;
1181 const char *attrs[] = {
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 if (!r->in.name.string) {
1192 return NT_STATUS_INVALID_PARAMETER;
1195 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1196 if (!trusted_domain_state) {
1197 return NT_STATUS_NO_MEMORY;
1199 trusted_domain_state->policy = policy_state;
1201 /* search for the trusted_domain record */
1202 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1203 mem_ctx, policy_state->system_dn, &msgs, attrs,
1204 "(&(flatname=%s)(objectclass=trustedDomain))",
1205 ldb_binary_encode_string(mem_ctx, r->in.name.string));
1207 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1211 DEBUG(0,("Found %d records matching DN %s\n", ret,
1212 ldb_dn_get_linearized(policy_state->system_dn)));
1213 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1216 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1218 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1220 return NT_STATUS_NO_MEMORY;
1223 handle->data = talloc_steal(handle, trusted_domain_state);
1225 trusted_domain_state->access_mask = r->in.access_mask;
1226 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1228 *r->out.trustdom_handle = handle->wire_handle;
1230 return NT_STATUS_OK;
1236 lsa_SetTrustedDomainInfo
1238 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1239 struct lsa_SetTrustedDomainInfo *r)
1241 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1247 lsa_SetInfomrationTrustedDomain
1249 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1250 TALLOC_CTX *mem_ctx,
1251 struct lsa_SetInformationTrustedDomain *r)
1253 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1258 lsa_DeleteTrustedDomain
1260 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1261 struct lsa_DeleteTrustedDomain *r)
1264 struct lsa_OpenTrustedDomain open;
1265 struct lsa_DeleteObject delete;
1266 struct dcesrv_handle *h;
1268 open.in.handle = r->in.handle;
1269 open.in.sid = r->in.dom_sid;
1270 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1271 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1272 if (!open.out.trustdom_handle) {
1273 return NT_STATUS_NO_MEMORY;
1275 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1276 if (!NT_STATUS_IS_OK(status)) {
1280 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1281 talloc_steal(mem_ctx, h);
1283 delete.in.handle = open.out.trustdom_handle;
1284 delete.out.handle = open.out.trustdom_handle;
1285 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &delete);
1286 if (!NT_STATUS_IS_OK(status)) {
1289 return NT_STATUS_OK;
1292 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1293 struct ldb_message *msg,
1294 struct lsa_TrustDomainInfoInfoEx *info_ex)
1296 info_ex->domain_name.string
1297 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1298 info_ex->netbios_name.string
1299 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1301 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1302 info_ex->trust_direction
1303 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1305 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1306 info_ex->trust_attributes
1307 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1308 return NT_STATUS_OK;
1312 lsa_QueryTrustedDomainInfo
1314 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1315 struct lsa_QueryTrustedDomainInfo *r)
1317 union lsa_TrustedDomainInfo *info = NULL;
1318 struct dcesrv_handle *h;
1319 struct lsa_trusted_domain_state *trusted_domain_state;
1320 struct ldb_message *msg;
1322 struct ldb_message **res;
1323 const char *attrs[] = {
1326 "securityIdentifier",
1330 "msDs-supportedEncryptionTypes",
1334 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1336 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1338 /* pull all the user attributes */
1339 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1340 trusted_domain_state->trusted_domain_dn, &res, attrs);
1342 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1346 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
1348 return NT_STATUS_NO_MEMORY;
1350 *r->out.info = info;
1352 switch (r->in.level) {
1353 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1354 info->name.netbios_name.string
1355 = samdb_result_string(msg, "flatname", NULL);
1357 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1358 info->posix_offset.posix_offset
1359 = samdb_result_uint(msg, "posixOffset", 0);
1361 #if 0 /* Win2k3 doesn't implement this */
1362 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1363 r->out.info->info_basic.netbios_name.string
1364 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1365 r->out.info->info_basic.sid
1366 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1369 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1370 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
1372 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1373 ZERO_STRUCT(info->full_info);
1374 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
1376 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1377 ZERO_STRUCT(info->full_info2_internal);
1378 info->full_info2_internal.posix_offset.posix_offset
1379 = samdb_result_uint(msg, "posixOffset", 0);
1380 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
1382 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
1383 info->enc_types.enc_types
1384 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
1387 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1388 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1389 /* oops, we don't want to return the info after all */
1392 return NT_STATUS_INVALID_PARAMETER;
1394 /* oops, we don't want to return the info after all */
1397 return NT_STATUS_INVALID_INFO_CLASS;
1400 return NT_STATUS_OK;
1405 lsa_QueryTrustedDomainInfoBySid
1407 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1408 struct lsa_QueryTrustedDomainInfoBySid *r)
1411 struct lsa_OpenTrustedDomain open;
1412 struct lsa_QueryTrustedDomainInfo query;
1413 union lsa_TrustedDomainInfo *info;
1414 struct dcesrv_handle *h;
1415 open.in.handle = r->in.handle;
1416 open.in.sid = r->in.dom_sid;
1417 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1418 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1419 if (!open.out.trustdom_handle) {
1420 return NT_STATUS_NO_MEMORY;
1422 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1423 if (!NT_STATUS_IS_OK(status)) {
1427 /* Ensure this handle goes away at the end of this call */
1428 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1429 talloc_steal(mem_ctx, h);
1431 query.in.trustdom_handle = open.out.trustdom_handle;
1432 query.in.level = r->in.level;
1433 query.out.info = r->out.info;
1434 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1435 if (!NT_STATUS_IS_OK(status)) {
1439 return NT_STATUS_OK;
1443 lsa_SetTrustedDomainInfoByName
1445 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1446 TALLOC_CTX *mem_ctx,
1447 struct lsa_SetTrustedDomainInfoByName *r)
1449 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1453 lsa_QueryTrustedDomainInfoByName
1455 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1456 TALLOC_CTX *mem_ctx,
1457 struct lsa_QueryTrustedDomainInfoByName *r)
1460 struct lsa_OpenTrustedDomainByName open;
1461 struct lsa_QueryTrustedDomainInfo query;
1462 struct dcesrv_handle *h;
1463 open.in.handle = r->in.handle;
1464 open.in.name = *r->in.trusted_domain;
1465 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1466 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1467 if (!open.out.trustdom_handle) {
1468 return NT_STATUS_NO_MEMORY;
1470 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1471 if (!NT_STATUS_IS_OK(status)) {
1475 /* Ensure this handle goes away at the end of this call */
1476 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1477 talloc_steal(mem_ctx, h);
1479 query.in.trustdom_handle = open.out.trustdom_handle;
1480 query.in.level = r->in.level;
1481 query.out.info = r->out.info;
1482 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1483 if (!NT_STATUS_IS_OK(status)) {
1487 return NT_STATUS_OK;
1491 lsa_CloseTrustedDomainEx
1493 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1494 TALLOC_CTX *mem_ctx,
1495 struct lsa_CloseTrustedDomainEx *r)
1497 /* The result of a bad hair day from an IDL programmer? Not
1498 * implmented in Win2k3. You should always just lsa_Close
1500 return NT_STATUS_NOT_IMPLEMENTED;
1505 comparison function for sorting lsa_DomainInformation array
1507 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1509 return strcasecmp_m(e1->name.string, e2->name.string);
1515 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1516 struct lsa_EnumTrustDom *r)
1518 struct dcesrv_handle *policy_handle;
1519 struct lsa_DomainInfo *entries;
1520 struct lsa_policy_state *policy_state;
1521 struct ldb_message **domains;
1522 const char *attrs[] = {
1524 "securityIdentifier",
1531 *r->out.resume_handle = 0;
1533 r->out.domains->domains = NULL;
1534 r->out.domains->count = 0;
1536 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1538 policy_state = policy_handle->data;
1540 /* search for all users in this domain. This could possibly be cached and
1541 resumed based on resume_key */
1542 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1543 "objectclass=trustedDomain");
1545 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1548 /* convert to lsa_TrustInformation format */
1549 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1551 return NT_STATUS_NO_MEMORY;
1553 for (i=0;i<count;i++) {
1554 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1555 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1558 /* sort the results by name */
1559 qsort(entries, count, sizeof(*entries),
1560 (comparison_fn_t)compare_DomainInfo);
1562 if (*r->in.resume_handle >= count) {
1563 *r->out.resume_handle = -1;
1565 return NT_STATUS_NO_MORE_ENTRIES;
1568 /* return the rest, limit by max_size. Note that we
1569 use the w2k3 element size value of 60 */
1570 r->out.domains->count = count - *r->in.resume_handle;
1571 r->out.domains->count = MIN(r->out.domains->count,
1572 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1574 r->out.domains->domains = entries + *r->in.resume_handle;
1575 r->out.domains->count = r->out.domains->count;
1577 if (r->out.domains->count < count - *r->in.resume_handle) {
1578 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1579 return STATUS_MORE_ENTRIES;
1582 return NT_STATUS_OK;
1586 comparison function for sorting lsa_DomainInformation array
1588 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1590 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1594 lsa_EnumTrustedDomainsEx
1596 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1597 struct lsa_EnumTrustedDomainsEx *r)
1599 struct dcesrv_handle *policy_handle;
1600 struct lsa_TrustDomainInfoInfoEx *entries;
1601 struct lsa_policy_state *policy_state;
1602 struct ldb_message **domains;
1603 const char *attrs[] = {
1606 "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_DomainInformation format */
1634 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1636 return NT_STATUS_NO_MEMORY;
1638 for (i=0;i<count;i++) {
1639 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1640 if (!NT_STATUS_IS_OK(nt_status)) {
1645 /* sort the results by name */
1646 qsort(entries, count, sizeof(*entries),
1647 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1649 if (*r->in.resume_handle >= count) {
1650 *r->out.resume_handle = -1;
1652 return NT_STATUS_NO_MORE_ENTRIES;
1655 /* return the rest, limit by max_size. Note that we
1656 use the w2k3 element size value of 60 */
1657 r->out.domains->count = count - *r->in.resume_handle;
1658 r->out.domains->count = MIN(r->out.domains->count,
1659 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1661 r->out.domains->domains = entries + *r->in.resume_handle;
1662 r->out.domains->count = r->out.domains->count;
1664 if (r->out.domains->count < count - *r->in.resume_handle) {
1665 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1666 return STATUS_MORE_ENTRIES;
1669 return NT_STATUS_OK;
1676 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1677 struct lsa_OpenAccount *r)
1679 struct dcesrv_handle *h, *ah;
1680 struct lsa_policy_state *state;
1681 struct lsa_account_state *astate;
1683 ZERO_STRUCTP(r->out.acct_handle);
1685 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1689 astate = talloc(dce_call->conn, struct lsa_account_state);
1690 if (astate == NULL) {
1691 return NT_STATUS_NO_MEMORY;
1694 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1695 if (astate->account_sid == NULL) {
1696 talloc_free(astate);
1697 return NT_STATUS_NO_MEMORY;
1700 astate->policy = talloc_reference(astate, state);
1701 astate->access_mask = r->in.access_mask;
1703 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1705 talloc_free(astate);
1706 return NT_STATUS_NO_MEMORY;
1709 ah->data = talloc_steal(ah, astate);
1711 *r->out.acct_handle = ah->wire_handle;
1713 return NT_STATUS_OK;
1718 lsa_EnumPrivsAccount
1720 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1721 TALLOC_CTX *mem_ctx,
1722 struct lsa_EnumPrivsAccount *r)
1724 struct dcesrv_handle *h;
1725 struct lsa_account_state *astate;
1727 struct ldb_message **res;
1728 const char * const attrs[] = { "privilege", NULL};
1729 struct ldb_message_element *el;
1731 struct lsa_PrivilegeSet *privs;
1733 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1737 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1738 if (privs == NULL) {
1739 return NT_STATUS_NO_MEMORY;
1745 *r->out.privs = privs;
1747 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1748 if (sidstr == NULL) {
1749 return NT_STATUS_NO_MEMORY;
1752 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1753 "objectSid=%s", sidstr);
1755 return NT_STATUS_OK;
1758 el = ldb_msg_find_element(res[0], "privilege");
1759 if (el == NULL || el->num_values == 0) {
1760 return NT_STATUS_OK;
1763 privs->set = talloc_array(privs,
1764 struct lsa_LUIDAttribute, el->num_values);
1765 if (privs->set == NULL) {
1766 return NT_STATUS_NO_MEMORY;
1769 for (i=0;i<el->num_values;i++) {
1770 int id = sec_privilege_id((const char *)el->values[i].data);
1772 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1774 privs->set[i].attribute = 0;
1775 privs->set[i].luid.low = id;
1776 privs->set[i].luid.high = 0;
1779 privs->count = el->num_values;
1781 return NT_STATUS_OK;
1785 lsa_EnumAccountRights
1787 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1788 TALLOC_CTX *mem_ctx,
1789 struct lsa_EnumAccountRights *r)
1791 struct dcesrv_handle *h;
1792 struct lsa_policy_state *state;
1794 struct ldb_message **res;
1795 const char * const attrs[] = { "privilege", NULL};
1797 struct ldb_message_element *el;
1799 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1803 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1804 if (sidstr == NULL) {
1805 return NT_STATUS_NO_MEMORY;
1808 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1809 "(&(objectSid=%s)(privilege=*))", sidstr);
1811 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1814 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1817 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1818 dom_sid_string(mem_ctx, r->in.sid),
1819 ldb_errstring(state->sam_ldb)));
1820 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1823 el = ldb_msg_find_element(res[0], "privilege");
1824 if (el == NULL || el->num_values == 0) {
1825 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1828 r->out.rights->count = el->num_values;
1829 r->out.rights->names = talloc_array(r->out.rights,
1830 struct lsa_StringLarge, r->out.rights->count);
1831 if (r->out.rights->names == NULL) {
1832 return NT_STATUS_NO_MEMORY;
1835 for (i=0;i<el->num_values;i++) {
1836 r->out.rights->names[i].string = (const char *)el->values[i].data;
1839 return NT_STATUS_OK;
1845 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1847 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1848 TALLOC_CTX *mem_ctx,
1849 struct lsa_policy_state *state,
1851 struct dom_sid *sid,
1852 const struct lsa_RightSet *rights)
1855 struct ldb_message *msg;
1856 struct ldb_message_element *el;
1858 struct lsa_EnumAccountRights r2;
1860 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1861 if (sidstr == NULL) {
1862 return NT_STATUS_NO_MEMORY;
1865 msg = ldb_msg_new(mem_ctx);
1867 return NT_STATUS_NO_MEMORY;
1870 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1871 NULL, "objectSid=%s", sidstr);
1872 if (msg->dn == NULL) {
1874 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1875 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1877 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1879 if (!NT_STATUS_IS_OK(status)) {
1882 return NT_STATUS_NO_SUCH_USER;
1885 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1886 return NT_STATUS_NO_MEMORY;
1889 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1892 r2.in.handle = &state->handle->wire_handle;
1894 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1896 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1897 if (!NT_STATUS_IS_OK(status)) {
1898 ZERO_STRUCTP(r2.out.rights);
1902 for (i=0;i<rights->count;i++) {
1903 if (sec_privilege_id(rights->names[i].string) == -1) {
1904 return NT_STATUS_NO_SUCH_PRIVILEGE;
1907 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1909 for (j=0;j<r2.out.rights->count;j++) {
1910 if (strcasecmp_m(r2.out.rights->names[j].string,
1911 rights->names[i].string) == 0) {
1915 if (j != r2.out.rights->count) continue;
1918 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1919 if (ret != LDB_SUCCESS) {
1920 return NT_STATUS_NO_MEMORY;
1924 el = ldb_msg_find_element(msg, "privilege");
1926 return NT_STATUS_OK;
1929 ret = ldb_modify(state->sam_ldb, msg);
1931 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1932 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1934 DEBUG(3, ("Could not %s attributes from %s: %s",
1935 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1936 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1937 return NT_STATUS_UNEXPECTED_IO_ERROR;
1940 return NT_STATUS_OK;
1944 lsa_AddPrivilegesToAccount
1946 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1947 struct lsa_AddPrivilegesToAccount *r)
1949 struct lsa_RightSet rights;
1950 struct dcesrv_handle *h;
1951 struct lsa_account_state *astate;
1954 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1958 rights.count = r->in.privs->count;
1959 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1960 if (rights.names == NULL) {
1961 return NT_STATUS_NO_MEMORY;
1963 for (i=0;i<rights.count;i++) {
1964 int id = r->in.privs->set[i].luid.low;
1965 if (r->in.privs->set[i].luid.high) {
1966 return NT_STATUS_NO_SUCH_PRIVILEGE;
1968 rights.names[i].string = sec_privilege_name(id);
1969 if (rights.names[i].string == NULL) {
1970 return NT_STATUS_NO_SUCH_PRIVILEGE;
1974 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1975 LDB_FLAG_MOD_ADD, astate->account_sid,
1981 lsa_RemovePrivilegesFromAccount
1983 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1984 struct lsa_RemovePrivilegesFromAccount *r)
1986 struct lsa_RightSet *rights;
1987 struct dcesrv_handle *h;
1988 struct lsa_account_state *astate;
1991 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1995 rights = talloc(mem_ctx, struct lsa_RightSet);
1997 if (r->in.remove_all == 1 &&
1998 r->in.privs == NULL) {
1999 struct lsa_EnumAccountRights r2;
2002 r2.in.handle = &astate->policy->handle->wire_handle;
2003 r2.in.sid = astate->account_sid;
2004 r2.out.rights = rights;
2006 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2007 if (!NT_STATUS_IS_OK(status)) {
2011 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2012 LDB_FLAG_MOD_DELETE, astate->account_sid,
2016 if (r->in.remove_all != 0) {
2017 return NT_STATUS_INVALID_PARAMETER;
2020 rights->count = r->in.privs->count;
2021 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2022 if (rights->names == NULL) {
2023 return NT_STATUS_NO_MEMORY;
2025 for (i=0;i<rights->count;i++) {
2026 int id = r->in.privs->set[i].luid.low;
2027 if (r->in.privs->set[i].luid.high) {
2028 return NT_STATUS_NO_SUCH_PRIVILEGE;
2030 rights->names[i].string = sec_privilege_name(id);
2031 if (rights->names[i].string == NULL) {
2032 return NT_STATUS_NO_SUCH_PRIVILEGE;
2036 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2037 LDB_FLAG_MOD_DELETE, astate->account_sid,
2043 lsa_GetQuotasForAccount
2045 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2046 struct lsa_GetQuotasForAccount *r)
2048 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2053 lsa_SetQuotasForAccount
2055 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2056 struct lsa_SetQuotasForAccount *r)
2058 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2063 lsa_GetSystemAccessAccount
2065 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2066 struct lsa_GetSystemAccessAccount *r)
2070 struct lsa_EnumPrivsAccount enumPrivs;
2071 struct lsa_PrivilegeSet *privs;
2073 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2075 return NT_STATUS_NO_MEMORY;
2081 enumPrivs.in.handle = r->in.handle;
2082 enumPrivs.out.privs = &privs;
2084 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2085 if (!NT_STATUS_IS_OK(status)) {
2089 *(r->out.access_mask) = 0x00000000;
2091 for (i = 0; i < privs->count; i++) {
2092 int priv = privs->set[i].luid.low;
2095 case SEC_PRIV_INTERACTIVE_LOGON:
2096 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2098 case SEC_PRIV_NETWORK_LOGON:
2099 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2101 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2102 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2107 return NT_STATUS_OK;
2112 lsa_SetSystemAccessAccount
2114 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2115 struct lsa_SetSystemAccessAccount *r)
2117 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2124 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2125 struct lsa_CreateSecret *r)
2127 struct dcesrv_handle *policy_handle;
2128 struct lsa_policy_state *policy_state;
2129 struct lsa_secret_state *secret_state;
2130 struct dcesrv_handle *handle;
2131 struct ldb_message **msgs, *msg;
2133 const char *attrs[] = {
2141 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2142 ZERO_STRUCTP(r->out.sec_handle);
2144 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2146 case SECURITY_SYSTEM:
2147 case SECURITY_ADMINISTRATOR:
2150 /* Users and annonymous are not allowed create secrets */
2151 return NT_STATUS_ACCESS_DENIED;
2154 policy_state = policy_handle->data;
2156 if (!r->in.name.string) {
2157 return NT_STATUS_INVALID_PARAMETER;
2160 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2161 if (!secret_state) {
2162 return NT_STATUS_NO_MEMORY;
2164 secret_state->policy = policy_state;
2166 msg = ldb_msg_new(mem_ctx);
2168 return NT_STATUS_NO_MEMORY;
2171 if (strncmp("G$", r->in.name.string, 2) == 0) {
2173 name = &r->in.name.string[2];
2174 /* 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) */
2175 secret_state->sam_ldb = talloc_reference(secret_state,
2176 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(secret_state, dce_call->conn->dce_ctx->lp_ctx)));
2177 secret_state->global = true;
2179 if (strlen(name) < 1) {
2180 return NT_STATUS_INVALID_PARAMETER;
2183 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2184 /* search for the secret record */
2185 ret = gendb_search(secret_state->sam_ldb,
2186 mem_ctx, policy_state->system_dn, &msgs, attrs,
2187 "(&(cn=%s)(objectclass=secret))",
2190 return NT_STATUS_OBJECT_NAME_COLLISION;
2194 DEBUG(0,("Failure searching for CN=%s: %s\n",
2195 name2, ldb_errstring(secret_state->sam_ldb)));
2196 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2199 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2200 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2201 return NT_STATUS_NO_MEMORY;
2204 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2207 secret_state->global = false;
2209 name = r->in.name.string;
2210 if (strlen(name) < 1) {
2211 return NT_STATUS_INVALID_PARAMETER;
2214 secret_state->sam_ldb = talloc_reference(secret_state,
2215 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2216 /* search for the secret record */
2217 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2218 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2220 "(&(cn=%s)(objectclass=secret))",
2221 ldb_binary_encode_string(mem_ctx, name));
2223 return NT_STATUS_OBJECT_NAME_COLLISION;
2227 DEBUG(0,("Failure searching for CN=%s: %s\n",
2228 name, ldb_errstring(secret_state->sam_ldb)));
2229 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2232 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2233 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2236 /* pull in all the template attributes. Note this is always from the global samdb */
2237 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
2240 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2242 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2245 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2247 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2249 /* create the secret */
2250 ret = ldb_add(secret_state->sam_ldb, msg);
2252 DEBUG(0,("Failed to create secret record %s: %s\n",
2253 ldb_dn_get_linearized(msg->dn),
2254 ldb_errstring(secret_state->sam_ldb)));
2255 return NT_STATUS_ACCESS_DENIED;
2258 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2260 return NT_STATUS_NO_MEMORY;
2263 handle->data = talloc_steal(handle, secret_state);
2265 secret_state->access_mask = r->in.access_mask;
2266 secret_state->policy = talloc_reference(secret_state, policy_state);
2268 *r->out.sec_handle = handle->wire_handle;
2270 return NT_STATUS_OK;
2277 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2278 struct lsa_OpenSecret *r)
2280 struct dcesrv_handle *policy_handle;
2282 struct lsa_policy_state *policy_state;
2283 struct lsa_secret_state *secret_state;
2284 struct dcesrv_handle *handle;
2285 struct ldb_message **msgs;
2286 const char *attrs[] = {
2294 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2295 ZERO_STRUCTP(r->out.sec_handle);
2296 policy_state = policy_handle->data;
2298 if (!r->in.name.string) {
2299 return NT_STATUS_INVALID_PARAMETER;
2302 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2304 case SECURITY_SYSTEM:
2305 case SECURITY_ADMINISTRATOR:
2308 /* Users and annonymous are not allowed to access secrets */
2309 return NT_STATUS_ACCESS_DENIED;
2312 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2313 if (!secret_state) {
2314 return NT_STATUS_NO_MEMORY;
2316 secret_state->policy = policy_state;
2318 if (strncmp("G$", r->in.name.string, 2) == 0) {
2319 name = &r->in.name.string[2];
2320 /* 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) */
2321 secret_state->sam_ldb = talloc_reference(secret_state,
2322 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(secret_state, dce_call->conn->dce_ctx->lp_ctx)));
2323 secret_state->global = true;
2325 if (strlen(name) < 1) {
2326 return NT_STATUS_INVALID_PARAMETER;
2329 /* search for the secret record */
2330 ret = gendb_search(secret_state->sam_ldb,
2331 mem_ctx, policy_state->system_dn, &msgs, attrs,
2332 "(&(cn=%s Secret)(objectclass=secret))",
2333 ldb_binary_encode_string(mem_ctx, name));
2335 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2339 DEBUG(0,("Found %d records matching DN %s\n", ret,
2340 ldb_dn_get_linearized(policy_state->system_dn)));
2341 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2345 secret_state->global = false;
2346 secret_state->sam_ldb = talloc_reference(secret_state,
2347 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2349 name = r->in.name.string;
2350 if (strlen(name) < 1) {
2351 return NT_STATUS_INVALID_PARAMETER;
2354 /* search for the secret record */
2355 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2356 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2358 "(&(cn=%s)(objectclass=secret))",
2359 ldb_binary_encode_string(mem_ctx, name));
2361 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2365 DEBUG(0,("Found %d records matching CN=%s\n",
2366 ret, ldb_binary_encode_string(mem_ctx, name)));
2367 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2371 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2373 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2375 return NT_STATUS_NO_MEMORY;
2378 handle->data = talloc_steal(handle, secret_state);
2380 secret_state->access_mask = r->in.access_mask;
2381 secret_state->policy = talloc_reference(secret_state, policy_state);
2383 *r->out.sec_handle = handle->wire_handle;
2385 return NT_STATUS_OK;
2392 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2393 struct lsa_SetSecret *r)
2396 struct dcesrv_handle *h;
2397 struct lsa_secret_state *secret_state;
2398 struct ldb_message *msg;
2399 DATA_BLOB session_key;
2400 DATA_BLOB crypt_secret, secret;
2403 NTSTATUS status = NT_STATUS_OK;
2405 struct timeval now = timeval_current();
2406 NTTIME nt_now = timeval_to_nttime(&now);
2408 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2410 secret_state = h->data;
2412 msg = ldb_msg_new(mem_ctx);
2414 return NT_STATUS_NO_MEMORY;
2417 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2419 return NT_STATUS_NO_MEMORY;
2421 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2422 if (!NT_STATUS_IS_OK(status)) {
2426 if (r->in.old_val) {
2428 crypt_secret.data = r->in.old_val->data;
2429 crypt_secret.length = r->in.old_val->size;
2431 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2432 if (!NT_STATUS_IS_OK(status)) {
2436 val.data = secret.data;
2437 val.length = secret.length;
2440 if (samdb_msg_add_value(secret_state->sam_ldb,
2441 mem_ctx, msg, "priorValue", &val) != 0) {
2442 return NT_STATUS_NO_MEMORY;
2445 /* set old value mtime */
2446 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2447 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2448 return NT_STATUS_NO_MEMORY;
2452 /* If the old value is not set, then migrate the
2453 * current value to the old value */
2454 const struct ldb_val *old_val;
2455 NTTIME last_set_time;
2456 struct ldb_message **res;
2457 const char *attrs[] = {
2463 /* search for the secret record */
2464 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2465 secret_state->secret_dn, &res, attrs);
2467 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2471 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2472 ldb_dn_get_linearized(secret_state->secret_dn)));
2473 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2476 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2477 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2481 if (samdb_msg_add_value(secret_state->sam_ldb,
2482 mem_ctx, msg, "priorValue",
2484 return NT_STATUS_NO_MEMORY;
2487 if (samdb_msg_add_delete(secret_state->sam_ldb,
2488 mem_ctx, msg, "priorValue")) {
2489 return NT_STATUS_NO_MEMORY;
2494 /* set old value mtime */
2495 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2496 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2497 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2498 return NT_STATUS_NO_MEMORY;
2501 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2502 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2503 return NT_STATUS_NO_MEMORY;
2508 if (r->in.new_val) {
2510 crypt_secret.data = r->in.new_val->data;
2511 crypt_secret.length = r->in.new_val->size;
2513 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2514 if (!NT_STATUS_IS_OK(status)) {
2518 val.data = secret.data;
2519 val.length = secret.length;
2522 if (samdb_msg_add_value(secret_state->sam_ldb,
2523 mem_ctx, msg, "currentValue", &val) != 0) {
2524 return NT_STATUS_NO_MEMORY;
2527 /* set new value mtime */
2528 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2529 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2530 return NT_STATUS_NO_MEMORY;
2534 /* NULL out the NEW value */
2535 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2536 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2537 return NT_STATUS_NO_MEMORY;
2539 if (samdb_msg_add_delete(secret_state->sam_ldb,
2540 mem_ctx, msg, "currentValue")) {
2541 return NT_STATUS_NO_MEMORY;
2545 /* modify the samdb record */
2546 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2548 /* we really need samdb.c to return NTSTATUS */
2549 return NT_STATUS_UNSUCCESSFUL;
2552 return NT_STATUS_OK;
2559 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2560 struct lsa_QuerySecret *r)
2562 struct dcesrv_handle *h;
2563 struct lsa_secret_state *secret_state;
2564 struct ldb_message *msg;
2565 DATA_BLOB session_key;
2566 DATA_BLOB crypt_secret, secret;
2568 struct ldb_message **res;
2569 const char *attrs[] = {
2579 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2581 /* Ensure user is permitted to read this... */
2582 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2584 case SECURITY_SYSTEM:
2585 case SECURITY_ADMINISTRATOR:
2588 /* Users and annonymous are not allowed to read secrets */
2589 return NT_STATUS_ACCESS_DENIED;
2592 secret_state = h->data;
2594 /* pull all the user attributes */
2595 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2596 secret_state->secret_dn, &res, attrs);
2598 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2602 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2603 if (!NT_STATUS_IS_OK(nt_status)) {
2607 if (r->in.old_val) {
2608 const struct ldb_val *prior_val;
2609 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2610 if (!r->out.old_val) {
2611 return NT_STATUS_NO_MEMORY;
2613 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2615 if (prior_val && prior_val->length) {
2616 secret.data = prior_val->data;
2617 secret.length = prior_val->length;
2620 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2621 if (!crypt_secret.length) {
2622 return NT_STATUS_NO_MEMORY;
2624 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2625 if (!r->out.old_val->buf) {
2626 return NT_STATUS_NO_MEMORY;
2628 r->out.old_val->buf->size = crypt_secret.length;
2629 r->out.old_val->buf->length = crypt_secret.length;
2630 r->out.old_val->buf->data = crypt_secret.data;
2634 if (r->in.old_mtime) {
2635 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2636 if (!r->out.old_mtime) {
2637 return NT_STATUS_NO_MEMORY;
2639 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2642 if (r->in.new_val) {
2643 const struct ldb_val *new_val;
2644 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2645 if (!r->out.new_val) {
2646 return NT_STATUS_NO_MEMORY;
2649 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2651 if (new_val && new_val->length) {
2652 secret.data = new_val->data;
2653 secret.length = new_val->length;
2656 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2657 if (!crypt_secret.length) {
2658 return NT_STATUS_NO_MEMORY;
2660 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2661 if (!r->out.new_val->buf) {
2662 return NT_STATUS_NO_MEMORY;
2664 r->out.new_val->buf->length = crypt_secret.length;
2665 r->out.new_val->buf->size = crypt_secret.length;
2666 r->out.new_val->buf->data = crypt_secret.data;
2670 if (r->in.new_mtime) {
2671 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2672 if (!r->out.new_mtime) {
2673 return NT_STATUS_NO_MEMORY;
2675 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2678 return NT_STATUS_OK;
2685 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2686 TALLOC_CTX *mem_ctx,
2687 struct lsa_LookupPrivValue *r)
2689 struct dcesrv_handle *h;
2690 struct lsa_policy_state *state;
2693 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2697 id = sec_privilege_id(r->in.name->string);
2699 return NT_STATUS_NO_SUCH_PRIVILEGE;
2702 r->out.luid->low = id;
2703 r->out.luid->high = 0;
2705 return NT_STATUS_OK;
2712 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2713 TALLOC_CTX *mem_ctx,
2714 struct lsa_LookupPrivName *r)
2716 struct dcesrv_handle *h;
2717 struct lsa_policy_state *state;
2718 struct lsa_StringLarge *name;
2719 const char *privname;
2721 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2725 if (r->in.luid->high != 0) {
2726 return NT_STATUS_NO_SUCH_PRIVILEGE;
2729 privname = sec_privilege_name(r->in.luid->low);
2730 if (privname == NULL) {
2731 return NT_STATUS_NO_SUCH_PRIVILEGE;
2734 name = talloc(mem_ctx, struct lsa_StringLarge);
2736 return NT_STATUS_NO_MEMORY;
2739 name->string = privname;
2741 *r->out.name = name;
2743 return NT_STATUS_OK;
2748 lsa_LookupPrivDisplayName
2750 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2751 TALLOC_CTX *mem_ctx,
2752 struct lsa_LookupPrivDisplayName *r)
2754 struct dcesrv_handle *h;
2755 struct lsa_policy_state *state;
2756 struct lsa_StringLarge *disp_name = NULL;
2759 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2763 id = sec_privilege_id(r->in.name->string);
2765 return NT_STATUS_NO_SUCH_PRIVILEGE;
2768 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2769 if (disp_name == NULL) {
2770 return NT_STATUS_NO_MEMORY;
2773 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
2774 if (disp_name->string == NULL) {
2775 return NT_STATUS_INTERNAL_ERROR;
2778 *r->out.disp_name = disp_name;
2779 *r->out.returned_language_id = 0;
2781 return NT_STATUS_OK;
2786 lsa_EnumAccountsWithUserRight
2788 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2789 TALLOC_CTX *mem_ctx,
2790 struct lsa_EnumAccountsWithUserRight *r)
2792 struct dcesrv_handle *h;
2793 struct lsa_policy_state *state;
2795 struct ldb_message **res;
2796 const char * const attrs[] = { "objectSid", NULL};
2797 const char *privname;
2799 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2803 if (r->in.name == NULL) {
2804 return NT_STATUS_NO_SUCH_PRIVILEGE;
2807 privname = r->in.name->string;
2808 if (sec_privilege_id(privname) == -1) {
2809 return NT_STATUS_NO_SUCH_PRIVILEGE;
2812 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2813 "privilege=%s", privname);
2815 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2818 return NT_STATUS_NO_MORE_ENTRIES;
2821 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2822 if (r->out.sids->sids == NULL) {
2823 return NT_STATUS_NO_MEMORY;
2825 for (i=0;i<ret;i++) {
2826 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2827 res[i], "objectSid");
2828 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2830 r->out.sids->num_sids = ret;
2832 return NT_STATUS_OK;
2837 lsa_AddAccountRights
2839 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2840 TALLOC_CTX *mem_ctx,
2841 struct lsa_AddAccountRights *r)
2843 struct dcesrv_handle *h;
2844 struct lsa_policy_state *state;
2846 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2850 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2852 r->in.sid, r->in.rights);
2857 lsa_RemoveAccountRights
2859 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2860 TALLOC_CTX *mem_ctx,
2861 struct lsa_RemoveAccountRights *r)
2863 struct dcesrv_handle *h;
2864 struct lsa_policy_state *state;
2866 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2870 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2871 LDB_FLAG_MOD_DELETE,
2872 r->in.sid, r->in.rights);
2877 lsa_StorePrivateData
2879 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2880 struct lsa_StorePrivateData *r)
2882 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2887 lsa_RetrievePrivateData
2889 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2890 struct lsa_RetrievePrivateData *r)
2892 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2899 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2900 struct lsa_GetUserName *r)
2902 NTSTATUS status = NT_STATUS_OK;
2903 const char *account_name;
2904 const char *authority_name;
2905 struct lsa_String *_account_name;
2906 struct lsa_String *_authority_name = NULL;
2908 /* this is what w2k3 does */
2909 r->out.account_name = r->in.account_name;
2910 r->out.authority_name = r->in.authority_name;
2912 if (r->in.account_name
2913 && *r->in.account_name
2914 /* && *(*r->in.account_name)->string */
2916 return NT_STATUS_INVALID_PARAMETER;
2919 if (r->in.authority_name
2920 && *r->in.authority_name
2921 /* && *(*r->in.authority_name)->string */
2923 return NT_STATUS_INVALID_PARAMETER;
2926 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2927 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2929 _account_name = talloc(mem_ctx, struct lsa_String);
2930 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2931 _account_name->string = account_name;
2933 if (r->in.authority_name) {
2934 _authority_name = talloc(mem_ctx, struct lsa_String);
2935 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2936 _authority_name->string = authority_name;
2939 *r->out.account_name = _account_name;
2940 if (r->out.authority_name) {
2941 *r->out.authority_name = _authority_name;
2950 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2951 TALLOC_CTX *mem_ctx,
2952 struct lsa_SetInfoPolicy2 *r)
2954 /* need to support these */
2955 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2959 lsa_QueryDomainInformationPolicy
2961 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2962 TALLOC_CTX *mem_ctx,
2963 struct lsa_QueryDomainInformationPolicy *r)
2965 union lsa_DomainInformationPolicy *info;
2967 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
2969 return NT_STATUS_NO_MEMORY;
2972 switch (r->in.level) {
2973 case LSA_DOMAIN_INFO_POLICY_EFS:
2975 *r->out.info = NULL;
2976 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2977 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
2979 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
2980 struct smb_krb5_context *smb_krb5_context;
2981 int ret = smb_krb5_init_context(mem_ctx,
2982 dce_call->event_ctx,
2983 dce_call->conn->dce_ctx->lp_ctx,
2986 talloc_free(r->out.info);
2988 return NT_STATUS_INTERNAL_ERROR;
2990 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
2991 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2992 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2993 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
2994 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
2995 talloc_free(smb_krb5_context);
2996 *r->out.info = info;
2997 return NT_STATUS_OK;
3001 *r->out.info = NULL;
3002 return NT_STATUS_INVALID_INFO_CLASS;
3007 lsa_SetDomInfoPolicy
3009 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3010 TALLOC_CTX *mem_ctx,
3011 struct lsa_SetDomainInformationPolicy *r)
3013 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3019 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3020 TALLOC_CTX *mem_ctx,
3021 struct lsa_TestCall *r)
3023 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3029 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3030 struct lsa_CREDRWRITE *r)
3032 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3039 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3040 struct lsa_CREDRREAD *r)
3042 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3049 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3050 struct lsa_CREDRENUMERATE *r)
3052 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3057 lsa_CREDRWRITEDOMAINCREDENTIALS
3059 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3060 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3062 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3067 lsa_CREDRREADDOMAINCREDENTIALS
3069 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3070 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3072 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3079 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3080 struct lsa_CREDRDELETE *r)
3082 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3087 lsa_CREDRGETTARGETINFO
3089 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3090 struct lsa_CREDRGETTARGETINFO *r)
3092 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3097 lsa_CREDRPROFILELOADED
3099 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3100 struct lsa_CREDRPROFILELOADED *r)
3102 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3107 lsa_CREDRGETSESSIONTYPES
3109 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3110 struct lsa_CREDRGETSESSIONTYPES *r)
3112 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3117 lsa_LSARREGISTERAUDITEVENT
3119 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3120 struct lsa_LSARREGISTERAUDITEVENT *r)
3122 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3127 lsa_LSARGENAUDITEVENT
3129 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3130 struct lsa_LSARGENAUDITEVENT *r)
3132 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3137 lsa_LSARUNREGISTERAUDITEVENT
3139 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3140 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3142 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3147 lsa_lsaRQueryForestTrustInformation
3149 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3150 struct lsa_lsaRQueryForestTrustInformation *r)
3152 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3157 lsa_LSARSETFORESTTRUSTINFORMATION
3159 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3160 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3162 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3169 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3170 struct lsa_CREDRRENAME *r)
3172 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3178 lsa_LSAROPENPOLICYSCE
3180 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3181 struct lsa_LSAROPENPOLICYSCE *r)
3183 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3188 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3190 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3191 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3193 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3198 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3200 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3201 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3203 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3208 lsa_LSARADTREPORTSECURITYEVENT
3210 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3211 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3213 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3217 /* include the generated boilerplate */
3218 #include "librpc/gen_ndr/ndr_lsa_s.c"
3222 /*****************************************
3223 NOTE! The remaining calls below were
3224 removed in w2k3, so the DCESRV_FAULT()
3225 replies are the correct implementation. Do
3226 not try and fill these in with anything else
3227 ******************************************/
3230 dssetup_DsRoleDnsNameToFlatName
3232 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3233 struct dssetup_DsRoleDnsNameToFlatName *r)
3235 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3240 dssetup_DsRoleDcAsDc
3242 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3243 struct dssetup_DsRoleDcAsDc *r)
3245 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3250 dssetup_DsRoleDcAsReplica
3252 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3253 struct dssetup_DsRoleDcAsReplica *r)
3255 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3260 dssetup_DsRoleDemoteDc
3262 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3263 struct dssetup_DsRoleDemoteDc *r)
3265 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3270 dssetup_DsRoleGetDcOperationProgress
3272 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3273 struct dssetup_DsRoleGetDcOperationProgress *r)
3275 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3280 dssetup_DsRoleGetDcOperationResults
3282 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3283 struct dssetup_DsRoleGetDcOperationResults *r)
3285 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3290 dssetup_DsRoleCancel
3292 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3293 struct dssetup_DsRoleCancel *r)
3295 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3300 dssetup_DsRoleServerSaveStateForUpgrade
3302 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3303 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3305 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3310 dssetup_DsRoleUpgradeDownlevelServer
3312 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3313 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3315 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3320 dssetup_DsRoleAbortDownlevelServerUpgrade
3322 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3323 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3325 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3329 /* include the generated boilerplate */
3330 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3332 NTSTATUS dcerpc_server_lsa_init(void)
3336 ret = dcerpc_server_dssetup_init();
3337 if (!NT_STATUS_IS_OK(ret)) {
3340 ret = dcerpc_server_lsarpc_init();
3341 if (!NT_STATUS_IS_OK(ret)) {