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 "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;
404 fill in the AccountDomain info
406 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
407 struct lsa_DomainInfo *info)
409 info->name.string = state->domain_name;
410 info->sid = state->domain_sid;
416 fill in the DNS domain info
418 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
419 struct lsa_DnsDomainInfo *info)
421 info->name.string = state->domain_name;
422 info->sid = state->domain_sid;
423 info->dns_domain.string = state->domain_dns;
424 info->dns_forest.string = state->forest_dns;
425 info->domain_guid = state->domain_guid;
433 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
434 struct lsa_QueryInfoPolicy2 *r)
436 struct lsa_policy_state *state;
437 struct dcesrv_handle *h;
441 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
445 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
447 return NT_STATUS_NO_MEMORY;
450 ZERO_STRUCTP(r->out.info);
452 switch (r->in.level) {
453 case LSA_POLICY_INFO_AUDIT_LOG:
454 /* we don't need to fill in any of this */
455 ZERO_STRUCT(r->out.info->audit_log);
457 case LSA_POLICY_INFO_AUDIT_EVENTS:
458 /* we don't need to fill in any of this */
459 ZERO_STRUCT(r->out.info->audit_events);
461 case LSA_POLICY_INFO_PD:
462 /* we don't need to fill in any of this */
463 ZERO_STRUCT(r->out.info->pd);
465 case LSA_POLICY_INFO_DOMAIN:
466 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
467 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
468 case LSA_POLICY_INFO_ROLE:
469 r->out.info->role.role = LSA_ROLE_PRIMARY;
472 case LSA_POLICY_INFO_DNS:
473 case LSA_POLICY_INFO_DNS_INT:
474 return dcesrv_lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
476 case LSA_POLICY_INFO_REPLICA:
477 ZERO_STRUCT(r->out.info->replica);
480 case LSA_POLICY_INFO_QUOTA:
481 ZERO_STRUCT(r->out.info->quota);
484 case LSA_POLICY_INFO_AUDIT_FULL_SET:
485 case LSA_POLICY_INFO_DB:
486 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
487 /* windows gives INVALID_PARAMETER */
489 return NT_STATUS_INVALID_PARAMETER;
493 return NT_STATUS_INVALID_INFO_CLASS;
499 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
500 struct lsa_QueryInfoPolicy *r)
502 struct lsa_QueryInfoPolicy2 r2;
507 r2.in.handle = r->in.handle;
508 r2.in.level = r->in.level;
510 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
512 r->out.info = r2.out.info;
520 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
521 struct lsa_SetInfoPolicy *r)
523 /* need to support this */
524 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
531 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
532 struct lsa_ClearAuditLog *r)
534 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
541 This call does not seem to have any long-term effects, hence no database operations
543 we need to talk to the MS product group to find out what this account database means!
545 answer is that the lsa database is totally separate from the SAM and
546 ldap databases. We are going to need a separate ldb to store these
547 accounts. The SIDs on this account bear no relation to the SIDs in
550 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
551 struct lsa_CreateAccount *r)
553 struct lsa_account_state *astate;
555 struct lsa_policy_state *state;
556 struct dcesrv_handle *h, *ah;
558 ZERO_STRUCTP(r->out.acct_handle);
560 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
564 astate = talloc(dce_call->conn, struct lsa_account_state);
565 if (astate == NULL) {
566 return NT_STATUS_NO_MEMORY;
569 astate->account_sid = dom_sid_dup(astate, r->in.sid);
570 if (astate->account_sid == NULL) {
572 return NT_STATUS_NO_MEMORY;
575 astate->policy = talloc_reference(astate, state);
576 astate->access_mask = r->in.access_mask;
578 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
581 return NT_STATUS_NO_MEMORY;
584 ah->data = talloc_steal(ah, astate);
586 *r->out.acct_handle = ah->wire_handle;
595 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
596 struct lsa_EnumAccounts *r)
598 struct dcesrv_handle *h;
599 struct lsa_policy_state *state;
601 struct ldb_message **res;
602 const char * const attrs[] = { "objectSid", NULL};
605 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
609 /* NOTE: This call must only return accounts that have at least
612 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
613 "(&(objectSid=*)(privilege=*))");
615 return NT_STATUS_NO_SUCH_USER;
618 if (*r->in.resume_handle >= ret) {
619 return NT_STATUS_NO_MORE_ENTRIES;
622 count = ret - *r->in.resume_handle;
623 if (count > r->in.num_entries) {
624 count = r->in.num_entries;
628 return NT_STATUS_NO_MORE_ENTRIES;
631 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
632 if (r->out.sids->sids == NULL) {
633 return NT_STATUS_NO_MEMORY;
636 for (i=0;i<count;i++) {
637 r->out.sids->sids[i].sid =
638 samdb_result_dom_sid(r->out.sids->sids,
639 res[i + *r->in.resume_handle],
641 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
644 r->out.sids->num_sids = count;
645 *r->out.resume_handle = count + *r->in.resume_handle;
653 lsa_CreateTrustedDomainEx2
655 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
657 struct lsa_CreateTrustedDomainEx2 *r,
660 struct dcesrv_handle *policy_handle;
661 struct lsa_policy_state *policy_state;
662 struct lsa_trusted_domain_state *trusted_domain_state;
663 struct dcesrv_handle *handle;
664 struct ldb_message **msgs, *msg, *msg_user;
665 const char *attrs[] = {
668 const char *netbios_name;
669 const char *dns_name;
671 DATA_BLOB session_key = data_blob(NULL, 0);
672 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
673 struct trustDomainPasswords auth_struct;
676 enum ndr_err_code ndr_err;
678 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
679 ZERO_STRUCTP(r->out.trustdom_handle);
681 policy_state = policy_handle->data;
683 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
684 if (!NT_STATUS_IS_OK(nt_status)) {
688 netbios_name = r->in.info->netbios_name.string;
690 return NT_STATUS_INVALID_PARAMETER;
693 dns_name = r->in.info->domain_name.string;
695 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
696 if (!trusted_domain_state) {
697 return NT_STATUS_NO_MEMORY;
699 trusted_domain_state->policy = policy_state;
701 if (strcasecmp(netbios_name, "BUILTIN") == 0
702 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
703 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
704 return NT_STATUS_INVALID_PARAMETER;;
707 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
708 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
709 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
710 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
711 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
712 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
715 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
716 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
717 /* No secrets are created at this time, for this function */
718 auth_struct.outgoing.count = 0;
719 auth_struct.incoming.count = 0;
721 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data, r->in.auth_info->auth_blob.size);
722 arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key);
723 ndr_err = ndr_pull_struct_blob(&auth_blob, mem_ctx,
724 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
726 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
727 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
728 return NT_STATUS_INVALID_PARAMETER;
731 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
732 if (auth_struct.incoming.count > 1) {
733 return NT_STATUS_INVALID_PARAMETER;
738 if (auth_struct.incoming.count) {
740 struct trustAuthInOutBlob incoming;
742 incoming.count = auth_struct.incoming.count;
743 incoming.current = talloc(mem_ctx, struct AuthenticationInformationArray);
744 if (!incoming.current) {
745 return NT_STATUS_NO_MEMORY;
748 incoming.current->array = *auth_struct.incoming.current;
749 if (!incoming.current->array) {
750 return NT_STATUS_NO_MEMORY;
753 incoming.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
754 if (!incoming.previous) {
755 return NT_STATUS_NO_MEMORY;
757 incoming.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, incoming.count);
758 if (!incoming.previous->array) {
759 return NT_STATUS_NO_MEMORY;
762 for (i = 0; i < incoming.count; i++) {
763 incoming.previous->array[i].LastUpdateTime = 0;
764 incoming.previous->array[i].AuthType = 0;
766 ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx,
767 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
769 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
770 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
771 return NT_STATUS_INVALID_PARAMETER;
774 trustAuthIncoming = data_blob(NULL, 0);
777 if (auth_struct.outgoing.count) {
779 struct trustAuthInOutBlob outgoing;
781 outgoing.count = auth_struct.outgoing.count;
782 outgoing.current = talloc(mem_ctx, struct AuthenticationInformationArray);
783 if (!outgoing.current) {
784 return NT_STATUS_NO_MEMORY;
787 outgoing.current->array = *auth_struct.outgoing.current;
788 if (!outgoing.current->array) {
789 return NT_STATUS_NO_MEMORY;
792 outgoing.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
793 if (!outgoing.previous) {
794 return NT_STATUS_NO_MEMORY;
796 outgoing.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, outgoing.count);
797 if (!outgoing.previous->array) {
798 return NT_STATUS_NO_MEMORY;
801 for (i = 0; i < outgoing.count; i++) {
802 outgoing.previous->array[i].LastUpdateTime = 0;
803 outgoing.previous->array[i].AuthType = 0;
805 ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx,
806 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
808 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
809 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
810 return NT_STATUS_INVALID_PARAMETER;
813 trustAuthOutgoing = data_blob(NULL, 0);
816 ret = ldb_transaction_start(policy_state->sam_ldb);
817 if (ret != LDB_SUCCESS) {
818 return NT_STATUS_INTERNAL_DB_CORRUPTION;
822 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
823 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
824 /* search for the trusted_domain record */
825 ret = gendb_search(policy_state->sam_ldb,
826 mem_ctx, policy_state->system_dn, &msgs, attrs,
827 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
828 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
830 ldb_transaction_cancel(policy_state->sam_ldb);
831 return NT_STATUS_OBJECT_NAME_COLLISION;
834 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
835 /* search for the trusted_domain record */
836 ret = gendb_search(policy_state->sam_ldb,
837 mem_ctx, policy_state->system_dn, &msgs, attrs,
838 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
839 netbios_encoded, netbios_encoded, netbios_encoded);
841 ldb_transaction_cancel(policy_state->sam_ldb);
842 return NT_STATUS_OBJECT_NAME_COLLISION;
847 ldb_transaction_cancel(policy_state->sam_ldb);
848 return NT_STATUS_INTERNAL_DB_CORRUPTION;
851 name = dns_name ? dns_name : netbios_name;
853 msg = ldb_msg_new(mem_ctx);
855 return NT_STATUS_NO_MEMORY;
858 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
859 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
860 ldb_transaction_cancel(policy_state->sam_ldb);
861 return NT_STATUS_NO_MEMORY;
864 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", netbios_name);
866 if (r->in.info->sid) {
867 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
869 ldb_transaction_cancel(policy_state->sam_ldb);
870 return NT_STATUS_NO_MEMORY;
873 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
876 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
878 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
880 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
882 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
885 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
888 if (trustAuthIncoming.data) {
889 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
890 if (ret != LDB_SUCCESS) {
891 ldb_transaction_cancel(policy_state->sam_ldb);
892 return NT_STATUS_NO_MEMORY;
895 if (trustAuthOutgoing.data) {
896 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
897 if (ret != LDB_SUCCESS) {
898 ldb_transaction_cancel(policy_state->sam_ldb);
899 return NT_STATUS_NO_MEMORY;
903 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
905 /* create the trusted_domain */
906 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
910 case LDB_ERR_ENTRY_ALREADY_EXISTS:
911 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
912 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
913 ldb_dn_get_linearized(msg->dn),
914 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
915 return NT_STATUS_DOMAIN_EXISTS;
916 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
917 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
918 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
919 ldb_dn_get_linearized(msg->dn),
920 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
921 return NT_STATUS_ACCESS_DENIED;
923 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
924 DEBUG(0,("Failed to create user record %s: %s\n",
925 ldb_dn_get_linearized(msg->dn),
926 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
927 return NT_STATUS_INTERNAL_DB_CORRUPTION;
930 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
931 msg_user = ldb_msg_new(mem_ctx);
933 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
934 return NT_STATUS_NO_MEMORY;
937 /* Inbound trusts must also create a cn=users object to match */
939 trusted_domain_state->trusted_domain_user_dn = msg_user->dn
940 = ldb_dn_copy(trusted_domain_state, policy_state->domain_dn);
941 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=users")) {
942 ldb_transaction_cancel(policy_state->sam_ldb);
943 return NT_STATUS_NO_MEMORY;
946 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=%s", netbios_name)) {
947 ldb_transaction_cancel(policy_state->sam_ldb);
948 return NT_STATUS_NO_MEMORY;
951 ldb_msg_add_string(msg_user, "objectClass", "user");
953 ldb_msg_add_steal_string(msg_user, "samAccountName",
954 talloc_asprintf(mem_ctx, "%s$", netbios_name));
956 if (samdb_msg_add_uint(trusted_domain_state->policy->sam_ldb, mem_ctx, msg_user,
957 "userAccountControl",
958 UF_INTERDOMAIN_TRUST_ACCOUNT) != 0) {
959 ldb_transaction_cancel(policy_state->sam_ldb);
960 return NT_STATUS_NO_MEMORY;
963 if (auth_struct.incoming.count) {
965 for (i=0; i < auth_struct.incoming.count; i++ ) {
966 if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_NT4OWF) {
967 samdb_msg_add_hash(trusted_domain_state->policy->sam_ldb,
968 mem_ctx, msg_user, "unicodePwd",
969 &auth_struct.incoming.current[i]->AuthInfo.nt4owf.password);
970 } else if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_CLEAR) {
971 struct samr_Password hash;
973 . We cannot do this, as windows chooses to send in random passwords here, that won't convert to UTF8
974 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb,
975 mem_ctx, msg_user, "userPassword",
976 auth_struct.incoming.current->array[i].AuthInfo.clear.password);
978 mdfour(hash.hash, auth_struct.incoming.current[i]->AuthInfo.clear.password,
979 auth_struct.incoming.current[i]->AuthInfo.clear.size);
980 samdb_msg_add_hash(trusted_domain_state->policy->sam_ldb,
981 mem_ctx, msg_user, "unicodePwd",
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 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 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
1347 return NT_STATUS_NO_MEMORY;
1349 switch (r->in.level) {
1350 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1351 r->out.info->name.netbios_name.string
1352 = samdb_result_string(msg, "flatname", NULL);
1354 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1355 r->out.info->posix_offset.posix_offset
1356 = samdb_result_uint(msg, "posixOffset", 0);
1358 #if 0 /* Win2k3 doesn't implement this */
1359 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1360 r->out.info->info_basic.netbios_name.string
1361 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1362 r->out.info->info_basic.sid
1363 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1366 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1367 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
1369 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1370 ZERO_STRUCT(r->out.info->full_info);
1371 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
1373 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1374 ZERO_STRUCT(r->out.info->full_info2_internal);
1375 r->out.info->full_info2_internal.posix_offset.posix_offset
1376 = samdb_result_uint(msg, "posixOffset", 0);
1377 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info2_internal.info.info_ex);
1379 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
1380 r->out.info->enc_types.enc_types
1381 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
1384 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1385 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1386 /* oops, we don't want to return the info after all */
1387 talloc_free(r->out.info);
1389 return NT_STATUS_INVALID_PARAMETER;
1391 /* oops, we don't want to return the info after all */
1392 talloc_free(r->out.info);
1394 return NT_STATUS_INVALID_INFO_CLASS;
1397 return NT_STATUS_OK;
1402 lsa_QueryTrustedDomainInfoBySid
1404 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1405 struct lsa_QueryTrustedDomainInfoBySid *r)
1408 struct lsa_OpenTrustedDomain open;
1409 struct lsa_QueryTrustedDomainInfo query;
1410 struct dcesrv_handle *h;
1411 open.in.handle = r->in.handle;
1412 open.in.sid = r->in.dom_sid;
1413 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1414 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1415 if (!open.out.trustdom_handle) {
1416 return NT_STATUS_NO_MEMORY;
1418 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1419 if (!NT_STATUS_IS_OK(status)) {
1423 /* Ensure this handle goes away at the end of this call */
1424 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1425 talloc_steal(mem_ctx, h);
1427 query.in.trustdom_handle = open.out.trustdom_handle;
1428 query.in.level = r->in.level;
1429 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1430 if (!NT_STATUS_IS_OK(status)) {
1434 r->out.info = query.out.info;
1435 return NT_STATUS_OK;
1439 lsa_SetTrustedDomainInfoByName
1441 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1442 TALLOC_CTX *mem_ctx,
1443 struct lsa_SetTrustedDomainInfoByName *r)
1445 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1449 lsa_QueryTrustedDomainInfoByName
1451 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1452 TALLOC_CTX *mem_ctx,
1453 struct lsa_QueryTrustedDomainInfoByName *r)
1456 struct lsa_OpenTrustedDomainByName open;
1457 struct lsa_QueryTrustedDomainInfo query;
1458 struct dcesrv_handle *h;
1459 open.in.handle = r->in.handle;
1460 open.in.name = r->in.trusted_domain;
1461 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1462 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1463 if (!open.out.trustdom_handle) {
1464 return NT_STATUS_NO_MEMORY;
1466 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1467 if (!NT_STATUS_IS_OK(status)) {
1471 /* Ensure this handle goes away at the end of this call */
1472 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1473 talloc_steal(mem_ctx, h);
1475 query.in.trustdom_handle = open.out.trustdom_handle;
1476 query.in.level = r->in.level;
1477 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1478 if (!NT_STATUS_IS_OK(status)) {
1482 r->out.info = query.out.info;
1483 return NT_STATUS_OK;
1487 lsa_CloseTrustedDomainEx
1489 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1490 TALLOC_CTX *mem_ctx,
1491 struct lsa_CloseTrustedDomainEx *r)
1493 /* The result of a bad hair day from an IDL programmer? Not
1494 * implmented in Win2k3. You should always just lsa_Close
1496 return NT_STATUS_NOT_IMPLEMENTED;
1501 comparison function for sorting lsa_DomainInformation array
1503 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1505 return strcasecmp_m(e1->name.string, e2->name.string);
1511 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1512 struct lsa_EnumTrustDom *r)
1514 struct dcesrv_handle *policy_handle;
1515 struct lsa_DomainInfo *entries;
1516 struct lsa_policy_state *policy_state;
1517 struct ldb_message **domains;
1518 const char *attrs[] = {
1520 "securityIdentifier",
1527 *r->out.resume_handle = 0;
1529 r->out.domains->domains = NULL;
1530 r->out.domains->count = 0;
1532 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1534 policy_state = policy_handle->data;
1536 /* search for all users in this domain. This could possibly be cached and
1537 resumed based on resume_key */
1538 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1539 "objectclass=trustedDomain");
1541 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1544 /* convert to lsa_TrustInformation format */
1545 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1547 return NT_STATUS_NO_MEMORY;
1549 for (i=0;i<count;i++) {
1550 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1551 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1554 /* sort the results by name */
1555 qsort(entries, count, sizeof(*entries),
1556 (comparison_fn_t)compare_DomainInfo);
1558 if (*r->in.resume_handle >= count) {
1559 *r->out.resume_handle = -1;
1561 return NT_STATUS_NO_MORE_ENTRIES;
1564 /* return the rest, limit by max_size. Note that we
1565 use the w2k3 element size value of 60 */
1566 r->out.domains->count = count - *r->in.resume_handle;
1567 r->out.domains->count = MIN(r->out.domains->count,
1568 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1570 r->out.domains->domains = entries + *r->in.resume_handle;
1571 r->out.domains->count = r->out.domains->count;
1573 if (r->out.domains->count < count - *r->in.resume_handle) {
1574 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1575 return STATUS_MORE_ENTRIES;
1578 return NT_STATUS_OK;
1582 comparison function for sorting lsa_DomainInformation array
1584 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1586 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1590 lsa_EnumTrustedDomainsEx
1592 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1593 struct lsa_EnumTrustedDomainsEx *r)
1595 struct dcesrv_handle *policy_handle;
1596 struct lsa_TrustDomainInfoInfoEx *entries;
1597 struct lsa_policy_state *policy_state;
1598 struct ldb_message **domains;
1599 const char *attrs[] = {
1602 "securityIdentifier",
1612 *r->out.resume_handle = 0;
1614 r->out.domains->domains = NULL;
1615 r->out.domains->count = 0;
1617 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1619 policy_state = policy_handle->data;
1621 /* search for all users in this domain. This could possibly be cached and
1622 resumed based on resume_key */
1623 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1624 "objectclass=trustedDomain");
1626 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1629 /* convert to lsa_DomainInformation format */
1630 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1632 return NT_STATUS_NO_MEMORY;
1634 for (i=0;i<count;i++) {
1635 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1636 if (!NT_STATUS_IS_OK(nt_status)) {
1641 /* sort the results by name */
1642 qsort(entries, count, sizeof(*entries),
1643 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1645 if (*r->in.resume_handle >= count) {
1646 *r->out.resume_handle = -1;
1648 return NT_STATUS_NO_MORE_ENTRIES;
1651 /* return the rest, limit by max_size. Note that we
1652 use the w2k3 element size value of 60 */
1653 r->out.domains->count = count - *r->in.resume_handle;
1654 r->out.domains->count = MIN(r->out.domains->count,
1655 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1657 r->out.domains->domains = entries + *r->in.resume_handle;
1658 r->out.domains->count = r->out.domains->count;
1660 if (r->out.domains->count < count - *r->in.resume_handle) {
1661 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1662 return STATUS_MORE_ENTRIES;
1665 return NT_STATUS_OK;
1672 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1673 struct lsa_OpenAccount *r)
1675 struct dcesrv_handle *h, *ah;
1676 struct lsa_policy_state *state;
1677 struct lsa_account_state *astate;
1679 ZERO_STRUCTP(r->out.acct_handle);
1681 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1685 astate = talloc(dce_call->conn, struct lsa_account_state);
1686 if (astate == NULL) {
1687 return NT_STATUS_NO_MEMORY;
1690 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1691 if (astate->account_sid == NULL) {
1692 talloc_free(astate);
1693 return NT_STATUS_NO_MEMORY;
1696 astate->policy = talloc_reference(astate, state);
1697 astate->access_mask = r->in.access_mask;
1699 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1701 talloc_free(astate);
1702 return NT_STATUS_NO_MEMORY;
1705 ah->data = talloc_steal(ah, astate);
1707 *r->out.acct_handle = ah->wire_handle;
1709 return NT_STATUS_OK;
1714 lsa_EnumPrivsAccount
1716 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1717 TALLOC_CTX *mem_ctx,
1718 struct lsa_EnumPrivsAccount *r)
1720 struct dcesrv_handle *h;
1721 struct lsa_account_state *astate;
1723 struct ldb_message **res;
1724 const char * const attrs[] = { "privilege", NULL};
1725 struct ldb_message_element *el;
1728 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1732 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1733 r->out.privs->count = 0;
1734 r->out.privs->unknown = 0;
1735 r->out.privs->set = NULL;
1737 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1738 if (sidstr == NULL) {
1739 return NT_STATUS_NO_MEMORY;
1742 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1743 "objectSid=%s", sidstr);
1745 return NT_STATUS_OK;
1748 el = ldb_msg_find_element(res[0], "privilege");
1749 if (el == NULL || el->num_values == 0) {
1750 return NT_STATUS_OK;
1753 r->out.privs->set = talloc_array(r->out.privs,
1754 struct lsa_LUIDAttribute, el->num_values);
1755 if (r->out.privs->set == NULL) {
1756 return NT_STATUS_NO_MEMORY;
1759 for (i=0;i<el->num_values;i++) {
1760 int id = sec_privilege_id((const char *)el->values[i].data);
1762 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1764 r->out.privs->set[i].attribute = 0;
1765 r->out.privs->set[i].luid.low = id;
1766 r->out.privs->set[i].luid.high = 0;
1769 r->out.privs->count = el->num_values;
1771 return NT_STATUS_OK;
1775 lsa_EnumAccountRights
1777 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1778 TALLOC_CTX *mem_ctx,
1779 struct lsa_EnumAccountRights *r)
1781 struct dcesrv_handle *h;
1782 struct lsa_policy_state *state;
1784 struct ldb_message **res;
1785 const char * const attrs[] = { "privilege", NULL};
1787 struct ldb_message_element *el;
1789 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1793 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1794 if (sidstr == NULL) {
1795 return NT_STATUS_NO_MEMORY;
1798 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1799 "(&(objectSid=%s)(privilege=*))", sidstr);
1801 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1804 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1807 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1808 dom_sid_string(mem_ctx, r->in.sid),
1809 ldb_errstring(state->sam_ldb)));
1810 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1813 el = ldb_msg_find_element(res[0], "privilege");
1814 if (el == NULL || el->num_values == 0) {
1815 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1818 r->out.rights->count = el->num_values;
1819 r->out.rights->names = talloc_array(r->out.rights,
1820 struct lsa_StringLarge, r->out.rights->count);
1821 if (r->out.rights->names == NULL) {
1822 return NT_STATUS_NO_MEMORY;
1825 for (i=0;i<el->num_values;i++) {
1826 r->out.rights->names[i].string = (const char *)el->values[i].data;
1829 return NT_STATUS_OK;
1835 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1837 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1838 TALLOC_CTX *mem_ctx,
1839 struct lsa_policy_state *state,
1841 struct dom_sid *sid,
1842 const struct lsa_RightSet *rights)
1845 struct ldb_message *msg;
1846 struct ldb_message_element *el;
1848 struct lsa_EnumAccountRights r2;
1850 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1851 if (sidstr == NULL) {
1852 return NT_STATUS_NO_MEMORY;
1855 msg = ldb_msg_new(mem_ctx);
1857 return NT_STATUS_NO_MEMORY;
1860 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1861 NULL, "objectSid=%s", sidstr);
1862 if (msg->dn == NULL) {
1864 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1865 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1867 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1869 if (!NT_STATUS_IS_OK(status)) {
1872 return NT_STATUS_NO_SUCH_USER;
1875 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1876 return NT_STATUS_NO_MEMORY;
1879 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1882 r2.in.handle = &state->handle->wire_handle;
1884 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1886 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1887 if (!NT_STATUS_IS_OK(status)) {
1888 ZERO_STRUCTP(r2.out.rights);
1892 for (i=0;i<rights->count;i++) {
1893 if (sec_privilege_id(rights->names[i].string) == -1) {
1894 return NT_STATUS_NO_SUCH_PRIVILEGE;
1897 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1899 for (j=0;j<r2.out.rights->count;j++) {
1900 if (strcasecmp_m(r2.out.rights->names[j].string,
1901 rights->names[i].string) == 0) {
1905 if (j != r2.out.rights->count) continue;
1908 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1909 if (ret != LDB_SUCCESS) {
1910 return NT_STATUS_NO_MEMORY;
1914 el = ldb_msg_find_element(msg, "privilege");
1916 return NT_STATUS_OK;
1919 ret = ldb_modify(state->sam_ldb, msg);
1921 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1922 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1924 DEBUG(3, ("Could not %s attributes from %s: %s",
1925 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1926 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1927 return NT_STATUS_UNEXPECTED_IO_ERROR;
1930 return NT_STATUS_OK;
1934 lsa_AddPrivilegesToAccount
1936 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1937 struct lsa_AddPrivilegesToAccount *r)
1939 struct lsa_RightSet rights;
1940 struct dcesrv_handle *h;
1941 struct lsa_account_state *astate;
1944 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1948 rights.count = r->in.privs->count;
1949 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1950 if (rights.names == NULL) {
1951 return NT_STATUS_NO_MEMORY;
1953 for (i=0;i<rights.count;i++) {
1954 int id = r->in.privs->set[i].luid.low;
1955 if (r->in.privs->set[i].luid.high) {
1956 return NT_STATUS_NO_SUCH_PRIVILEGE;
1958 rights.names[i].string = sec_privilege_name(id);
1959 if (rights.names[i].string == NULL) {
1960 return NT_STATUS_NO_SUCH_PRIVILEGE;
1964 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1965 LDB_FLAG_MOD_ADD, astate->account_sid,
1971 lsa_RemovePrivilegesFromAccount
1973 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1974 struct lsa_RemovePrivilegesFromAccount *r)
1976 struct lsa_RightSet *rights;
1977 struct dcesrv_handle *h;
1978 struct lsa_account_state *astate;
1981 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1985 rights = talloc(mem_ctx, struct lsa_RightSet);
1987 if (r->in.remove_all == 1 &&
1988 r->in.privs == NULL) {
1989 struct lsa_EnumAccountRights r2;
1992 r2.in.handle = &astate->policy->handle->wire_handle;
1993 r2.in.sid = astate->account_sid;
1994 r2.out.rights = rights;
1996 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1997 if (!NT_STATUS_IS_OK(status)) {
2001 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2002 LDB_FLAG_MOD_DELETE, astate->account_sid,
2006 if (r->in.remove_all != 0) {
2007 return NT_STATUS_INVALID_PARAMETER;
2010 rights->count = r->in.privs->count;
2011 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2012 if (rights->names == NULL) {
2013 return NT_STATUS_NO_MEMORY;
2015 for (i=0;i<rights->count;i++) {
2016 int id = r->in.privs->set[i].luid.low;
2017 if (r->in.privs->set[i].luid.high) {
2018 return NT_STATUS_NO_SUCH_PRIVILEGE;
2020 rights->names[i].string = sec_privilege_name(id);
2021 if (rights->names[i].string == NULL) {
2022 return NT_STATUS_NO_SUCH_PRIVILEGE;
2026 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2027 LDB_FLAG_MOD_DELETE, astate->account_sid,
2033 lsa_GetQuotasForAccount
2035 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2036 struct lsa_GetQuotasForAccount *r)
2038 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2043 lsa_SetQuotasForAccount
2045 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2046 struct lsa_SetQuotasForAccount *r)
2048 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2053 lsa_GetSystemAccessAccount
2055 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2056 struct lsa_GetSystemAccessAccount *r)
2058 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2063 lsa_SetSystemAccessAccount
2065 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2066 struct lsa_SetSystemAccessAccount *r)
2068 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2075 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2076 struct lsa_CreateSecret *r)
2078 struct dcesrv_handle *policy_handle;
2079 struct lsa_policy_state *policy_state;
2080 struct lsa_secret_state *secret_state;
2081 struct dcesrv_handle *handle;
2082 struct ldb_message **msgs, *msg;
2084 const char *attrs[] = {
2092 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2093 ZERO_STRUCTP(r->out.sec_handle);
2095 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2097 case SECURITY_SYSTEM:
2098 case SECURITY_ADMINISTRATOR:
2101 /* Users and annonymous are not allowed create secrets */
2102 return NT_STATUS_ACCESS_DENIED;
2105 policy_state = policy_handle->data;
2107 if (!r->in.name.string) {
2108 return NT_STATUS_INVALID_PARAMETER;
2111 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2112 if (!secret_state) {
2113 return NT_STATUS_NO_MEMORY;
2115 secret_state->policy = policy_state;
2117 msg = ldb_msg_new(mem_ctx);
2119 return NT_STATUS_NO_MEMORY;
2122 if (strncmp("G$", r->in.name.string, 2) == 0) {
2124 name = &r->in.name.string[2];
2125 /* 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) */
2126 secret_state->sam_ldb = talloc_reference(secret_state,
2127 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)));
2128 secret_state->global = true;
2130 if (strlen(name) < 1) {
2131 return NT_STATUS_INVALID_PARAMETER;
2134 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2135 /* search for the secret record */
2136 ret = gendb_search(secret_state->sam_ldb,
2137 mem_ctx, policy_state->system_dn, &msgs, attrs,
2138 "(&(cn=%s)(objectclass=secret))",
2141 return NT_STATUS_OBJECT_NAME_COLLISION;
2145 DEBUG(0,("Failure searching for CN=%s: %s\n",
2146 name2, ldb_errstring(secret_state->sam_ldb)));
2147 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2150 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2151 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2152 return NT_STATUS_NO_MEMORY;
2155 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2158 secret_state->global = false;
2160 name = r->in.name.string;
2161 if (strlen(name) < 1) {
2162 return NT_STATUS_INVALID_PARAMETER;
2165 secret_state->sam_ldb = talloc_reference(secret_state,
2166 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2167 /* search for the secret record */
2168 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2169 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2171 "(&(cn=%s)(objectclass=secret))",
2172 ldb_binary_encode_string(mem_ctx, name));
2174 return NT_STATUS_OBJECT_NAME_COLLISION;
2178 DEBUG(0,("Failure searching for CN=%s: %s\n",
2179 name, ldb_errstring(secret_state->sam_ldb)));
2180 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2183 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2184 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2187 /* pull in all the template attributes. Note this is always from the global samdb */
2188 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
2191 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2193 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2196 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2198 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2200 /* create the secret */
2201 ret = ldb_add(secret_state->sam_ldb, msg);
2203 DEBUG(0,("Failed to create secret record %s: %s\n",
2204 ldb_dn_get_linearized(msg->dn),
2205 ldb_errstring(secret_state->sam_ldb)));
2206 return NT_STATUS_ACCESS_DENIED;
2209 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2211 return NT_STATUS_NO_MEMORY;
2214 handle->data = talloc_steal(handle, secret_state);
2216 secret_state->access_mask = r->in.access_mask;
2217 secret_state->policy = talloc_reference(secret_state, policy_state);
2219 *r->out.sec_handle = handle->wire_handle;
2221 return NT_STATUS_OK;
2228 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2229 struct lsa_OpenSecret *r)
2231 struct dcesrv_handle *policy_handle;
2233 struct lsa_policy_state *policy_state;
2234 struct lsa_secret_state *secret_state;
2235 struct dcesrv_handle *handle;
2236 struct ldb_message **msgs;
2237 const char *attrs[] = {
2245 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2246 ZERO_STRUCTP(r->out.sec_handle);
2247 policy_state = policy_handle->data;
2249 if (!r->in.name.string) {
2250 return NT_STATUS_INVALID_PARAMETER;
2253 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2255 case SECURITY_SYSTEM:
2256 case SECURITY_ADMINISTRATOR:
2259 /* Users and annonymous are not allowed to access secrets */
2260 return NT_STATUS_ACCESS_DENIED;
2263 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2264 if (!secret_state) {
2265 return NT_STATUS_NO_MEMORY;
2267 secret_state->policy = policy_state;
2269 if (strncmp("G$", r->in.name.string, 2) == 0) {
2270 name = &r->in.name.string[2];
2271 /* 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) */
2272 secret_state->sam_ldb = talloc_reference(secret_state,
2273 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)));
2274 secret_state->global = true;
2276 if (strlen(name) < 1) {
2277 return NT_STATUS_INVALID_PARAMETER;
2280 /* search for the secret record */
2281 ret = gendb_search(secret_state->sam_ldb,
2282 mem_ctx, policy_state->system_dn, &msgs, attrs,
2283 "(&(cn=%s Secret)(objectclass=secret))",
2284 ldb_binary_encode_string(mem_ctx, name));
2286 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2290 DEBUG(0,("Found %d records matching DN %s\n", ret,
2291 ldb_dn_get_linearized(policy_state->system_dn)));
2292 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2296 secret_state->global = false;
2297 secret_state->sam_ldb = talloc_reference(secret_state,
2298 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2300 name = r->in.name.string;
2301 if (strlen(name) < 1) {
2302 return NT_STATUS_INVALID_PARAMETER;
2305 /* search for the secret record */
2306 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2307 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2309 "(&(cn=%s)(objectclass=secret))",
2310 ldb_binary_encode_string(mem_ctx, name));
2312 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2316 DEBUG(0,("Found %d records matching CN=%s\n",
2317 ret, ldb_binary_encode_string(mem_ctx, name)));
2318 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2322 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2324 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2326 return NT_STATUS_NO_MEMORY;
2329 handle->data = talloc_steal(handle, secret_state);
2331 secret_state->access_mask = r->in.access_mask;
2332 secret_state->policy = talloc_reference(secret_state, policy_state);
2334 *r->out.sec_handle = handle->wire_handle;
2336 return NT_STATUS_OK;
2343 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2344 struct lsa_SetSecret *r)
2347 struct dcesrv_handle *h;
2348 struct lsa_secret_state *secret_state;
2349 struct ldb_message *msg;
2350 DATA_BLOB session_key;
2351 DATA_BLOB crypt_secret, secret;
2354 NTSTATUS status = NT_STATUS_OK;
2356 struct timeval now = timeval_current();
2357 NTTIME nt_now = timeval_to_nttime(&now);
2359 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2361 secret_state = h->data;
2363 msg = ldb_msg_new(mem_ctx);
2365 return NT_STATUS_NO_MEMORY;
2368 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2370 return NT_STATUS_NO_MEMORY;
2372 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2373 if (!NT_STATUS_IS_OK(status)) {
2377 if (r->in.old_val) {
2379 crypt_secret.data = r->in.old_val->data;
2380 crypt_secret.length = r->in.old_val->size;
2382 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2383 if (!NT_STATUS_IS_OK(status)) {
2387 val.data = secret.data;
2388 val.length = secret.length;
2391 if (samdb_msg_add_value(secret_state->sam_ldb,
2392 mem_ctx, msg, "priorValue", &val) != 0) {
2393 return NT_STATUS_NO_MEMORY;
2396 /* set old value mtime */
2397 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2398 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2399 return NT_STATUS_NO_MEMORY;
2403 /* If the old value is not set, then migrate the
2404 * current value to the old value */
2405 const struct ldb_val *old_val;
2406 NTTIME last_set_time;
2407 struct ldb_message **res;
2408 const char *attrs[] = {
2414 /* search for the secret record */
2415 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2416 secret_state->secret_dn, &res, attrs);
2418 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2422 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2423 ldb_dn_get_linearized(secret_state->secret_dn)));
2424 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2427 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2428 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2432 if (samdb_msg_add_value(secret_state->sam_ldb,
2433 mem_ctx, msg, "priorValue",
2435 return NT_STATUS_NO_MEMORY;
2438 if (samdb_msg_add_delete(secret_state->sam_ldb,
2439 mem_ctx, msg, "priorValue")) {
2440 return NT_STATUS_NO_MEMORY;
2445 /* set old value mtime */
2446 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2447 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2448 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2449 return NT_STATUS_NO_MEMORY;
2452 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2453 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2454 return NT_STATUS_NO_MEMORY;
2459 if (r->in.new_val) {
2461 crypt_secret.data = r->in.new_val->data;
2462 crypt_secret.length = r->in.new_val->size;
2464 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2465 if (!NT_STATUS_IS_OK(status)) {
2469 val.data = secret.data;
2470 val.length = secret.length;
2473 if (samdb_msg_add_value(secret_state->sam_ldb,
2474 mem_ctx, msg, "currentValue", &val) != 0) {
2475 return NT_STATUS_NO_MEMORY;
2478 /* set new value mtime */
2479 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2480 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2481 return NT_STATUS_NO_MEMORY;
2485 /* NULL out the NEW value */
2486 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2487 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2488 return NT_STATUS_NO_MEMORY;
2490 if (samdb_msg_add_delete(secret_state->sam_ldb,
2491 mem_ctx, msg, "currentValue")) {
2492 return NT_STATUS_NO_MEMORY;
2496 /* modify the samdb record */
2497 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2499 /* we really need samdb.c to return NTSTATUS */
2500 return NT_STATUS_UNSUCCESSFUL;
2503 return NT_STATUS_OK;
2510 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2511 struct lsa_QuerySecret *r)
2513 struct dcesrv_handle *h;
2514 struct lsa_secret_state *secret_state;
2515 struct ldb_message *msg;
2516 DATA_BLOB session_key;
2517 DATA_BLOB crypt_secret, secret;
2519 struct ldb_message **res;
2520 const char *attrs[] = {
2530 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2532 /* Ensure user is permitted to read this... */
2533 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2535 case SECURITY_SYSTEM:
2536 case SECURITY_ADMINISTRATOR:
2539 /* Users and annonymous are not allowed to read secrets */
2540 return NT_STATUS_ACCESS_DENIED;
2543 secret_state = h->data;
2545 /* pull all the user attributes */
2546 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2547 secret_state->secret_dn, &res, attrs);
2549 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2553 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2554 if (!NT_STATUS_IS_OK(nt_status)) {
2558 if (r->in.old_val) {
2559 const struct ldb_val *prior_val;
2560 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2561 if (!r->out.old_val) {
2562 return NT_STATUS_NO_MEMORY;
2564 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2566 if (prior_val && prior_val->length) {
2567 secret.data = prior_val->data;
2568 secret.length = prior_val->length;
2571 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2572 if (!crypt_secret.length) {
2573 return NT_STATUS_NO_MEMORY;
2575 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2576 if (!r->out.old_val->buf) {
2577 return NT_STATUS_NO_MEMORY;
2579 r->out.old_val->buf->size = crypt_secret.length;
2580 r->out.old_val->buf->length = crypt_secret.length;
2581 r->out.old_val->buf->data = crypt_secret.data;
2585 if (r->in.old_mtime) {
2586 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2587 if (!r->out.old_mtime) {
2588 return NT_STATUS_NO_MEMORY;
2590 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2593 if (r->in.new_val) {
2594 const struct ldb_val *new_val;
2595 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2596 if (!r->out.new_val) {
2597 return NT_STATUS_NO_MEMORY;
2600 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2602 if (new_val && new_val->length) {
2603 secret.data = new_val->data;
2604 secret.length = new_val->length;
2607 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2608 if (!crypt_secret.length) {
2609 return NT_STATUS_NO_MEMORY;
2611 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2612 if (!r->out.new_val->buf) {
2613 return NT_STATUS_NO_MEMORY;
2615 r->out.new_val->buf->length = crypt_secret.length;
2616 r->out.new_val->buf->size = crypt_secret.length;
2617 r->out.new_val->buf->data = crypt_secret.data;
2621 if (r->in.new_mtime) {
2622 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2623 if (!r->out.new_mtime) {
2624 return NT_STATUS_NO_MEMORY;
2626 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2629 return NT_STATUS_OK;
2636 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2637 TALLOC_CTX *mem_ctx,
2638 struct lsa_LookupPrivValue *r)
2640 struct dcesrv_handle *h;
2641 struct lsa_policy_state *state;
2644 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2648 id = sec_privilege_id(r->in.name->string);
2650 return NT_STATUS_NO_SUCH_PRIVILEGE;
2653 r->out.luid->low = id;
2654 r->out.luid->high = 0;
2656 return NT_STATUS_OK;
2663 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2664 TALLOC_CTX *mem_ctx,
2665 struct lsa_LookupPrivName *r)
2667 struct dcesrv_handle *h;
2668 struct lsa_policy_state *state;
2669 const char *privname;
2671 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2675 if (r->in.luid->high != 0) {
2676 return NT_STATUS_NO_SUCH_PRIVILEGE;
2679 privname = sec_privilege_name(r->in.luid->low);
2680 if (privname == NULL) {
2681 return NT_STATUS_NO_SUCH_PRIVILEGE;
2684 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2685 if (r->out.name == NULL) {
2686 return NT_STATUS_NO_MEMORY;
2688 r->out.name->string = privname;
2690 return NT_STATUS_OK;
2695 lsa_LookupPrivDisplayName
2697 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2698 TALLOC_CTX *mem_ctx,
2699 struct lsa_LookupPrivDisplayName *r)
2701 struct dcesrv_handle *h;
2702 struct lsa_policy_state *state;
2705 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2709 id = sec_privilege_id(r->in.name->string);
2711 return NT_STATUS_NO_SUCH_PRIVILEGE;
2714 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2715 if (r->out.disp_name == NULL) {
2716 return NT_STATUS_NO_MEMORY;
2719 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2720 if (r->out.disp_name->string == NULL) {
2721 return NT_STATUS_INTERNAL_ERROR;
2724 return NT_STATUS_OK;
2729 lsa_EnumAccountsWithUserRight
2731 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2732 TALLOC_CTX *mem_ctx,
2733 struct lsa_EnumAccountsWithUserRight *r)
2735 struct dcesrv_handle *h;
2736 struct lsa_policy_state *state;
2738 struct ldb_message **res;
2739 const char * const attrs[] = { "objectSid", NULL};
2740 const char *privname;
2742 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2746 if (r->in.name == NULL) {
2747 return NT_STATUS_NO_SUCH_PRIVILEGE;
2750 privname = r->in.name->string;
2751 if (sec_privilege_id(privname) == -1) {
2752 return NT_STATUS_NO_SUCH_PRIVILEGE;
2755 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2756 "privilege=%s", privname);
2758 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2761 return NT_STATUS_NO_MORE_ENTRIES;
2764 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2765 if (r->out.sids->sids == NULL) {
2766 return NT_STATUS_NO_MEMORY;
2768 for (i=0;i<ret;i++) {
2769 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2770 res[i], "objectSid");
2771 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2773 r->out.sids->num_sids = ret;
2775 return NT_STATUS_OK;
2780 lsa_AddAccountRights
2782 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2783 TALLOC_CTX *mem_ctx,
2784 struct lsa_AddAccountRights *r)
2786 struct dcesrv_handle *h;
2787 struct lsa_policy_state *state;
2789 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2793 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2795 r->in.sid, r->in.rights);
2800 lsa_RemoveAccountRights
2802 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2803 TALLOC_CTX *mem_ctx,
2804 struct lsa_RemoveAccountRights *r)
2806 struct dcesrv_handle *h;
2807 struct lsa_policy_state *state;
2809 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2813 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2814 LDB_FLAG_MOD_DELETE,
2815 r->in.sid, r->in.rights);
2820 lsa_StorePrivateData
2822 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2823 struct lsa_StorePrivateData *r)
2825 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2830 lsa_RetrievePrivateData
2832 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2833 struct lsa_RetrievePrivateData *r)
2835 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2842 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2843 struct lsa_GetUserName *r)
2845 NTSTATUS status = NT_STATUS_OK;
2846 const char *account_name;
2847 const char *authority_name;
2848 struct lsa_String *_account_name;
2849 struct lsa_StringPointer *_authority_name = NULL;
2851 /* this is what w2k3 does */
2852 r->out.account_name = r->in.account_name;
2853 r->out.authority_name = r->in.authority_name;
2855 if (r->in.account_name && r->in.account_name->string) {
2856 return NT_STATUS_INVALID_PARAMETER;
2859 if (r->in.authority_name &&
2860 r->in.authority_name->string &&
2861 r->in.authority_name->string->string) {
2862 return NT_STATUS_INVALID_PARAMETER;
2865 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2866 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2868 _account_name = talloc(mem_ctx, struct lsa_String);
2869 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2870 _account_name->string = account_name;
2872 if (r->in.authority_name) {
2873 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2874 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2875 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2876 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2877 _authority_name->string->string = authority_name;
2880 r->out.account_name = _account_name;
2881 r->out.authority_name = _authority_name;
2889 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2890 TALLOC_CTX *mem_ctx,
2891 struct lsa_SetInfoPolicy2 *r)
2893 /* need to support these */
2894 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2898 lsa_QueryDomainInformationPolicy
2900 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2901 TALLOC_CTX *mem_ctx,
2902 struct lsa_QueryDomainInformationPolicy *r)
2904 r->out.info = talloc(mem_ctx, union lsa_DomainInformationPolicy);
2906 return NT_STATUS_NO_MEMORY;
2909 switch (r->in.level) {
2910 case LSA_DOMAIN_INFO_POLICY_EFS:
2911 talloc_free(r->out.info);
2913 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2914 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
2916 struct lsa_DomainInfoKerberos *k = &r->out.info->kerberos_info;
2917 struct smb_krb5_context *smb_krb5_context;
2918 int ret = smb_krb5_init_context(mem_ctx,
2919 dce_call->event_ctx,
2920 dce_call->conn->dce_ctx->lp_ctx,
2923 talloc_free(r->out.info);
2925 return NT_STATUS_INTERNAL_ERROR;
2927 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
2928 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2929 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2930 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
2931 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
2932 talloc_free(smb_krb5_context);
2933 return NT_STATUS_OK;
2936 talloc_free(r->out.info);
2938 return NT_STATUS_INVALID_INFO_CLASS;
2943 lsa_SetDomInfoPolicy
2945 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2946 TALLOC_CTX *mem_ctx,
2947 struct lsa_SetDomainInformationPolicy *r)
2949 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2955 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
2956 TALLOC_CTX *mem_ctx,
2957 struct lsa_TestCall *r)
2959 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2965 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2966 struct lsa_CREDRWRITE *r)
2968 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2975 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2976 struct lsa_CREDRREAD *r)
2978 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2985 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2986 struct lsa_CREDRENUMERATE *r)
2988 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2993 lsa_CREDRWRITEDOMAINCREDENTIALS
2995 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2996 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2998 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3003 lsa_CREDRREADDOMAINCREDENTIALS
3005 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3006 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3008 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3015 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3016 struct lsa_CREDRDELETE *r)
3018 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3023 lsa_CREDRGETTARGETINFO
3025 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3026 struct lsa_CREDRGETTARGETINFO *r)
3028 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3033 lsa_CREDRPROFILELOADED
3035 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3036 struct lsa_CREDRPROFILELOADED *r)
3038 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3043 lsa_CREDRGETSESSIONTYPES
3045 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3046 struct lsa_CREDRGETSESSIONTYPES *r)
3048 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3053 lsa_LSARREGISTERAUDITEVENT
3055 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3056 struct lsa_LSARREGISTERAUDITEVENT *r)
3058 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3063 lsa_LSARGENAUDITEVENT
3065 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3066 struct lsa_LSARGENAUDITEVENT *r)
3068 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3073 lsa_LSARUNREGISTERAUDITEVENT
3075 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3076 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3078 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3083 lsa_lsaRQueryForestTrustInformation
3085 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3086 struct lsa_lsaRQueryForestTrustInformation *r)
3088 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3093 lsa_LSARSETFORESTTRUSTINFORMATION
3095 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3096 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3098 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3105 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3106 struct lsa_CREDRRENAME *r)
3108 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3114 lsa_LSAROPENPOLICYSCE
3116 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3117 struct lsa_LSAROPENPOLICYSCE *r)
3119 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3124 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3126 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3127 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3129 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3134 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3136 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3137 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3139 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3144 lsa_LSARADTREPORTSECURITYEVENT
3146 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3147 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3149 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3153 /* include the generated boilerplate */
3154 #include "librpc/gen_ndr/ndr_lsa_s.c"
3158 /*****************************************
3159 NOTE! The remaining calls below were
3160 removed in w2k3, so the DCESRV_FAULT()
3161 replies are the correct implementation. Do
3162 not try and fill these in with anything else
3163 ******************************************/
3166 dssetup_DsRoleDnsNameToFlatName
3168 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3169 struct dssetup_DsRoleDnsNameToFlatName *r)
3171 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3176 dssetup_DsRoleDcAsDc
3178 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3179 struct dssetup_DsRoleDcAsDc *r)
3181 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3186 dssetup_DsRoleDcAsReplica
3188 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3189 struct dssetup_DsRoleDcAsReplica *r)
3191 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3196 dssetup_DsRoleDemoteDc
3198 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3199 struct dssetup_DsRoleDemoteDc *r)
3201 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3206 dssetup_DsRoleGetDcOperationProgress
3208 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3209 struct dssetup_DsRoleGetDcOperationProgress *r)
3211 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3216 dssetup_DsRoleGetDcOperationResults
3218 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3219 struct dssetup_DsRoleGetDcOperationResults *r)
3221 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3226 dssetup_DsRoleCancel
3228 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3229 struct dssetup_DsRoleCancel *r)
3231 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3236 dssetup_DsRoleServerSaveStateForUpgrade
3238 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3239 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3241 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3246 dssetup_DsRoleUpgradeDownlevelServer
3248 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3249 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3251 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3256 dssetup_DsRoleAbortDownlevelServerUpgrade
3258 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3259 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3261 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3265 /* include the generated boilerplate */
3266 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3268 NTSTATUS dcerpc_server_lsa_init(void)
3272 ret = dcerpc_server_dssetup_init();
3273 if (!NT_STATUS_IS_OK(ret)) {
3276 ret = dcerpc_server_lsarpc_init();
3277 if (!NT_STATUS_IS_OK(ret)) {