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;
437 union lsa_PolicyInformation *info;
441 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
445 info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
447 return NT_STATUS_NO_MEMORY;
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(info->audit_log);
456 case LSA_POLICY_INFO_AUDIT_EVENTS:
457 /* we don't need to fill in any of this */
458 ZERO_STRUCT(info->audit_events);
460 case LSA_POLICY_INFO_PD:
461 /* we don't need to fill in any of this */
462 ZERO_STRUCT(info->pd);
465 case LSA_POLICY_INFO_DOMAIN:
466 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
467 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
468 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
469 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
470 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
473 case LSA_POLICY_INFO_ROLE:
474 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, &info->dns);
481 case LSA_POLICY_INFO_REPLICA:
482 ZERO_STRUCT(info->replica);
485 case LSA_POLICY_INFO_QUOTA:
486 ZERO_STRUCT(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;
514 r2.out.info = r->out.info;
516 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
524 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
525 struct lsa_SetInfoPolicy *r)
527 /* need to support this */
528 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
535 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
536 struct lsa_ClearAuditLog *r)
538 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
545 This call does not seem to have any long-term effects, hence no database operations
547 we need to talk to the MS product group to find out what this account database means!
549 answer is that the lsa database is totally separate from the SAM and
550 ldap databases. We are going to need a separate ldb to store these
551 accounts. The SIDs on this account bear no relation to the SIDs in
554 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
555 struct lsa_CreateAccount *r)
557 struct lsa_account_state *astate;
559 struct lsa_policy_state *state;
560 struct dcesrv_handle *h, *ah;
562 ZERO_STRUCTP(r->out.acct_handle);
564 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
568 astate = talloc(dce_call->conn, struct lsa_account_state);
569 if (astate == NULL) {
570 return NT_STATUS_NO_MEMORY;
573 astate->account_sid = dom_sid_dup(astate, r->in.sid);
574 if (astate->account_sid == NULL) {
576 return NT_STATUS_NO_MEMORY;
579 astate->policy = talloc_reference(astate, state);
580 astate->access_mask = r->in.access_mask;
582 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
585 return NT_STATUS_NO_MEMORY;
588 ah->data = talloc_steal(ah, astate);
590 *r->out.acct_handle = ah->wire_handle;
599 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
600 struct lsa_EnumAccounts *r)
602 struct dcesrv_handle *h;
603 struct lsa_policy_state *state;
605 struct ldb_message **res;
606 const char * const attrs[] = { "objectSid", NULL};
609 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
613 /* NOTE: This call must only return accounts that have at least
616 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
617 "(&(objectSid=*)(privilege=*))");
619 return NT_STATUS_NO_SUCH_USER;
622 if (*r->in.resume_handle >= ret) {
623 return NT_STATUS_NO_MORE_ENTRIES;
626 count = ret - *r->in.resume_handle;
627 if (count > r->in.num_entries) {
628 count = r->in.num_entries;
632 return NT_STATUS_NO_MORE_ENTRIES;
635 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
636 if (r->out.sids->sids == NULL) {
637 return NT_STATUS_NO_MEMORY;
640 for (i=0;i<count;i++) {
641 r->out.sids->sids[i].sid =
642 samdb_result_dom_sid(r->out.sids->sids,
643 res[i + *r->in.resume_handle],
645 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
648 r->out.sids->num_sids = count;
649 *r->out.resume_handle = count + *r->in.resume_handle;
657 lsa_CreateTrustedDomainEx2
659 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
661 struct lsa_CreateTrustedDomainEx2 *r,
664 struct dcesrv_handle *policy_handle;
665 struct lsa_policy_state *policy_state;
666 struct lsa_trusted_domain_state *trusted_domain_state;
667 struct dcesrv_handle *handle;
668 struct ldb_message **msgs, *msg, *msg_user;
669 const char *attrs[] = {
672 const char *netbios_name;
673 const char *dns_name;
675 DATA_BLOB session_key = data_blob(NULL, 0);
676 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
677 struct trustDomainPasswords auth_struct;
680 enum ndr_err_code ndr_err;
682 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
683 ZERO_STRUCTP(r->out.trustdom_handle);
685 policy_state = policy_handle->data;
687 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
688 if (!NT_STATUS_IS_OK(nt_status)) {
692 netbios_name = r->in.info->netbios_name.string;
694 return NT_STATUS_INVALID_PARAMETER;
697 dns_name = r->in.info->domain_name.string;
699 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
700 if (!trusted_domain_state) {
701 return NT_STATUS_NO_MEMORY;
703 trusted_domain_state->policy = policy_state;
705 if (strcasecmp(netbios_name, "BUILTIN") == 0
706 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
707 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
708 return NT_STATUS_INVALID_PARAMETER;;
711 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
712 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
713 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
714 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
715 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
716 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
719 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
720 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
721 /* No secrets are created at this time, for this function */
722 auth_struct.outgoing.count = 0;
723 auth_struct.incoming.count = 0;
725 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data, r->in.auth_info->auth_blob.size);
726 arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key);
727 ndr_err = ndr_pull_struct_blob(&auth_blob, mem_ctx,
728 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
730 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
731 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
732 return NT_STATUS_INVALID_PARAMETER;
735 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
736 if (auth_struct.incoming.count > 1) {
737 return NT_STATUS_INVALID_PARAMETER;
742 if (auth_struct.incoming.count) {
744 struct trustAuthInOutBlob incoming;
746 incoming.count = auth_struct.incoming.count;
747 incoming.current = talloc(mem_ctx, struct AuthenticationInformationArray);
748 if (!incoming.current) {
749 return NT_STATUS_NO_MEMORY;
752 incoming.current->array = *auth_struct.incoming.current;
753 if (!incoming.current->array) {
754 return NT_STATUS_NO_MEMORY;
757 incoming.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
758 if (!incoming.previous) {
759 return NT_STATUS_NO_MEMORY;
761 incoming.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, incoming.count);
762 if (!incoming.previous->array) {
763 return NT_STATUS_NO_MEMORY;
766 for (i = 0; i < incoming.count; i++) {
767 incoming.previous->array[i].LastUpdateTime = 0;
768 incoming.previous->array[i].AuthType = 0;
770 ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx,
771 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
773 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
774 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
775 return NT_STATUS_INVALID_PARAMETER;
778 trustAuthIncoming = data_blob(NULL, 0);
781 if (auth_struct.outgoing.count) {
783 struct trustAuthInOutBlob outgoing;
785 outgoing.count = auth_struct.outgoing.count;
786 outgoing.current = talloc(mem_ctx, struct AuthenticationInformationArray);
787 if (!outgoing.current) {
788 return NT_STATUS_NO_MEMORY;
791 outgoing.current->array = *auth_struct.outgoing.current;
792 if (!outgoing.current->array) {
793 return NT_STATUS_NO_MEMORY;
796 outgoing.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
797 if (!outgoing.previous) {
798 return NT_STATUS_NO_MEMORY;
800 outgoing.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, outgoing.count);
801 if (!outgoing.previous->array) {
802 return NT_STATUS_NO_MEMORY;
805 for (i = 0; i < outgoing.count; i++) {
806 outgoing.previous->array[i].LastUpdateTime = 0;
807 outgoing.previous->array[i].AuthType = 0;
809 ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx,
810 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
812 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
813 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
814 return NT_STATUS_INVALID_PARAMETER;
817 trustAuthOutgoing = data_blob(NULL, 0);
820 ret = ldb_transaction_start(policy_state->sam_ldb);
821 if (ret != LDB_SUCCESS) {
822 return NT_STATUS_INTERNAL_DB_CORRUPTION;
826 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
827 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
828 /* search for the trusted_domain record */
829 ret = gendb_search(policy_state->sam_ldb,
830 mem_ctx, policy_state->system_dn, &msgs, attrs,
831 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
832 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
834 ldb_transaction_cancel(policy_state->sam_ldb);
835 return NT_STATUS_OBJECT_NAME_COLLISION;
838 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
839 /* search for the trusted_domain record */
840 ret = gendb_search(policy_state->sam_ldb,
841 mem_ctx, policy_state->system_dn, &msgs, attrs,
842 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
843 netbios_encoded, netbios_encoded, netbios_encoded);
845 ldb_transaction_cancel(policy_state->sam_ldb);
846 return NT_STATUS_OBJECT_NAME_COLLISION;
851 ldb_transaction_cancel(policy_state->sam_ldb);
852 return NT_STATUS_INTERNAL_DB_CORRUPTION;
855 name = dns_name ? dns_name : netbios_name;
857 msg = ldb_msg_new(mem_ctx);
859 return NT_STATUS_NO_MEMORY;
862 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
863 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
864 ldb_transaction_cancel(policy_state->sam_ldb);
865 return NT_STATUS_NO_MEMORY;
868 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", netbios_name);
870 if (r->in.info->sid) {
871 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
873 ldb_transaction_cancel(policy_state->sam_ldb);
874 return NT_STATUS_NO_MEMORY;
877 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
880 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
882 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
884 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
886 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
889 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
892 if (trustAuthIncoming.data) {
893 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
894 if (ret != LDB_SUCCESS) {
895 ldb_transaction_cancel(policy_state->sam_ldb);
896 return NT_STATUS_NO_MEMORY;
899 if (trustAuthOutgoing.data) {
900 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
901 if (ret != LDB_SUCCESS) {
902 ldb_transaction_cancel(policy_state->sam_ldb);
903 return NT_STATUS_NO_MEMORY;
907 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
909 /* create the trusted_domain */
910 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
914 case LDB_ERR_ENTRY_ALREADY_EXISTS:
915 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
916 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
917 ldb_dn_get_linearized(msg->dn),
918 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
919 return NT_STATUS_DOMAIN_EXISTS;
920 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
921 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
922 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
923 ldb_dn_get_linearized(msg->dn),
924 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
925 return NT_STATUS_ACCESS_DENIED;
927 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
928 DEBUG(0,("Failed to create user record %s: %s\n",
929 ldb_dn_get_linearized(msg->dn),
930 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
931 return NT_STATUS_INTERNAL_DB_CORRUPTION;
934 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
935 msg_user = ldb_msg_new(mem_ctx);
937 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
938 return NT_STATUS_NO_MEMORY;
941 /* Inbound trusts must also create a cn=users object to match */
943 trusted_domain_state->trusted_domain_user_dn = msg_user->dn
944 = ldb_dn_copy(trusted_domain_state, policy_state->domain_dn);
945 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=users")) {
946 ldb_transaction_cancel(policy_state->sam_ldb);
947 return NT_STATUS_NO_MEMORY;
950 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=%s", netbios_name)) {
951 ldb_transaction_cancel(policy_state->sam_ldb);
952 return NT_STATUS_NO_MEMORY;
955 ldb_msg_add_string(msg_user, "objectClass", "user");
957 ldb_msg_add_steal_string(msg_user, "samAccountName",
958 talloc_asprintf(mem_ctx, "%s$", netbios_name));
960 if (samdb_msg_add_uint(trusted_domain_state->policy->sam_ldb, mem_ctx, msg_user,
961 "userAccountControl",
962 UF_INTERDOMAIN_TRUST_ACCOUNT) != 0) {
963 ldb_transaction_cancel(policy_state->sam_ldb);
964 return NT_STATUS_NO_MEMORY;
967 if (auth_struct.incoming.count) {
969 for (i=0; i < auth_struct.incoming.count; i++ ) {
970 if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_NT4OWF) {
971 samdb_msg_add_hash(trusted_domain_state->policy->sam_ldb,
972 mem_ctx, msg_user, "unicodePwd",
973 &auth_struct.incoming.current[i]->AuthInfo.nt4owf.password);
974 } else if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_CLEAR) {
975 DATA_BLOB new_password = data_blob_const(auth_struct.incoming.current[i]->AuthInfo.clear.password,
976 auth_struct.incoming.current[i]->AuthInfo.clear.size);
977 ret = ldb_msg_add_value(msg_user, "clearTextPassword", &new_password, NULL);
978 if (ret != LDB_SUCCESS) {
979 ldb_transaction_cancel(policy_state->sam_ldb);
980 return NT_STATUS_NO_MEMORY;
986 /* create the cn=users trusted_domain account */
987 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg_user);
991 case LDB_ERR_ENTRY_ALREADY_EXISTS:
992 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
993 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
994 ldb_dn_get_linearized(msg_user->dn),
995 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
996 return NT_STATUS_DOMAIN_EXISTS;
997 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
998 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
999 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1000 ldb_dn_get_linearized(msg_user->dn),
1001 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1002 return NT_STATUS_ACCESS_DENIED;
1004 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1005 DEBUG(0,("Failed to create user record %s: %s\n",
1006 ldb_dn_get_linearized(msg_user->dn),
1007 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1008 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1012 ret = ldb_transaction_commit(policy_state->sam_ldb);
1013 if (ret != LDB_SUCCESS) {
1014 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1017 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1019 return NT_STATUS_NO_MEMORY;
1022 handle->data = talloc_steal(handle, trusted_domain_state);
1024 trusted_domain_state->access_mask = r->in.access_mask;
1025 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1027 *r->out.trustdom_handle = handle->wire_handle;
1029 return NT_STATUS_OK;
1033 lsa_CreateTrustedDomainEx2
1035 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1036 TALLOC_CTX *mem_ctx,
1037 struct lsa_CreateTrustedDomainEx2 *r)
1039 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
1042 lsa_CreateTrustedDomainEx
1044 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1045 TALLOC_CTX *mem_ctx,
1046 struct lsa_CreateTrustedDomainEx *r)
1048 struct lsa_CreateTrustedDomainEx2 r2;
1050 r2.in.policy_handle = r->in.policy_handle;
1051 r2.in.info = r->in.info;
1052 r2.in.auth_info = r->in.auth_info;
1053 r2.out.trustdom_handle = r->out.trustdom_handle;
1054 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
1058 lsa_CreateTrustedDomain
1060 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1061 struct lsa_CreateTrustedDomain *r)
1063 struct lsa_CreateTrustedDomainEx2 r2;
1065 r2.in.policy_handle = r->in.policy_handle;
1066 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1068 return NT_STATUS_NO_MEMORY;
1071 r2.in.info->domain_name.string = NULL;
1072 r2.in.info->netbios_name = r->in.info->name;
1073 r2.in.info->sid = r->in.info->sid;
1074 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1075 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1076 r2.in.info->trust_attributes = 0;
1078 r2.in.access_mask = r->in.access_mask;
1079 r2.out.trustdom_handle = r->out.trustdom_handle;
1081 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1086 lsa_OpenTrustedDomain
1088 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1089 struct lsa_OpenTrustedDomain *r)
1091 struct dcesrv_handle *policy_handle;
1093 struct lsa_policy_state *policy_state;
1094 struct lsa_trusted_domain_state *trusted_domain_state;
1095 struct dcesrv_handle *handle;
1096 struct ldb_message **msgs;
1097 const char *attrs[] = {
1103 const char *sid_string;
1106 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1107 ZERO_STRUCTP(r->out.trustdom_handle);
1108 policy_state = policy_handle->data;
1110 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1111 if (!trusted_domain_state) {
1112 return NT_STATUS_NO_MEMORY;
1114 trusted_domain_state->policy = policy_state;
1116 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1118 return NT_STATUS_NO_MEMORY;
1121 /* search for the trusted_domain record */
1122 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1123 mem_ctx, policy_state->system_dn, &msgs, attrs,
1124 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
1127 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1131 DEBUG(0,("Found %d records matching DN %s\n", ret,
1132 ldb_dn_get_linearized(policy_state->system_dn)));
1133 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1136 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1138 trusted_domain_state->trusted_domain_user_dn = NULL;
1140 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1141 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1142 /* search for the trusted_domain record */
1143 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1144 mem_ctx, policy_state->domain_dn, &msgs, attrs,
1145 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%d))",
1146 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1148 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1151 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1153 return NT_STATUS_NO_MEMORY;
1156 handle->data = talloc_steal(handle, trusted_domain_state);
1158 trusted_domain_state->access_mask = r->in.access_mask;
1159 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1161 *r->out.trustdom_handle = handle->wire_handle;
1163 return NT_STATUS_OK;
1168 lsa_OpenTrustedDomainByName
1170 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1171 TALLOC_CTX *mem_ctx,
1172 struct lsa_OpenTrustedDomainByName *r)
1174 struct dcesrv_handle *policy_handle;
1176 struct lsa_policy_state *policy_state;
1177 struct lsa_trusted_domain_state *trusted_domain_state;
1178 struct dcesrv_handle *handle;
1179 struct ldb_message **msgs;
1180 const char *attrs[] = {
1186 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1187 ZERO_STRUCTP(r->out.trustdom_handle);
1188 policy_state = policy_handle->data;
1190 if (!r->in.name.string) {
1191 return NT_STATUS_INVALID_PARAMETER;
1194 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1195 if (!trusted_domain_state) {
1196 return NT_STATUS_NO_MEMORY;
1198 trusted_domain_state->policy = policy_state;
1200 /* search for the trusted_domain record */
1201 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1202 mem_ctx, policy_state->system_dn, &msgs, attrs,
1203 "(&(flatname=%s)(objectclass=trustedDomain))",
1204 ldb_binary_encode_string(mem_ctx, r->in.name.string));
1206 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1210 DEBUG(0,("Found %d records matching DN %s\n", ret,
1211 ldb_dn_get_linearized(policy_state->system_dn)));
1212 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1215 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1217 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1219 return NT_STATUS_NO_MEMORY;
1222 handle->data = talloc_steal(handle, trusted_domain_state);
1224 trusted_domain_state->access_mask = r->in.access_mask;
1225 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1227 *r->out.trustdom_handle = handle->wire_handle;
1229 return NT_STATUS_OK;
1235 lsa_SetTrustedDomainInfo
1237 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1238 struct lsa_SetTrustedDomainInfo *r)
1240 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1246 lsa_SetInfomrationTrustedDomain
1248 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1249 TALLOC_CTX *mem_ctx,
1250 struct lsa_SetInformationTrustedDomain *r)
1252 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1257 lsa_DeleteTrustedDomain
1259 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1260 struct lsa_DeleteTrustedDomain *r)
1263 struct lsa_OpenTrustedDomain open;
1264 struct lsa_DeleteObject delete;
1265 struct dcesrv_handle *h;
1267 open.in.handle = r->in.handle;
1268 open.in.sid = r->in.dom_sid;
1269 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1270 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1271 if (!open.out.trustdom_handle) {
1272 return NT_STATUS_NO_MEMORY;
1274 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1275 if (!NT_STATUS_IS_OK(status)) {
1279 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1280 talloc_steal(mem_ctx, h);
1282 delete.in.handle = open.out.trustdom_handle;
1283 delete.out.handle = open.out.trustdom_handle;
1284 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &delete);
1285 if (!NT_STATUS_IS_OK(status)) {
1288 return NT_STATUS_OK;
1291 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1292 struct ldb_message *msg,
1293 struct lsa_TrustDomainInfoInfoEx *info_ex)
1295 info_ex->domain_name.string
1296 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1297 info_ex->netbios_name.string
1298 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1300 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1301 info_ex->trust_direction
1302 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1304 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1305 info_ex->trust_attributes
1306 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1307 return NT_STATUS_OK;
1311 lsa_QueryTrustedDomainInfo
1313 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1314 struct lsa_QueryTrustedDomainInfo *r)
1316 union lsa_TrustedDomainInfo *info = NULL;
1317 struct dcesrv_handle *h;
1318 struct lsa_trusted_domain_state *trusted_domain_state;
1319 struct ldb_message *msg;
1321 struct ldb_message **res;
1322 const char *attrs[] = {
1325 "securityIdentifier",
1329 "msDs-supportedEncryptionTypes",
1333 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1335 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1337 /* pull all the user attributes */
1338 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1339 trusted_domain_state->trusted_domain_dn, &res, attrs);
1341 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1345 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
1347 return NT_STATUS_NO_MEMORY;
1349 *r->out.info = info;
1351 switch (r->in.level) {
1352 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1353 info->name.netbios_name.string
1354 = samdb_result_string(msg, "flatname", NULL);
1356 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1357 info->posix_offset.posix_offset
1358 = samdb_result_uint(msg, "posixOffset", 0);
1360 #if 0 /* Win2k3 doesn't implement this */
1361 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1362 r->out.info->info_basic.netbios_name.string
1363 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1364 r->out.info->info_basic.sid
1365 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1368 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1369 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
1371 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1372 ZERO_STRUCT(info->full_info);
1373 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
1375 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1376 ZERO_STRUCT(info->full_info2_internal);
1377 info->full_info2_internal.posix_offset.posix_offset
1378 = samdb_result_uint(msg, "posixOffset", 0);
1379 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
1381 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
1382 info->enc_types.enc_types
1383 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
1386 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1387 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1388 /* oops, we don't want to return the info after all */
1391 return NT_STATUS_INVALID_PARAMETER;
1393 /* oops, we don't want to return the info after all */
1396 return NT_STATUS_INVALID_INFO_CLASS;
1399 return NT_STATUS_OK;
1404 lsa_QueryTrustedDomainInfoBySid
1406 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1407 struct lsa_QueryTrustedDomainInfoBySid *r)
1410 struct lsa_OpenTrustedDomain open;
1411 struct lsa_QueryTrustedDomainInfo query;
1412 union lsa_TrustedDomainInfo *info;
1413 struct dcesrv_handle *h;
1414 open.in.handle = r->in.handle;
1415 open.in.sid = r->in.dom_sid;
1416 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1417 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1418 if (!open.out.trustdom_handle) {
1419 return NT_STATUS_NO_MEMORY;
1421 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1422 if (!NT_STATUS_IS_OK(status)) {
1426 /* Ensure this handle goes away at the end of this call */
1427 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1428 talloc_steal(mem_ctx, h);
1430 query.in.trustdom_handle = open.out.trustdom_handle;
1431 query.in.level = r->in.level;
1432 query.out.info = r->out.info;
1433 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1434 if (!NT_STATUS_IS_OK(status)) {
1438 return NT_STATUS_OK;
1442 lsa_SetTrustedDomainInfoByName
1444 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1445 TALLOC_CTX *mem_ctx,
1446 struct lsa_SetTrustedDomainInfoByName *r)
1448 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1452 lsa_QueryTrustedDomainInfoByName
1454 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1455 TALLOC_CTX *mem_ctx,
1456 struct lsa_QueryTrustedDomainInfoByName *r)
1459 struct lsa_OpenTrustedDomainByName open;
1460 struct lsa_QueryTrustedDomainInfo query;
1461 struct dcesrv_handle *h;
1462 open.in.handle = r->in.handle;
1463 open.in.name = *r->in.trusted_domain;
1464 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1465 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1466 if (!open.out.trustdom_handle) {
1467 return NT_STATUS_NO_MEMORY;
1469 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1470 if (!NT_STATUS_IS_OK(status)) {
1474 /* Ensure this handle goes away at the end of this call */
1475 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1476 talloc_steal(mem_ctx, h);
1478 query.in.trustdom_handle = open.out.trustdom_handle;
1479 query.in.level = r->in.level;
1480 query.out.info = r->out.info;
1481 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1482 if (!NT_STATUS_IS_OK(status)) {
1486 return NT_STATUS_OK;
1490 lsa_CloseTrustedDomainEx
1492 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1493 TALLOC_CTX *mem_ctx,
1494 struct lsa_CloseTrustedDomainEx *r)
1496 /* The result of a bad hair day from an IDL programmer? Not
1497 * implmented in Win2k3. You should always just lsa_Close
1499 return NT_STATUS_NOT_IMPLEMENTED;
1504 comparison function for sorting lsa_DomainInformation array
1506 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1508 return strcasecmp_m(e1->name.string, e2->name.string);
1514 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1515 struct lsa_EnumTrustDom *r)
1517 struct dcesrv_handle *policy_handle;
1518 struct lsa_DomainInfo *entries;
1519 struct lsa_policy_state *policy_state;
1520 struct ldb_message **domains;
1521 const char *attrs[] = {
1523 "securityIdentifier",
1530 *r->out.resume_handle = 0;
1532 r->out.domains->domains = NULL;
1533 r->out.domains->count = 0;
1535 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1537 policy_state = policy_handle->data;
1539 /* search for all users in this domain. This could possibly be cached and
1540 resumed based on resume_key */
1541 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1542 "objectclass=trustedDomain");
1544 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1547 /* convert to lsa_TrustInformation format */
1548 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1550 return NT_STATUS_NO_MEMORY;
1552 for (i=0;i<count;i++) {
1553 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1554 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1557 /* sort the results by name */
1558 qsort(entries, count, sizeof(*entries),
1559 (comparison_fn_t)compare_DomainInfo);
1561 if (*r->in.resume_handle >= count) {
1562 *r->out.resume_handle = -1;
1564 return NT_STATUS_NO_MORE_ENTRIES;
1567 /* return the rest, limit by max_size. Note that we
1568 use the w2k3 element size value of 60 */
1569 r->out.domains->count = count - *r->in.resume_handle;
1570 r->out.domains->count = MIN(r->out.domains->count,
1571 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1573 r->out.domains->domains = entries + *r->in.resume_handle;
1574 r->out.domains->count = r->out.domains->count;
1576 if (r->out.domains->count < count - *r->in.resume_handle) {
1577 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1578 return STATUS_MORE_ENTRIES;
1581 return NT_STATUS_OK;
1585 comparison function for sorting lsa_DomainInformation array
1587 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1589 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1593 lsa_EnumTrustedDomainsEx
1595 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1596 struct lsa_EnumTrustedDomainsEx *r)
1598 struct dcesrv_handle *policy_handle;
1599 struct lsa_TrustDomainInfoInfoEx *entries;
1600 struct lsa_policy_state *policy_state;
1601 struct ldb_message **domains;
1602 const char *attrs[] = {
1605 "securityIdentifier",
1615 *r->out.resume_handle = 0;
1617 r->out.domains->domains = NULL;
1618 r->out.domains->count = 0;
1620 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1622 policy_state = policy_handle->data;
1624 /* search for all users in this domain. This could possibly be cached and
1625 resumed based on resume_key */
1626 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1627 "objectclass=trustedDomain");
1629 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1632 /* convert to lsa_DomainInformation format */
1633 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1635 return NT_STATUS_NO_MEMORY;
1637 for (i=0;i<count;i++) {
1638 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1639 if (!NT_STATUS_IS_OK(nt_status)) {
1644 /* sort the results by name */
1645 qsort(entries, count, sizeof(*entries),
1646 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1648 if (*r->in.resume_handle >= count) {
1649 *r->out.resume_handle = -1;
1651 return NT_STATUS_NO_MORE_ENTRIES;
1654 /* return the rest, limit by max_size. Note that we
1655 use the w2k3 element size value of 60 */
1656 r->out.domains->count = count - *r->in.resume_handle;
1657 r->out.domains->count = MIN(r->out.domains->count,
1658 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1660 r->out.domains->domains = entries + *r->in.resume_handle;
1661 r->out.domains->count = r->out.domains->count;
1663 if (r->out.domains->count < count - *r->in.resume_handle) {
1664 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1665 return STATUS_MORE_ENTRIES;
1668 return NT_STATUS_OK;
1675 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1676 struct lsa_OpenAccount *r)
1678 struct dcesrv_handle *h, *ah;
1679 struct lsa_policy_state *state;
1680 struct lsa_account_state *astate;
1682 ZERO_STRUCTP(r->out.acct_handle);
1684 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1688 astate = talloc(dce_call->conn, struct lsa_account_state);
1689 if (astate == NULL) {
1690 return NT_STATUS_NO_MEMORY;
1693 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1694 if (astate->account_sid == NULL) {
1695 talloc_free(astate);
1696 return NT_STATUS_NO_MEMORY;
1699 astate->policy = talloc_reference(astate, state);
1700 astate->access_mask = r->in.access_mask;
1702 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1704 talloc_free(astate);
1705 return NT_STATUS_NO_MEMORY;
1708 ah->data = talloc_steal(ah, astate);
1710 *r->out.acct_handle = ah->wire_handle;
1712 return NT_STATUS_OK;
1717 lsa_EnumPrivsAccount
1719 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1720 TALLOC_CTX *mem_ctx,
1721 struct lsa_EnumPrivsAccount *r)
1723 struct dcesrv_handle *h;
1724 struct lsa_account_state *astate;
1726 struct ldb_message **res;
1727 const char * const attrs[] = { "privilege", NULL};
1728 struct ldb_message_element *el;
1730 struct lsa_PrivilegeSet *privs;
1732 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1736 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1737 if (privs == NULL) {
1738 return NT_STATUS_NO_MEMORY;
1744 *r->out.privs = privs;
1746 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1747 if (sidstr == NULL) {
1748 return NT_STATUS_NO_MEMORY;
1751 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1752 "objectSid=%s", sidstr);
1754 return NT_STATUS_OK;
1757 el = ldb_msg_find_element(res[0], "privilege");
1758 if (el == NULL || el->num_values == 0) {
1759 return NT_STATUS_OK;
1762 privs->set = talloc_array(privs,
1763 struct lsa_LUIDAttribute, el->num_values);
1764 if (privs->set == NULL) {
1765 return NT_STATUS_NO_MEMORY;
1768 for (i=0;i<el->num_values;i++) {
1769 int id = sec_privilege_id((const char *)el->values[i].data);
1771 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1773 privs->set[i].attribute = 0;
1774 privs->set[i].luid.low = id;
1775 privs->set[i].luid.high = 0;
1778 privs->count = el->num_values;
1780 return NT_STATUS_OK;
1784 lsa_EnumAccountRights
1786 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1787 TALLOC_CTX *mem_ctx,
1788 struct lsa_EnumAccountRights *r)
1790 struct dcesrv_handle *h;
1791 struct lsa_policy_state *state;
1793 struct ldb_message **res;
1794 const char * const attrs[] = { "privilege", NULL};
1796 struct ldb_message_element *el;
1798 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1802 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1803 if (sidstr == NULL) {
1804 return NT_STATUS_NO_MEMORY;
1807 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1808 "(&(objectSid=%s)(privilege=*))", sidstr);
1810 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1813 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1816 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1817 dom_sid_string(mem_ctx, r->in.sid),
1818 ldb_errstring(state->sam_ldb)));
1819 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1822 el = ldb_msg_find_element(res[0], "privilege");
1823 if (el == NULL || el->num_values == 0) {
1824 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1827 r->out.rights->count = el->num_values;
1828 r->out.rights->names = talloc_array(r->out.rights,
1829 struct lsa_StringLarge, r->out.rights->count);
1830 if (r->out.rights->names == NULL) {
1831 return NT_STATUS_NO_MEMORY;
1834 for (i=0;i<el->num_values;i++) {
1835 r->out.rights->names[i].string = (const char *)el->values[i].data;
1838 return NT_STATUS_OK;
1844 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1846 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1847 TALLOC_CTX *mem_ctx,
1848 struct lsa_policy_state *state,
1850 struct dom_sid *sid,
1851 const struct lsa_RightSet *rights)
1854 struct ldb_message *msg;
1855 struct ldb_message_element *el;
1857 struct lsa_EnumAccountRights r2;
1859 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1860 if (sidstr == NULL) {
1861 return NT_STATUS_NO_MEMORY;
1864 msg = ldb_msg_new(mem_ctx);
1866 return NT_STATUS_NO_MEMORY;
1869 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1870 NULL, "objectSid=%s", sidstr);
1871 if (msg->dn == NULL) {
1873 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1874 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1876 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1878 if (!NT_STATUS_IS_OK(status)) {
1881 return NT_STATUS_NO_SUCH_USER;
1884 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1885 return NT_STATUS_NO_MEMORY;
1888 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1891 r2.in.handle = &state->handle->wire_handle;
1893 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1895 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1896 if (!NT_STATUS_IS_OK(status)) {
1897 ZERO_STRUCTP(r2.out.rights);
1901 for (i=0;i<rights->count;i++) {
1902 if (sec_privilege_id(rights->names[i].string) == -1) {
1903 return NT_STATUS_NO_SUCH_PRIVILEGE;
1906 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1908 for (j=0;j<r2.out.rights->count;j++) {
1909 if (strcasecmp_m(r2.out.rights->names[j].string,
1910 rights->names[i].string) == 0) {
1914 if (j != r2.out.rights->count) continue;
1917 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1918 if (ret != LDB_SUCCESS) {
1919 return NT_STATUS_NO_MEMORY;
1923 el = ldb_msg_find_element(msg, "privilege");
1925 return NT_STATUS_OK;
1928 ret = ldb_modify(state->sam_ldb, msg);
1930 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1931 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1933 DEBUG(3, ("Could not %s attributes from %s: %s",
1934 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1935 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1936 return NT_STATUS_UNEXPECTED_IO_ERROR;
1939 return NT_STATUS_OK;
1943 lsa_AddPrivilegesToAccount
1945 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1946 struct lsa_AddPrivilegesToAccount *r)
1948 struct lsa_RightSet rights;
1949 struct dcesrv_handle *h;
1950 struct lsa_account_state *astate;
1953 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1957 rights.count = r->in.privs->count;
1958 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1959 if (rights.names == NULL) {
1960 return NT_STATUS_NO_MEMORY;
1962 for (i=0;i<rights.count;i++) {
1963 int id = r->in.privs->set[i].luid.low;
1964 if (r->in.privs->set[i].luid.high) {
1965 return NT_STATUS_NO_SUCH_PRIVILEGE;
1967 rights.names[i].string = sec_privilege_name(id);
1968 if (rights.names[i].string == NULL) {
1969 return NT_STATUS_NO_SUCH_PRIVILEGE;
1973 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1974 LDB_FLAG_MOD_ADD, astate->account_sid,
1980 lsa_RemovePrivilegesFromAccount
1982 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1983 struct lsa_RemovePrivilegesFromAccount *r)
1985 struct lsa_RightSet *rights;
1986 struct dcesrv_handle *h;
1987 struct lsa_account_state *astate;
1990 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1994 rights = talloc(mem_ctx, struct lsa_RightSet);
1996 if (r->in.remove_all == 1 &&
1997 r->in.privs == NULL) {
1998 struct lsa_EnumAccountRights r2;
2001 r2.in.handle = &astate->policy->handle->wire_handle;
2002 r2.in.sid = astate->account_sid;
2003 r2.out.rights = rights;
2005 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2006 if (!NT_STATUS_IS_OK(status)) {
2010 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2011 LDB_FLAG_MOD_DELETE, astate->account_sid,
2015 if (r->in.remove_all != 0) {
2016 return NT_STATUS_INVALID_PARAMETER;
2019 rights->count = r->in.privs->count;
2020 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2021 if (rights->names == NULL) {
2022 return NT_STATUS_NO_MEMORY;
2024 for (i=0;i<rights->count;i++) {
2025 int id = r->in.privs->set[i].luid.low;
2026 if (r->in.privs->set[i].luid.high) {
2027 return NT_STATUS_NO_SUCH_PRIVILEGE;
2029 rights->names[i].string = sec_privilege_name(id);
2030 if (rights->names[i].string == NULL) {
2031 return NT_STATUS_NO_SUCH_PRIVILEGE;
2035 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2036 LDB_FLAG_MOD_DELETE, astate->account_sid,
2042 lsa_GetQuotasForAccount
2044 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2045 struct lsa_GetQuotasForAccount *r)
2047 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2052 lsa_SetQuotasForAccount
2054 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2055 struct lsa_SetQuotasForAccount *r)
2057 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2062 lsa_GetSystemAccessAccount
2064 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2065 struct lsa_GetSystemAccessAccount *r)
2069 struct lsa_EnumPrivsAccount enumPrivs;
2070 struct lsa_PrivilegeSet *privs;
2072 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2074 return NT_STATUS_NO_MEMORY;
2080 enumPrivs.in.handle = r->in.handle;
2081 enumPrivs.out.privs = &privs;
2083 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2084 if (!NT_STATUS_IS_OK(status)) {
2088 *(r->out.access_mask) = 0x00000000;
2090 for (i = 0; i < privs->count; i++) {
2091 int priv = privs->set[i].luid.low;
2094 case SEC_PRIV_INTERACTIVE_LOGON:
2095 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2097 case SEC_PRIV_NETWORK_LOGON:
2098 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2100 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2101 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2106 return NT_STATUS_OK;
2111 lsa_SetSystemAccessAccount
2113 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2114 struct lsa_SetSystemAccessAccount *r)
2116 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2123 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2124 struct lsa_CreateSecret *r)
2126 struct dcesrv_handle *policy_handle;
2127 struct lsa_policy_state *policy_state;
2128 struct lsa_secret_state *secret_state;
2129 struct dcesrv_handle *handle;
2130 struct ldb_message **msgs, *msg;
2132 const char *attrs[] = {
2140 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2141 ZERO_STRUCTP(r->out.sec_handle);
2143 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2145 case SECURITY_SYSTEM:
2146 case SECURITY_ADMINISTRATOR:
2149 /* Users and annonymous are not allowed create secrets */
2150 return NT_STATUS_ACCESS_DENIED;
2153 policy_state = policy_handle->data;
2155 if (!r->in.name.string) {
2156 return NT_STATUS_INVALID_PARAMETER;
2159 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2160 if (!secret_state) {
2161 return NT_STATUS_NO_MEMORY;
2163 secret_state->policy = policy_state;
2165 msg = ldb_msg_new(mem_ctx);
2167 return NT_STATUS_NO_MEMORY;
2170 if (strncmp("G$", r->in.name.string, 2) == 0) {
2172 name = &r->in.name.string[2];
2173 /* 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) */
2174 secret_state->sam_ldb = talloc_reference(secret_state,
2175 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)));
2176 secret_state->global = true;
2178 if (strlen(name) < 1) {
2179 return NT_STATUS_INVALID_PARAMETER;
2182 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2183 /* search for the secret record */
2184 ret = gendb_search(secret_state->sam_ldb,
2185 mem_ctx, policy_state->system_dn, &msgs, attrs,
2186 "(&(cn=%s)(objectclass=secret))",
2189 return NT_STATUS_OBJECT_NAME_COLLISION;
2193 DEBUG(0,("Failure searching for CN=%s: %s\n",
2194 name2, ldb_errstring(secret_state->sam_ldb)));
2195 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2198 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2199 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2200 return NT_STATUS_NO_MEMORY;
2203 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2206 secret_state->global = false;
2208 name = r->in.name.string;
2209 if (strlen(name) < 1) {
2210 return NT_STATUS_INVALID_PARAMETER;
2213 secret_state->sam_ldb = talloc_reference(secret_state,
2214 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2215 /* search for the secret record */
2216 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2217 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2219 "(&(cn=%s)(objectclass=secret))",
2220 ldb_binary_encode_string(mem_ctx, name));
2222 return NT_STATUS_OBJECT_NAME_COLLISION;
2226 DEBUG(0,("Failure searching for CN=%s: %s\n",
2227 name, ldb_errstring(secret_state->sam_ldb)));
2228 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2231 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2232 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2235 /* pull in all the template attributes. Note this is always from the global samdb */
2236 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
2239 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2241 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2244 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2246 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2248 /* create the secret */
2249 ret = ldb_add(secret_state->sam_ldb, msg);
2251 DEBUG(0,("Failed to create secret record %s: %s\n",
2252 ldb_dn_get_linearized(msg->dn),
2253 ldb_errstring(secret_state->sam_ldb)));
2254 return NT_STATUS_ACCESS_DENIED;
2257 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2259 return NT_STATUS_NO_MEMORY;
2262 handle->data = talloc_steal(handle, secret_state);
2264 secret_state->access_mask = r->in.access_mask;
2265 secret_state->policy = talloc_reference(secret_state, policy_state);
2267 *r->out.sec_handle = handle->wire_handle;
2269 return NT_STATUS_OK;
2276 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2277 struct lsa_OpenSecret *r)
2279 struct dcesrv_handle *policy_handle;
2281 struct lsa_policy_state *policy_state;
2282 struct lsa_secret_state *secret_state;
2283 struct dcesrv_handle *handle;
2284 struct ldb_message **msgs;
2285 const char *attrs[] = {
2293 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2294 ZERO_STRUCTP(r->out.sec_handle);
2295 policy_state = policy_handle->data;
2297 if (!r->in.name.string) {
2298 return NT_STATUS_INVALID_PARAMETER;
2301 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2303 case SECURITY_SYSTEM:
2304 case SECURITY_ADMINISTRATOR:
2307 /* Users and annonymous are not allowed to access secrets */
2308 return NT_STATUS_ACCESS_DENIED;
2311 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2312 if (!secret_state) {
2313 return NT_STATUS_NO_MEMORY;
2315 secret_state->policy = policy_state;
2317 if (strncmp("G$", r->in.name.string, 2) == 0) {
2318 name = &r->in.name.string[2];
2319 /* 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) */
2320 secret_state->sam_ldb = talloc_reference(secret_state,
2321 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)));
2322 secret_state->global = true;
2324 if (strlen(name) < 1) {
2325 return NT_STATUS_INVALID_PARAMETER;
2328 /* search for the secret record */
2329 ret = gendb_search(secret_state->sam_ldb,
2330 mem_ctx, policy_state->system_dn, &msgs, attrs,
2331 "(&(cn=%s Secret)(objectclass=secret))",
2332 ldb_binary_encode_string(mem_ctx, name));
2334 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2338 DEBUG(0,("Found %d records matching DN %s\n", ret,
2339 ldb_dn_get_linearized(policy_state->system_dn)));
2340 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2344 secret_state->global = false;
2345 secret_state->sam_ldb = talloc_reference(secret_state,
2346 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2348 name = r->in.name.string;
2349 if (strlen(name) < 1) {
2350 return NT_STATUS_INVALID_PARAMETER;
2353 /* search for the secret record */
2354 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2355 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2357 "(&(cn=%s)(objectclass=secret))",
2358 ldb_binary_encode_string(mem_ctx, name));
2360 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2364 DEBUG(0,("Found %d records matching CN=%s\n",
2365 ret, ldb_binary_encode_string(mem_ctx, name)));
2366 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2370 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2372 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2374 return NT_STATUS_NO_MEMORY;
2377 handle->data = talloc_steal(handle, secret_state);
2379 secret_state->access_mask = r->in.access_mask;
2380 secret_state->policy = talloc_reference(secret_state, policy_state);
2382 *r->out.sec_handle = handle->wire_handle;
2384 return NT_STATUS_OK;
2391 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2392 struct lsa_SetSecret *r)
2395 struct dcesrv_handle *h;
2396 struct lsa_secret_state *secret_state;
2397 struct ldb_message *msg;
2398 DATA_BLOB session_key;
2399 DATA_BLOB crypt_secret, secret;
2402 NTSTATUS status = NT_STATUS_OK;
2404 struct timeval now = timeval_current();
2405 NTTIME nt_now = timeval_to_nttime(&now);
2407 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2409 secret_state = h->data;
2411 msg = ldb_msg_new(mem_ctx);
2413 return NT_STATUS_NO_MEMORY;
2416 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2418 return NT_STATUS_NO_MEMORY;
2420 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2421 if (!NT_STATUS_IS_OK(status)) {
2425 if (r->in.old_val) {
2427 crypt_secret.data = r->in.old_val->data;
2428 crypt_secret.length = r->in.old_val->size;
2430 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2431 if (!NT_STATUS_IS_OK(status)) {
2435 val.data = secret.data;
2436 val.length = secret.length;
2439 if (samdb_msg_add_value(secret_state->sam_ldb,
2440 mem_ctx, msg, "priorValue", &val) != 0) {
2441 return NT_STATUS_NO_MEMORY;
2444 /* set old value mtime */
2445 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2446 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2447 return NT_STATUS_NO_MEMORY;
2451 /* If the old value is not set, then migrate the
2452 * current value to the old value */
2453 const struct ldb_val *old_val;
2454 NTTIME last_set_time;
2455 struct ldb_message **res;
2456 const char *attrs[] = {
2462 /* search for the secret record */
2463 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2464 secret_state->secret_dn, &res, attrs);
2466 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2470 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2471 ldb_dn_get_linearized(secret_state->secret_dn)));
2472 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2475 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2476 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2480 if (samdb_msg_add_value(secret_state->sam_ldb,
2481 mem_ctx, msg, "priorValue",
2483 return NT_STATUS_NO_MEMORY;
2486 if (samdb_msg_add_delete(secret_state->sam_ldb,
2487 mem_ctx, msg, "priorValue")) {
2488 return NT_STATUS_NO_MEMORY;
2493 /* set old value mtime */
2494 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2495 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2496 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2497 return NT_STATUS_NO_MEMORY;
2500 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2501 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2502 return NT_STATUS_NO_MEMORY;
2507 if (r->in.new_val) {
2509 crypt_secret.data = r->in.new_val->data;
2510 crypt_secret.length = r->in.new_val->size;
2512 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2513 if (!NT_STATUS_IS_OK(status)) {
2517 val.data = secret.data;
2518 val.length = secret.length;
2521 if (samdb_msg_add_value(secret_state->sam_ldb,
2522 mem_ctx, msg, "currentValue", &val) != 0) {
2523 return NT_STATUS_NO_MEMORY;
2526 /* set new value mtime */
2527 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2528 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2529 return NT_STATUS_NO_MEMORY;
2533 /* NULL out the NEW value */
2534 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2535 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2536 return NT_STATUS_NO_MEMORY;
2538 if (samdb_msg_add_delete(secret_state->sam_ldb,
2539 mem_ctx, msg, "currentValue")) {
2540 return NT_STATUS_NO_MEMORY;
2544 /* modify the samdb record */
2545 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2547 /* we really need samdb.c to return NTSTATUS */
2548 return NT_STATUS_UNSUCCESSFUL;
2551 return NT_STATUS_OK;
2558 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2559 struct lsa_QuerySecret *r)
2561 struct dcesrv_handle *h;
2562 struct lsa_secret_state *secret_state;
2563 struct ldb_message *msg;
2564 DATA_BLOB session_key;
2565 DATA_BLOB crypt_secret, secret;
2567 struct ldb_message **res;
2568 const char *attrs[] = {
2578 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2580 /* Ensure user is permitted to read this... */
2581 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2583 case SECURITY_SYSTEM:
2584 case SECURITY_ADMINISTRATOR:
2587 /* Users and annonymous are not allowed to read secrets */
2588 return NT_STATUS_ACCESS_DENIED;
2591 secret_state = h->data;
2593 /* pull all the user attributes */
2594 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2595 secret_state->secret_dn, &res, attrs);
2597 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2601 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2602 if (!NT_STATUS_IS_OK(nt_status)) {
2606 if (r->in.old_val) {
2607 const struct ldb_val *prior_val;
2608 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2609 if (!r->out.old_val) {
2610 return NT_STATUS_NO_MEMORY;
2612 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2614 if (prior_val && prior_val->length) {
2615 secret.data = prior_val->data;
2616 secret.length = prior_val->length;
2619 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2620 if (!crypt_secret.length) {
2621 return NT_STATUS_NO_MEMORY;
2623 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2624 if (!r->out.old_val->buf) {
2625 return NT_STATUS_NO_MEMORY;
2627 r->out.old_val->buf->size = crypt_secret.length;
2628 r->out.old_val->buf->length = crypt_secret.length;
2629 r->out.old_val->buf->data = crypt_secret.data;
2633 if (r->in.old_mtime) {
2634 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2635 if (!r->out.old_mtime) {
2636 return NT_STATUS_NO_MEMORY;
2638 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2641 if (r->in.new_val) {
2642 const struct ldb_val *new_val;
2643 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2644 if (!r->out.new_val) {
2645 return NT_STATUS_NO_MEMORY;
2648 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2650 if (new_val && new_val->length) {
2651 secret.data = new_val->data;
2652 secret.length = new_val->length;
2655 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2656 if (!crypt_secret.length) {
2657 return NT_STATUS_NO_MEMORY;
2659 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2660 if (!r->out.new_val->buf) {
2661 return NT_STATUS_NO_MEMORY;
2663 r->out.new_val->buf->length = crypt_secret.length;
2664 r->out.new_val->buf->size = crypt_secret.length;
2665 r->out.new_val->buf->data = crypt_secret.data;
2669 if (r->in.new_mtime) {
2670 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2671 if (!r->out.new_mtime) {
2672 return NT_STATUS_NO_MEMORY;
2674 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2677 return NT_STATUS_OK;
2684 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2685 TALLOC_CTX *mem_ctx,
2686 struct lsa_LookupPrivValue *r)
2688 struct dcesrv_handle *h;
2689 struct lsa_policy_state *state;
2692 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2696 id = sec_privilege_id(r->in.name->string);
2698 return NT_STATUS_NO_SUCH_PRIVILEGE;
2701 r->out.luid->low = id;
2702 r->out.luid->high = 0;
2704 return NT_STATUS_OK;
2711 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2712 TALLOC_CTX *mem_ctx,
2713 struct lsa_LookupPrivName *r)
2715 struct dcesrv_handle *h;
2716 struct lsa_policy_state *state;
2717 struct lsa_StringLarge *name;
2718 const char *privname;
2720 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2724 if (r->in.luid->high != 0) {
2725 return NT_STATUS_NO_SUCH_PRIVILEGE;
2728 privname = sec_privilege_name(r->in.luid->low);
2729 if (privname == NULL) {
2730 return NT_STATUS_NO_SUCH_PRIVILEGE;
2733 name = talloc(mem_ctx, struct lsa_StringLarge);
2735 return NT_STATUS_NO_MEMORY;
2738 name->string = privname;
2740 *r->out.name = name;
2742 return NT_STATUS_OK;
2747 lsa_LookupPrivDisplayName
2749 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2750 TALLOC_CTX *mem_ctx,
2751 struct lsa_LookupPrivDisplayName *r)
2753 struct dcesrv_handle *h;
2754 struct lsa_policy_state *state;
2755 struct lsa_StringLarge *disp_name = NULL;
2758 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2762 id = sec_privilege_id(r->in.name->string);
2764 return NT_STATUS_NO_SUCH_PRIVILEGE;
2767 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2768 if (disp_name == NULL) {
2769 return NT_STATUS_NO_MEMORY;
2772 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
2773 if (disp_name->string == NULL) {
2774 return NT_STATUS_INTERNAL_ERROR;
2777 *r->out.disp_name = disp_name;
2778 *r->out.returned_language_id = 0;
2780 return NT_STATUS_OK;
2785 lsa_EnumAccountsWithUserRight
2787 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2788 TALLOC_CTX *mem_ctx,
2789 struct lsa_EnumAccountsWithUserRight *r)
2791 struct dcesrv_handle *h;
2792 struct lsa_policy_state *state;
2794 struct ldb_message **res;
2795 const char * const attrs[] = { "objectSid", NULL};
2796 const char *privname;
2798 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2802 if (r->in.name == NULL) {
2803 return NT_STATUS_NO_SUCH_PRIVILEGE;
2806 privname = r->in.name->string;
2807 if (sec_privilege_id(privname) == -1) {
2808 return NT_STATUS_NO_SUCH_PRIVILEGE;
2811 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2812 "privilege=%s", privname);
2814 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2817 return NT_STATUS_NO_MORE_ENTRIES;
2820 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2821 if (r->out.sids->sids == NULL) {
2822 return NT_STATUS_NO_MEMORY;
2824 for (i=0;i<ret;i++) {
2825 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2826 res[i], "objectSid");
2827 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2829 r->out.sids->num_sids = ret;
2831 return NT_STATUS_OK;
2836 lsa_AddAccountRights
2838 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2839 TALLOC_CTX *mem_ctx,
2840 struct lsa_AddAccountRights *r)
2842 struct dcesrv_handle *h;
2843 struct lsa_policy_state *state;
2845 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2849 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2851 r->in.sid, r->in.rights);
2856 lsa_RemoveAccountRights
2858 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2859 TALLOC_CTX *mem_ctx,
2860 struct lsa_RemoveAccountRights *r)
2862 struct dcesrv_handle *h;
2863 struct lsa_policy_state *state;
2865 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2869 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2870 LDB_FLAG_MOD_DELETE,
2871 r->in.sid, r->in.rights);
2876 lsa_StorePrivateData
2878 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2879 struct lsa_StorePrivateData *r)
2881 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2886 lsa_RetrievePrivateData
2888 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2889 struct lsa_RetrievePrivateData *r)
2891 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2898 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2899 struct lsa_GetUserName *r)
2901 NTSTATUS status = NT_STATUS_OK;
2902 const char *account_name;
2903 const char *authority_name;
2904 struct lsa_String *_account_name;
2905 struct lsa_String *_authority_name = NULL;
2907 /* this is what w2k3 does */
2908 r->out.account_name = r->in.account_name;
2909 r->out.authority_name = r->in.authority_name;
2911 if (r->in.account_name
2912 && *r->in.account_name
2913 /* && *(*r->in.account_name)->string */
2915 return NT_STATUS_INVALID_PARAMETER;
2918 if (r->in.authority_name
2919 && *r->in.authority_name
2920 /* && *(*r->in.authority_name)->string */
2922 return NT_STATUS_INVALID_PARAMETER;
2925 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2926 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2928 _account_name = talloc(mem_ctx, struct lsa_String);
2929 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2930 _account_name->string = account_name;
2932 if (r->in.authority_name) {
2933 _authority_name = talloc(mem_ctx, struct lsa_String);
2934 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2935 _authority_name->string = authority_name;
2938 *r->out.account_name = _account_name;
2939 if (r->out.authority_name) {
2940 *r->out.authority_name = _authority_name;
2949 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2950 TALLOC_CTX *mem_ctx,
2951 struct lsa_SetInfoPolicy2 *r)
2953 /* need to support these */
2954 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2958 lsa_QueryDomainInformationPolicy
2960 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2961 TALLOC_CTX *mem_ctx,
2962 struct lsa_QueryDomainInformationPolicy *r)
2964 union lsa_DomainInformationPolicy *info;
2966 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
2968 return NT_STATUS_NO_MEMORY;
2971 switch (r->in.level) {
2972 case LSA_DOMAIN_INFO_POLICY_EFS:
2974 *r->out.info = NULL;
2975 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2976 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
2978 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
2979 struct smb_krb5_context *smb_krb5_context;
2980 int ret = smb_krb5_init_context(mem_ctx,
2981 dce_call->event_ctx,
2982 dce_call->conn->dce_ctx->lp_ctx,
2985 talloc_free(r->out.info);
2987 return NT_STATUS_INTERNAL_ERROR;
2989 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
2990 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2991 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2992 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
2993 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
2994 talloc_free(smb_krb5_context);
2995 *r->out.info = info;
2996 return NT_STATUS_OK;
3000 *r->out.info = NULL;
3001 return NT_STATUS_INVALID_INFO_CLASS;
3006 lsa_SetDomInfoPolicy
3008 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
3009 TALLOC_CTX *mem_ctx,
3010 struct lsa_SetDomainInformationPolicy *r)
3012 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3018 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3019 TALLOC_CTX *mem_ctx,
3020 struct lsa_TestCall *r)
3022 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3028 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3029 struct lsa_CREDRWRITE *r)
3031 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3038 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3039 struct lsa_CREDRREAD *r)
3041 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3048 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3049 struct lsa_CREDRENUMERATE *r)
3051 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3056 lsa_CREDRWRITEDOMAINCREDENTIALS
3058 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3059 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3061 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3066 lsa_CREDRREADDOMAINCREDENTIALS
3068 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3069 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3071 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3078 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3079 struct lsa_CREDRDELETE *r)
3081 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3086 lsa_CREDRGETTARGETINFO
3088 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3089 struct lsa_CREDRGETTARGETINFO *r)
3091 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3096 lsa_CREDRPROFILELOADED
3098 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3099 struct lsa_CREDRPROFILELOADED *r)
3101 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3106 lsa_CREDRGETSESSIONTYPES
3108 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3109 struct lsa_CREDRGETSESSIONTYPES *r)
3111 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3116 lsa_LSARREGISTERAUDITEVENT
3118 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3119 struct lsa_LSARREGISTERAUDITEVENT *r)
3121 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3126 lsa_LSARGENAUDITEVENT
3128 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3129 struct lsa_LSARGENAUDITEVENT *r)
3131 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3136 lsa_LSARUNREGISTERAUDITEVENT
3138 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3139 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3141 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3146 lsa_lsaRQueryForestTrustInformation
3148 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3149 struct lsa_lsaRQueryForestTrustInformation *r)
3151 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3156 lsa_LSARSETFORESTTRUSTINFORMATION
3158 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3159 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3161 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3168 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3169 struct lsa_CREDRRENAME *r)
3171 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3177 lsa_LSAROPENPOLICYSCE
3179 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3180 struct lsa_LSAROPENPOLICYSCE *r)
3182 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3187 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3189 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3190 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3192 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3197 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3199 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3200 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3202 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3207 lsa_LSARADTREPORTSECURITYEVENT
3209 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3210 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3212 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3216 /* include the generated boilerplate */
3217 #include "librpc/gen_ndr/ndr_lsa_s.c"
3221 /*****************************************
3222 NOTE! The remaining calls below were
3223 removed in w2k3, so the DCESRV_FAULT()
3224 replies are the correct implementation. Do
3225 not try and fill these in with anything else
3226 ******************************************/
3229 dssetup_DsRoleDnsNameToFlatName
3231 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3232 struct dssetup_DsRoleDnsNameToFlatName *r)
3234 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3239 dssetup_DsRoleDcAsDc
3241 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3242 struct dssetup_DsRoleDcAsDc *r)
3244 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3249 dssetup_DsRoleDcAsReplica
3251 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3252 struct dssetup_DsRoleDcAsReplica *r)
3254 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3259 dssetup_DsRoleDemoteDc
3261 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3262 struct dssetup_DsRoleDemoteDc *r)
3264 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3269 dssetup_DsRoleGetDcOperationProgress
3271 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3272 struct dssetup_DsRoleGetDcOperationProgress *r)
3274 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3279 dssetup_DsRoleGetDcOperationResults
3281 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3282 struct dssetup_DsRoleGetDcOperationResults *r)
3284 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3289 dssetup_DsRoleCancel
3291 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3292 struct dssetup_DsRoleCancel *r)
3294 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3299 dssetup_DsRoleServerSaveStateForUpgrade
3301 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3302 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3304 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3309 dssetup_DsRoleUpgradeDownlevelServer
3311 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3312 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3314 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3319 dssetup_DsRoleAbortDownlevelServerUpgrade
3321 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3322 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3324 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3328 /* include the generated boilerplate */
3329 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3331 NTSTATUS dcerpc_server_lsa_init(void)
3335 ret = dcerpc_server_dssetup_init();
3336 if (!NT_STATUS_IS_OK(ret)) {
3339 ret = dcerpc_server_lsarpc_init();
3340 if (!NT_STATUS_IS_OK(ret)) {