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;
732 if (auth_struct.incoming.count) {
733 ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx,
734 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
735 &auth_struct.incoming,
736 (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
737 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
738 return NT_STATUS_INVALID_PARAMETER;
741 trustAuthIncoming = data_blob(NULL, 0);
744 if (auth_struct.outgoing.count) {
745 ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx,
746 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
747 &auth_struct.outgoing,
748 (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
749 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
750 return NT_STATUS_INVALID_PARAMETER;
753 trustAuthOutgoing = data_blob(NULL, 0);
756 ret = ldb_transaction_start(policy_state->sam_ldb);
757 if (ret != LDB_SUCCESS) {
758 return NT_STATUS_INTERNAL_DB_CORRUPTION;
762 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
763 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
764 /* search for the trusted_domain record */
765 ret = gendb_search(policy_state->sam_ldb,
766 mem_ctx, policy_state->system_dn, &msgs, attrs,
767 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
768 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
770 ldb_transaction_cancel(policy_state->sam_ldb);
771 return NT_STATUS_OBJECT_NAME_COLLISION;
774 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
775 /* search for the trusted_domain record */
776 ret = gendb_search(policy_state->sam_ldb,
777 mem_ctx, policy_state->system_dn, &msgs, attrs,
778 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
779 netbios_encoded, netbios_encoded, netbios_encoded);
781 ldb_transaction_cancel(policy_state->sam_ldb);
782 return NT_STATUS_OBJECT_NAME_COLLISION;
787 ldb_transaction_cancel(policy_state->sam_ldb);
788 return NT_STATUS_INTERNAL_DB_CORRUPTION;
791 name = dns_name ? dns_name : netbios_name;
793 msg = ldb_msg_new(mem_ctx);
795 return NT_STATUS_NO_MEMORY;
798 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
799 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
800 ldb_transaction_cancel(policy_state->sam_ldb);
801 return NT_STATUS_NO_MEMORY;
804 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", netbios_name);
806 if (r->in.info->sid) {
807 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
809 ldb_transaction_cancel(policy_state->sam_ldb);
810 return NT_STATUS_NO_MEMORY;
813 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
816 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
818 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
820 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
822 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
825 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
828 if (trustAuthIncoming.data) {
829 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
830 if (ret != LDB_SUCCESS) {
831 ldb_transaction_cancel(policy_state->sam_ldb);
832 return NT_STATUS_NO_MEMORY;
835 if (trustAuthOutgoing.data) {
836 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
837 if (ret != LDB_SUCCESS) {
838 ldb_transaction_cancel(policy_state->sam_ldb);
839 return NT_STATUS_NO_MEMORY;
843 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
845 /* create the trusted_domain */
846 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
850 case LDB_ERR_ENTRY_ALREADY_EXISTS:
851 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
852 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
853 ldb_dn_get_linearized(msg->dn),
854 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
855 return NT_STATUS_DOMAIN_EXISTS;
856 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
857 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
858 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
859 ldb_dn_get_linearized(msg->dn),
860 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
861 return NT_STATUS_ACCESS_DENIED;
863 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
864 DEBUG(0,("Failed to create user record %s: %s\n",
865 ldb_dn_get_linearized(msg->dn),
866 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
867 return NT_STATUS_INTERNAL_DB_CORRUPTION;
870 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
871 msg_user = ldb_msg_new(mem_ctx);
873 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
874 return NT_STATUS_NO_MEMORY;
877 /* Inbound trusts must also create a cn=users object to match */
879 trusted_domain_state->trusted_domain_user_dn = msg_user->dn
880 = ldb_dn_copy(trusted_domain_state, policy_state->domain_dn);
881 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=users")) {
882 ldb_transaction_cancel(policy_state->sam_ldb);
883 return NT_STATUS_NO_MEMORY;
886 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=%s", netbios_name)) {
887 ldb_transaction_cancel(policy_state->sam_ldb);
888 return NT_STATUS_NO_MEMORY;
891 ldb_msg_add_string(msg_user, "objectClass", "user");
893 ldb_msg_add_steal_string(msg_user, "samAccountName",
894 talloc_asprintf(mem_ctx, "%s$", netbios_name));
896 if (samdb_msg_add_uint(trusted_domain_state->policy->sam_ldb, mem_ctx, msg_user,
897 "userAccountControl",
898 UF_INTERDOMAIN_TRUST_ACCOUNT) != 0) {
899 ldb_transaction_cancel(policy_state->sam_ldb);
900 return NT_STATUS_NO_MEMORY;
903 if (auth_struct.incoming.count) {
905 for (i=0; i < auth_struct.incoming.count; i++ ) {
906 if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_NT4OWF) {
907 samdb_msg_add_hash(trusted_domain_state->policy->sam_ldb,
908 mem_ctx, msg_user, "unicodePwd",
909 &auth_struct.incoming.current[i]->AuthInfo.nt4owf.password);
910 } else if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_CLEAR) {
911 struct samr_Password hash;
913 . We cannot do this, as windows chooses to send in random passwords here, that won't convert to UTF8
914 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb,
915 mem_ctx, msg_user, "userPassword",
916 auth_struct.incoming.current->array[i].AuthInfo.clear.password);
918 mdfour(hash.hash, auth_struct.incoming.current[i]->AuthInfo.clear.password,
919 auth_struct.incoming.current[i]->AuthInfo.clear.size);
920 samdb_msg_add_hash(trusted_domain_state->policy->sam_ldb,
921 mem_ctx, msg_user, "unicodePwd",
927 /* create the cn=users trusted_domain account */
928 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg_user);
932 case LDB_ERR_ENTRY_ALREADY_EXISTS:
933 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
934 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
935 ldb_dn_get_linearized(msg_user->dn),
936 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
937 return NT_STATUS_DOMAIN_EXISTS;
938 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
939 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
940 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
941 ldb_dn_get_linearized(msg_user->dn),
942 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
943 return NT_STATUS_ACCESS_DENIED;
945 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
946 DEBUG(0,("Failed to create user record %s: %s\n",
947 ldb_dn_get_linearized(msg_user->dn),
948 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
949 return NT_STATUS_INTERNAL_DB_CORRUPTION;
953 ret = ldb_transaction_commit(policy_state->sam_ldb);
954 if (ret != LDB_SUCCESS) {
955 return NT_STATUS_INTERNAL_DB_CORRUPTION;
958 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
960 return NT_STATUS_NO_MEMORY;
963 handle->data = talloc_steal(handle, trusted_domain_state);
965 trusted_domain_state->access_mask = r->in.access_mask;
966 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
968 *r->out.trustdom_handle = handle->wire_handle;
974 lsa_CreateTrustedDomainEx2
976 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
978 struct lsa_CreateTrustedDomainEx2 *r)
980 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
983 lsa_CreateTrustedDomainEx
985 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
987 struct lsa_CreateTrustedDomainEx *r)
989 struct lsa_CreateTrustedDomainEx2 r2;
991 r2.in.policy_handle = r->in.policy_handle;
992 r2.in.info = r->in.info;
993 r2.in.auth_info = r->in.auth_info;
994 r2.out.trustdom_handle = r->out.trustdom_handle;
995 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
999 lsa_CreateTrustedDomain
1001 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1002 struct lsa_CreateTrustedDomain *r)
1004 struct lsa_CreateTrustedDomainEx2 r2;
1006 r2.in.policy_handle = r->in.policy_handle;
1007 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1009 return NT_STATUS_NO_MEMORY;
1012 r2.in.info->domain_name.string = NULL;
1013 r2.in.info->netbios_name = r->in.info->name;
1014 r2.in.info->sid = r->in.info->sid;
1015 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1016 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1017 r2.in.info->trust_attributes = 0;
1019 r2.in.access_mask = r->in.access_mask;
1020 r2.out.trustdom_handle = r->out.trustdom_handle;
1022 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1027 lsa_OpenTrustedDomain
1029 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1030 struct lsa_OpenTrustedDomain *r)
1032 struct dcesrv_handle *policy_handle;
1034 struct lsa_policy_state *policy_state;
1035 struct lsa_trusted_domain_state *trusted_domain_state;
1036 struct dcesrv_handle *handle;
1037 struct ldb_message **msgs;
1038 const char *attrs[] = {
1044 const char *sid_string;
1047 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1048 ZERO_STRUCTP(r->out.trustdom_handle);
1049 policy_state = policy_handle->data;
1051 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1052 if (!trusted_domain_state) {
1053 return NT_STATUS_NO_MEMORY;
1055 trusted_domain_state->policy = policy_state;
1057 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1059 return NT_STATUS_NO_MEMORY;
1062 /* search for the trusted_domain record */
1063 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1064 mem_ctx, policy_state->system_dn, &msgs, attrs,
1065 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
1068 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1072 DEBUG(0,("Found %d records matching DN %s\n", ret,
1073 ldb_dn_get_linearized(policy_state->system_dn)));
1074 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1077 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1079 trusted_domain_state->trusted_domain_user_dn = NULL;
1081 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1082 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1083 /* search for the trusted_domain record */
1084 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1085 mem_ctx, policy_state->domain_dn, &msgs, attrs,
1086 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%d))",
1087 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1089 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1092 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1094 return NT_STATUS_NO_MEMORY;
1097 handle->data = talloc_steal(handle, trusted_domain_state);
1099 trusted_domain_state->access_mask = r->in.access_mask;
1100 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1102 *r->out.trustdom_handle = handle->wire_handle;
1104 return NT_STATUS_OK;
1109 lsa_OpenTrustedDomainByName
1111 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1112 TALLOC_CTX *mem_ctx,
1113 struct lsa_OpenTrustedDomainByName *r)
1115 struct dcesrv_handle *policy_handle;
1117 struct lsa_policy_state *policy_state;
1118 struct lsa_trusted_domain_state *trusted_domain_state;
1119 struct dcesrv_handle *handle;
1120 struct ldb_message **msgs;
1121 const char *attrs[] = {
1127 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1128 ZERO_STRUCTP(r->out.trustdom_handle);
1129 policy_state = policy_handle->data;
1131 if (!r->in.name.string) {
1132 return NT_STATUS_INVALID_PARAMETER;
1135 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1136 if (!trusted_domain_state) {
1137 return NT_STATUS_NO_MEMORY;
1139 trusted_domain_state->policy = policy_state;
1141 /* search for the trusted_domain record */
1142 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1143 mem_ctx, policy_state->system_dn, &msgs, attrs,
1144 "(&(flatname=%s)(objectclass=trustedDomain))",
1145 ldb_binary_encode_string(mem_ctx, r->in.name.string));
1147 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1151 DEBUG(0,("Found %d records matching DN %s\n", ret,
1152 ldb_dn_get_linearized(policy_state->system_dn)));
1153 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1156 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1158 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1160 return NT_STATUS_NO_MEMORY;
1163 handle->data = talloc_steal(handle, trusted_domain_state);
1165 trusted_domain_state->access_mask = r->in.access_mask;
1166 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1168 *r->out.trustdom_handle = handle->wire_handle;
1170 return NT_STATUS_OK;
1176 lsa_SetTrustedDomainInfo
1178 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1179 struct lsa_SetTrustedDomainInfo *r)
1181 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1187 lsa_SetInfomrationTrustedDomain
1189 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1190 TALLOC_CTX *mem_ctx,
1191 struct lsa_SetInformationTrustedDomain *r)
1193 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1198 lsa_DeleteTrustedDomain
1200 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1201 struct lsa_DeleteTrustedDomain *r)
1204 struct lsa_OpenTrustedDomain open;
1205 struct lsa_DeleteObject delete;
1206 struct dcesrv_handle *h;
1208 open.in.handle = r->in.handle;
1209 open.in.sid = r->in.dom_sid;
1210 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1211 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1212 if (!open.out.trustdom_handle) {
1213 return NT_STATUS_NO_MEMORY;
1215 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1216 if (!NT_STATUS_IS_OK(status)) {
1220 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1221 talloc_steal(mem_ctx, h);
1223 delete.in.handle = open.out.trustdom_handle;
1224 delete.out.handle = open.out.trustdom_handle;
1225 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &delete);
1226 if (!NT_STATUS_IS_OK(status)) {
1229 return NT_STATUS_OK;
1232 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1233 struct ldb_message *msg,
1234 struct lsa_TrustDomainInfoInfoEx *info_ex)
1236 info_ex->domain_name.string
1237 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1238 info_ex->netbios_name.string
1239 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1241 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1242 info_ex->trust_direction
1243 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1245 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1246 info_ex->trust_attributes
1247 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1248 return NT_STATUS_OK;
1252 lsa_QueryTrustedDomainInfo
1254 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1255 struct lsa_QueryTrustedDomainInfo *r)
1257 struct dcesrv_handle *h;
1258 struct lsa_trusted_domain_state *trusted_domain_state;
1259 struct ldb_message *msg;
1261 struct ldb_message **res;
1262 const char *attrs[] = {
1265 "securityIdentifier",
1269 "msDs-supportedEncryptionTypes",
1273 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1275 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1277 /* pull all the user attributes */
1278 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1279 trusted_domain_state->trusted_domain_dn, &res, attrs);
1281 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1285 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
1287 return NT_STATUS_NO_MEMORY;
1289 switch (r->in.level) {
1290 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1291 r->out.info->name.netbios_name.string
1292 = samdb_result_string(msg, "flatname", NULL);
1294 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1295 r->out.info->posix_offset.posix_offset
1296 = samdb_result_uint(msg, "posixOffset", 0);
1298 #if 0 /* Win2k3 doesn't implement this */
1299 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1300 r->out.info->info_basic.netbios_name.string
1301 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1302 r->out.info->info_basic.sid
1303 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1306 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1307 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
1309 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1310 ZERO_STRUCT(r->out.info->full_info);
1311 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
1313 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1314 ZERO_STRUCT(r->out.info->full_info2_internal);
1315 r->out.info->full_info2_internal.posix_offset.posix_offset
1316 = samdb_result_uint(msg, "posixOffset", 0);
1317 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info2_internal.info.info_ex);
1319 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
1320 r->out.info->enc_types.enc_types
1321 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
1324 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1325 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1326 /* oops, we don't want to return the info after all */
1327 talloc_free(r->out.info);
1329 return NT_STATUS_INVALID_PARAMETER;
1331 /* oops, we don't want to return the info after all */
1332 talloc_free(r->out.info);
1334 return NT_STATUS_INVALID_INFO_CLASS;
1337 return NT_STATUS_OK;
1342 lsa_QueryTrustedDomainInfoBySid
1344 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1345 struct lsa_QueryTrustedDomainInfoBySid *r)
1348 struct lsa_OpenTrustedDomain open;
1349 struct lsa_QueryTrustedDomainInfo query;
1350 struct dcesrv_handle *h;
1351 open.in.handle = r->in.handle;
1352 open.in.sid = r->in.dom_sid;
1353 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1354 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1355 if (!open.out.trustdom_handle) {
1356 return NT_STATUS_NO_MEMORY;
1358 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1359 if (!NT_STATUS_IS_OK(status)) {
1363 /* Ensure this handle goes away at the end of this call */
1364 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1365 talloc_steal(mem_ctx, h);
1367 query.in.trustdom_handle = open.out.trustdom_handle;
1368 query.in.level = r->in.level;
1369 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1370 if (!NT_STATUS_IS_OK(status)) {
1374 r->out.info = query.out.info;
1375 return NT_STATUS_OK;
1379 lsa_SetTrustedDomainInfoByName
1381 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1382 TALLOC_CTX *mem_ctx,
1383 struct lsa_SetTrustedDomainInfoByName *r)
1385 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1389 lsa_QueryTrustedDomainInfoByName
1391 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1392 TALLOC_CTX *mem_ctx,
1393 struct lsa_QueryTrustedDomainInfoByName *r)
1396 struct lsa_OpenTrustedDomainByName open;
1397 struct lsa_QueryTrustedDomainInfo query;
1398 struct dcesrv_handle *h;
1399 open.in.handle = r->in.handle;
1400 open.in.name = r->in.trusted_domain;
1401 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1402 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1403 if (!open.out.trustdom_handle) {
1404 return NT_STATUS_NO_MEMORY;
1406 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1407 if (!NT_STATUS_IS_OK(status)) {
1411 /* Ensure this handle goes away at the end of this call */
1412 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1413 talloc_steal(mem_ctx, h);
1415 query.in.trustdom_handle = open.out.trustdom_handle;
1416 query.in.level = r->in.level;
1417 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1418 if (!NT_STATUS_IS_OK(status)) {
1422 r->out.info = query.out.info;
1423 return NT_STATUS_OK;
1427 lsa_CloseTrustedDomainEx
1429 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1430 TALLOC_CTX *mem_ctx,
1431 struct lsa_CloseTrustedDomainEx *r)
1433 /* The result of a bad hair day from an IDL programmer? Not
1434 * implmented in Win2k3. You should always just lsa_Close
1436 return NT_STATUS_NOT_IMPLEMENTED;
1441 comparison function for sorting lsa_DomainInformation array
1443 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1445 return strcasecmp_m(e1->name.string, e2->name.string);
1451 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1452 struct lsa_EnumTrustDom *r)
1454 struct dcesrv_handle *policy_handle;
1455 struct lsa_DomainInfo *entries;
1456 struct lsa_policy_state *policy_state;
1457 struct ldb_message **domains;
1458 const char *attrs[] = {
1460 "securityIdentifier",
1467 *r->out.resume_handle = 0;
1469 r->out.domains->domains = NULL;
1470 r->out.domains->count = 0;
1472 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1474 policy_state = policy_handle->data;
1476 /* search for all users in this domain. This could possibly be cached and
1477 resumed based on resume_key */
1478 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1479 "objectclass=trustedDomain");
1481 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1484 /* convert to lsa_TrustInformation format */
1485 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1487 return NT_STATUS_NO_MEMORY;
1489 for (i=0;i<count;i++) {
1490 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1491 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1494 /* sort the results by name */
1495 qsort(entries, count, sizeof(*entries),
1496 (comparison_fn_t)compare_DomainInfo);
1498 if (*r->in.resume_handle >= count) {
1499 *r->out.resume_handle = -1;
1501 return NT_STATUS_NO_MORE_ENTRIES;
1504 /* return the rest, limit by max_size. Note that we
1505 use the w2k3 element size value of 60 */
1506 r->out.domains->count = count - *r->in.resume_handle;
1507 r->out.domains->count = MIN(r->out.domains->count,
1508 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1510 r->out.domains->domains = entries + *r->in.resume_handle;
1511 r->out.domains->count = r->out.domains->count;
1513 if (r->out.domains->count < count - *r->in.resume_handle) {
1514 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1515 return STATUS_MORE_ENTRIES;
1518 return NT_STATUS_OK;
1522 comparison function for sorting lsa_DomainInformation array
1524 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1526 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1530 lsa_EnumTrustedDomainsEx
1532 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1533 struct lsa_EnumTrustedDomainsEx *r)
1535 struct dcesrv_handle *policy_handle;
1536 struct lsa_TrustDomainInfoInfoEx *entries;
1537 struct lsa_policy_state *policy_state;
1538 struct ldb_message **domains;
1539 const char *attrs[] = {
1542 "securityIdentifier",
1552 *r->out.resume_handle = 0;
1554 r->out.domains->domains = NULL;
1555 r->out.domains->count = 0;
1557 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1559 policy_state = policy_handle->data;
1561 /* search for all users in this domain. This could possibly be cached and
1562 resumed based on resume_key */
1563 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1564 "objectclass=trustedDomain");
1566 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1569 /* convert to lsa_DomainInformation format */
1570 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1572 return NT_STATUS_NO_MEMORY;
1574 for (i=0;i<count;i++) {
1575 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1576 if (!NT_STATUS_IS_OK(nt_status)) {
1581 /* sort the results by name */
1582 qsort(entries, count, sizeof(*entries),
1583 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1585 if (*r->in.resume_handle >= count) {
1586 *r->out.resume_handle = -1;
1588 return NT_STATUS_NO_MORE_ENTRIES;
1591 /* return the rest, limit by max_size. Note that we
1592 use the w2k3 element size value of 60 */
1593 r->out.domains->count = count - *r->in.resume_handle;
1594 r->out.domains->count = MIN(r->out.domains->count,
1595 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1597 r->out.domains->domains = entries + *r->in.resume_handle;
1598 r->out.domains->count = r->out.domains->count;
1600 if (r->out.domains->count < count - *r->in.resume_handle) {
1601 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1602 return STATUS_MORE_ENTRIES;
1605 return NT_STATUS_OK;
1612 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1613 struct lsa_OpenAccount *r)
1615 struct dcesrv_handle *h, *ah;
1616 struct lsa_policy_state *state;
1617 struct lsa_account_state *astate;
1619 ZERO_STRUCTP(r->out.acct_handle);
1621 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1625 astate = talloc(dce_call->conn, struct lsa_account_state);
1626 if (astate == NULL) {
1627 return NT_STATUS_NO_MEMORY;
1630 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1631 if (astate->account_sid == NULL) {
1632 talloc_free(astate);
1633 return NT_STATUS_NO_MEMORY;
1636 astate->policy = talloc_reference(astate, state);
1637 astate->access_mask = r->in.access_mask;
1639 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1641 talloc_free(astate);
1642 return NT_STATUS_NO_MEMORY;
1645 ah->data = talloc_steal(ah, astate);
1647 *r->out.acct_handle = ah->wire_handle;
1649 return NT_STATUS_OK;
1654 lsa_EnumPrivsAccount
1656 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1657 TALLOC_CTX *mem_ctx,
1658 struct lsa_EnumPrivsAccount *r)
1660 struct dcesrv_handle *h;
1661 struct lsa_account_state *astate;
1663 struct ldb_message **res;
1664 const char * const attrs[] = { "privilege", NULL};
1665 struct ldb_message_element *el;
1668 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1672 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1673 r->out.privs->count = 0;
1674 r->out.privs->unknown = 0;
1675 r->out.privs->set = NULL;
1677 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1678 if (sidstr == NULL) {
1679 return NT_STATUS_NO_MEMORY;
1682 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1683 "objectSid=%s", sidstr);
1685 return NT_STATUS_OK;
1688 el = ldb_msg_find_element(res[0], "privilege");
1689 if (el == NULL || el->num_values == 0) {
1690 return NT_STATUS_OK;
1693 r->out.privs->set = talloc_array(r->out.privs,
1694 struct lsa_LUIDAttribute, el->num_values);
1695 if (r->out.privs->set == NULL) {
1696 return NT_STATUS_NO_MEMORY;
1699 for (i=0;i<el->num_values;i++) {
1700 int id = sec_privilege_id((const char *)el->values[i].data);
1702 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1704 r->out.privs->set[i].attribute = 0;
1705 r->out.privs->set[i].luid.low = id;
1706 r->out.privs->set[i].luid.high = 0;
1709 r->out.privs->count = el->num_values;
1711 return NT_STATUS_OK;
1715 lsa_EnumAccountRights
1717 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1718 TALLOC_CTX *mem_ctx,
1719 struct lsa_EnumAccountRights *r)
1721 struct dcesrv_handle *h;
1722 struct lsa_policy_state *state;
1724 struct ldb_message **res;
1725 const char * const attrs[] = { "privilege", NULL};
1727 struct ldb_message_element *el;
1729 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1733 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1734 if (sidstr == NULL) {
1735 return NT_STATUS_NO_MEMORY;
1738 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1739 "(&(objectSid=%s)(privilege=*))", sidstr);
1741 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1744 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1747 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1748 dom_sid_string(mem_ctx, r->in.sid),
1749 ldb_errstring(state->sam_ldb)));
1750 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1753 el = ldb_msg_find_element(res[0], "privilege");
1754 if (el == NULL || el->num_values == 0) {
1755 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1758 r->out.rights->count = el->num_values;
1759 r->out.rights->names = talloc_array(r->out.rights,
1760 struct lsa_StringLarge, r->out.rights->count);
1761 if (r->out.rights->names == NULL) {
1762 return NT_STATUS_NO_MEMORY;
1765 for (i=0;i<el->num_values;i++) {
1766 r->out.rights->names[i].string = (const char *)el->values[i].data;
1769 return NT_STATUS_OK;
1775 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1777 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1778 TALLOC_CTX *mem_ctx,
1779 struct lsa_policy_state *state,
1781 struct dom_sid *sid,
1782 const struct lsa_RightSet *rights)
1785 struct ldb_message *msg;
1786 struct ldb_message_element *el;
1788 struct lsa_EnumAccountRights r2;
1790 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1791 if (sidstr == NULL) {
1792 return NT_STATUS_NO_MEMORY;
1795 msg = ldb_msg_new(mem_ctx);
1797 return NT_STATUS_NO_MEMORY;
1800 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1801 NULL, "objectSid=%s", sidstr);
1802 if (msg->dn == NULL) {
1804 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1805 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1807 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1809 if (!NT_STATUS_IS_OK(status)) {
1812 return NT_STATUS_NO_SUCH_USER;
1815 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1816 return NT_STATUS_NO_MEMORY;
1819 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1822 r2.in.handle = &state->handle->wire_handle;
1824 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1826 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1827 if (!NT_STATUS_IS_OK(status)) {
1828 ZERO_STRUCTP(r2.out.rights);
1832 for (i=0;i<rights->count;i++) {
1833 if (sec_privilege_id(rights->names[i].string) == -1) {
1834 return NT_STATUS_NO_SUCH_PRIVILEGE;
1837 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1839 for (j=0;j<r2.out.rights->count;j++) {
1840 if (strcasecmp_m(r2.out.rights->names[j].string,
1841 rights->names[i].string) == 0) {
1845 if (j != r2.out.rights->count) continue;
1848 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1849 if (ret != LDB_SUCCESS) {
1850 return NT_STATUS_NO_MEMORY;
1854 el = ldb_msg_find_element(msg, "privilege");
1856 return NT_STATUS_OK;
1859 ret = ldb_modify(state->sam_ldb, msg);
1861 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1862 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1864 DEBUG(3, ("Could not %s attributes from %s: %s",
1865 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1866 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1867 return NT_STATUS_UNEXPECTED_IO_ERROR;
1870 return NT_STATUS_OK;
1874 lsa_AddPrivilegesToAccount
1876 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1877 struct lsa_AddPrivilegesToAccount *r)
1879 struct lsa_RightSet rights;
1880 struct dcesrv_handle *h;
1881 struct lsa_account_state *astate;
1884 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1888 rights.count = r->in.privs->count;
1889 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1890 if (rights.names == NULL) {
1891 return NT_STATUS_NO_MEMORY;
1893 for (i=0;i<rights.count;i++) {
1894 int id = r->in.privs->set[i].luid.low;
1895 if (r->in.privs->set[i].luid.high) {
1896 return NT_STATUS_NO_SUCH_PRIVILEGE;
1898 rights.names[i].string = sec_privilege_name(id);
1899 if (rights.names[i].string == NULL) {
1900 return NT_STATUS_NO_SUCH_PRIVILEGE;
1904 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1905 LDB_FLAG_MOD_ADD, astate->account_sid,
1911 lsa_RemovePrivilegesFromAccount
1913 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1914 struct lsa_RemovePrivilegesFromAccount *r)
1916 struct lsa_RightSet *rights;
1917 struct dcesrv_handle *h;
1918 struct lsa_account_state *astate;
1921 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1925 rights = talloc(mem_ctx, struct lsa_RightSet);
1927 if (r->in.remove_all == 1 &&
1928 r->in.privs == NULL) {
1929 struct lsa_EnumAccountRights r2;
1932 r2.in.handle = &astate->policy->handle->wire_handle;
1933 r2.in.sid = astate->account_sid;
1934 r2.out.rights = rights;
1936 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1937 if (!NT_STATUS_IS_OK(status)) {
1941 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1942 LDB_FLAG_MOD_DELETE, astate->account_sid,
1946 if (r->in.remove_all != 0) {
1947 return NT_STATUS_INVALID_PARAMETER;
1950 rights->count = r->in.privs->count;
1951 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
1952 if (rights->names == NULL) {
1953 return NT_STATUS_NO_MEMORY;
1955 for (i=0;i<rights->count;i++) {
1956 int id = r->in.privs->set[i].luid.low;
1957 if (r->in.privs->set[i].luid.high) {
1958 return NT_STATUS_NO_SUCH_PRIVILEGE;
1960 rights->names[i].string = sec_privilege_name(id);
1961 if (rights->names[i].string == NULL) {
1962 return NT_STATUS_NO_SUCH_PRIVILEGE;
1966 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1967 LDB_FLAG_MOD_DELETE, astate->account_sid,
1973 lsa_GetQuotasForAccount
1975 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1976 struct lsa_GetQuotasForAccount *r)
1978 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1983 lsa_SetQuotasForAccount
1985 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1986 struct lsa_SetQuotasForAccount *r)
1988 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1993 lsa_GetSystemAccessAccount
1995 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1996 struct lsa_GetSystemAccessAccount *r)
1998 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2003 lsa_SetSystemAccessAccount
2005 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2006 struct lsa_SetSystemAccessAccount *r)
2008 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2015 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2016 struct lsa_CreateSecret *r)
2018 struct dcesrv_handle *policy_handle;
2019 struct lsa_policy_state *policy_state;
2020 struct lsa_secret_state *secret_state;
2021 struct dcesrv_handle *handle;
2022 struct ldb_message **msgs, *msg;
2024 const char *attrs[] = {
2032 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2033 ZERO_STRUCTP(r->out.sec_handle);
2035 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2037 case SECURITY_SYSTEM:
2038 case SECURITY_ADMINISTRATOR:
2041 /* Users and annonymous are not allowed create secrets */
2042 return NT_STATUS_ACCESS_DENIED;
2045 policy_state = policy_handle->data;
2047 if (!r->in.name.string) {
2048 return NT_STATUS_INVALID_PARAMETER;
2051 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2052 if (!secret_state) {
2053 return NT_STATUS_NO_MEMORY;
2055 secret_state->policy = policy_state;
2057 msg = ldb_msg_new(mem_ctx);
2059 return NT_STATUS_NO_MEMORY;
2062 if (strncmp("G$", r->in.name.string, 2) == 0) {
2064 name = &r->in.name.string[2];
2065 /* 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) */
2066 secret_state->sam_ldb = talloc_reference(secret_state,
2067 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)));
2068 secret_state->global = true;
2070 if (strlen(name) < 1) {
2071 return NT_STATUS_INVALID_PARAMETER;
2074 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2075 /* search for the secret record */
2076 ret = gendb_search(secret_state->sam_ldb,
2077 mem_ctx, policy_state->system_dn, &msgs, attrs,
2078 "(&(cn=%s)(objectclass=secret))",
2081 return NT_STATUS_OBJECT_NAME_COLLISION;
2085 DEBUG(0,("Failure searching for CN=%s: %s\n",
2086 name2, ldb_errstring(secret_state->sam_ldb)));
2087 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2090 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2091 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2092 return NT_STATUS_NO_MEMORY;
2095 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2098 secret_state->global = false;
2100 name = r->in.name.string;
2101 if (strlen(name) < 1) {
2102 return NT_STATUS_INVALID_PARAMETER;
2105 secret_state->sam_ldb = talloc_reference(secret_state,
2106 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2107 /* search for the secret record */
2108 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2109 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2111 "(&(cn=%s)(objectclass=secret))",
2112 ldb_binary_encode_string(mem_ctx, name));
2114 return NT_STATUS_OBJECT_NAME_COLLISION;
2118 DEBUG(0,("Failure searching for CN=%s: %s\n",
2119 name, ldb_errstring(secret_state->sam_ldb)));
2120 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2123 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2124 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2127 /* pull in all the template attributes. Note this is always from the global samdb */
2128 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
2131 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2133 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2136 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2138 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2140 /* create the secret */
2141 ret = ldb_add(secret_state->sam_ldb, msg);
2143 DEBUG(0,("Failed to create secret record %s: %s\n",
2144 ldb_dn_get_linearized(msg->dn),
2145 ldb_errstring(secret_state->sam_ldb)));
2146 return NT_STATUS_ACCESS_DENIED;
2149 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2151 return NT_STATUS_NO_MEMORY;
2154 handle->data = talloc_steal(handle, secret_state);
2156 secret_state->access_mask = r->in.access_mask;
2157 secret_state->policy = talloc_reference(secret_state, policy_state);
2159 *r->out.sec_handle = handle->wire_handle;
2161 return NT_STATUS_OK;
2168 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2169 struct lsa_OpenSecret *r)
2171 struct dcesrv_handle *policy_handle;
2173 struct lsa_policy_state *policy_state;
2174 struct lsa_secret_state *secret_state;
2175 struct dcesrv_handle *handle;
2176 struct ldb_message **msgs;
2177 const char *attrs[] = {
2185 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2186 ZERO_STRUCTP(r->out.sec_handle);
2187 policy_state = policy_handle->data;
2189 if (!r->in.name.string) {
2190 return NT_STATUS_INVALID_PARAMETER;
2193 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2195 case SECURITY_SYSTEM:
2196 case SECURITY_ADMINISTRATOR:
2199 /* Users and annonymous are not allowed to access secrets */
2200 return NT_STATUS_ACCESS_DENIED;
2203 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2204 if (!secret_state) {
2205 return NT_STATUS_NO_MEMORY;
2207 secret_state->policy = policy_state;
2209 if (strncmp("G$", r->in.name.string, 2) == 0) {
2210 name = &r->in.name.string[2];
2211 /* 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) */
2212 secret_state->sam_ldb = talloc_reference(secret_state,
2213 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)));
2214 secret_state->global = true;
2216 if (strlen(name) < 1) {
2217 return NT_STATUS_INVALID_PARAMETER;
2220 /* search for the secret record */
2221 ret = gendb_search(secret_state->sam_ldb,
2222 mem_ctx, policy_state->system_dn, &msgs, attrs,
2223 "(&(cn=%s Secret)(objectclass=secret))",
2224 ldb_binary_encode_string(mem_ctx, name));
2226 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2230 DEBUG(0,("Found %d records matching DN %s\n", ret,
2231 ldb_dn_get_linearized(policy_state->system_dn)));
2232 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2236 secret_state->global = false;
2237 secret_state->sam_ldb = talloc_reference(secret_state,
2238 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2240 name = r->in.name.string;
2241 if (strlen(name) < 1) {
2242 return NT_STATUS_INVALID_PARAMETER;
2245 /* search for the secret record */
2246 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2247 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2249 "(&(cn=%s)(objectclass=secret))",
2250 ldb_binary_encode_string(mem_ctx, name));
2252 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2256 DEBUG(0,("Found %d records matching CN=%s\n",
2257 ret, ldb_binary_encode_string(mem_ctx, name)));
2258 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2262 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2264 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2266 return NT_STATUS_NO_MEMORY;
2269 handle->data = talloc_steal(handle, secret_state);
2271 secret_state->access_mask = r->in.access_mask;
2272 secret_state->policy = talloc_reference(secret_state, policy_state);
2274 *r->out.sec_handle = handle->wire_handle;
2276 return NT_STATUS_OK;
2283 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2284 struct lsa_SetSecret *r)
2287 struct dcesrv_handle *h;
2288 struct lsa_secret_state *secret_state;
2289 struct ldb_message *msg;
2290 DATA_BLOB session_key;
2291 DATA_BLOB crypt_secret, secret;
2294 NTSTATUS status = NT_STATUS_OK;
2296 struct timeval now = timeval_current();
2297 NTTIME nt_now = timeval_to_nttime(&now);
2299 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2301 secret_state = h->data;
2303 msg = ldb_msg_new(mem_ctx);
2305 return NT_STATUS_NO_MEMORY;
2308 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2310 return NT_STATUS_NO_MEMORY;
2312 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2313 if (!NT_STATUS_IS_OK(status)) {
2317 if (r->in.old_val) {
2319 crypt_secret.data = r->in.old_val->data;
2320 crypt_secret.length = r->in.old_val->size;
2322 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2323 if (!NT_STATUS_IS_OK(status)) {
2327 val.data = secret.data;
2328 val.length = secret.length;
2331 if (samdb_msg_add_value(secret_state->sam_ldb,
2332 mem_ctx, msg, "priorValue", &val) != 0) {
2333 return NT_STATUS_NO_MEMORY;
2336 /* set old value mtime */
2337 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2338 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2339 return NT_STATUS_NO_MEMORY;
2343 /* If the old value is not set, then migrate the
2344 * current value to the old value */
2345 const struct ldb_val *old_val;
2346 NTTIME last_set_time;
2347 struct ldb_message **res;
2348 const char *attrs[] = {
2354 /* search for the secret record */
2355 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2356 secret_state->secret_dn, &res, attrs);
2358 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2362 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2363 ldb_dn_get_linearized(secret_state->secret_dn)));
2364 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2367 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2368 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2372 if (samdb_msg_add_value(secret_state->sam_ldb,
2373 mem_ctx, msg, "priorValue",
2375 return NT_STATUS_NO_MEMORY;
2378 if (samdb_msg_add_delete(secret_state->sam_ldb,
2379 mem_ctx, msg, "priorValue")) {
2380 return NT_STATUS_NO_MEMORY;
2385 /* set old value mtime */
2386 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2387 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2388 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2389 return NT_STATUS_NO_MEMORY;
2392 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2393 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2394 return NT_STATUS_NO_MEMORY;
2399 if (r->in.new_val) {
2401 crypt_secret.data = r->in.new_val->data;
2402 crypt_secret.length = r->in.new_val->size;
2404 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2405 if (!NT_STATUS_IS_OK(status)) {
2409 val.data = secret.data;
2410 val.length = secret.length;
2413 if (samdb_msg_add_value(secret_state->sam_ldb,
2414 mem_ctx, msg, "currentValue", &val) != 0) {
2415 return NT_STATUS_NO_MEMORY;
2418 /* set new value mtime */
2419 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2420 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2421 return NT_STATUS_NO_MEMORY;
2425 /* NULL out the NEW value */
2426 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2427 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2428 return NT_STATUS_NO_MEMORY;
2430 if (samdb_msg_add_delete(secret_state->sam_ldb,
2431 mem_ctx, msg, "currentValue")) {
2432 return NT_STATUS_NO_MEMORY;
2436 /* modify the samdb record */
2437 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2439 /* we really need samdb.c to return NTSTATUS */
2440 return NT_STATUS_UNSUCCESSFUL;
2443 return NT_STATUS_OK;
2450 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2451 struct lsa_QuerySecret *r)
2453 struct dcesrv_handle *h;
2454 struct lsa_secret_state *secret_state;
2455 struct ldb_message *msg;
2456 DATA_BLOB session_key;
2457 DATA_BLOB crypt_secret, secret;
2459 struct ldb_message **res;
2460 const char *attrs[] = {
2470 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2472 /* Ensure user is permitted to read this... */
2473 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2475 case SECURITY_SYSTEM:
2476 case SECURITY_ADMINISTRATOR:
2479 /* Users and annonymous are not allowed to read secrets */
2480 return NT_STATUS_ACCESS_DENIED;
2483 secret_state = h->data;
2485 /* pull all the user attributes */
2486 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2487 secret_state->secret_dn, &res, attrs);
2489 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2493 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2494 if (!NT_STATUS_IS_OK(nt_status)) {
2498 if (r->in.old_val) {
2499 const struct ldb_val *prior_val;
2500 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2501 if (!r->out.old_val) {
2502 return NT_STATUS_NO_MEMORY;
2504 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2506 if (prior_val && prior_val->length) {
2507 secret.data = prior_val->data;
2508 secret.length = prior_val->length;
2511 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2512 if (!crypt_secret.length) {
2513 return NT_STATUS_NO_MEMORY;
2515 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2516 if (!r->out.old_val->buf) {
2517 return NT_STATUS_NO_MEMORY;
2519 r->out.old_val->buf->size = crypt_secret.length;
2520 r->out.old_val->buf->length = crypt_secret.length;
2521 r->out.old_val->buf->data = crypt_secret.data;
2525 if (r->in.old_mtime) {
2526 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2527 if (!r->out.old_mtime) {
2528 return NT_STATUS_NO_MEMORY;
2530 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2533 if (r->in.new_val) {
2534 const struct ldb_val *new_val;
2535 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2536 if (!r->out.new_val) {
2537 return NT_STATUS_NO_MEMORY;
2540 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2542 if (new_val && new_val->length) {
2543 secret.data = new_val->data;
2544 secret.length = new_val->length;
2547 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2548 if (!crypt_secret.length) {
2549 return NT_STATUS_NO_MEMORY;
2551 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2552 if (!r->out.new_val->buf) {
2553 return NT_STATUS_NO_MEMORY;
2555 r->out.new_val->buf->length = crypt_secret.length;
2556 r->out.new_val->buf->size = crypt_secret.length;
2557 r->out.new_val->buf->data = crypt_secret.data;
2561 if (r->in.new_mtime) {
2562 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2563 if (!r->out.new_mtime) {
2564 return NT_STATUS_NO_MEMORY;
2566 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2569 return NT_STATUS_OK;
2576 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2577 TALLOC_CTX *mem_ctx,
2578 struct lsa_LookupPrivValue *r)
2580 struct dcesrv_handle *h;
2581 struct lsa_policy_state *state;
2584 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2588 id = sec_privilege_id(r->in.name->string);
2590 return NT_STATUS_NO_SUCH_PRIVILEGE;
2593 r->out.luid->low = id;
2594 r->out.luid->high = 0;
2596 return NT_STATUS_OK;
2603 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2604 TALLOC_CTX *mem_ctx,
2605 struct lsa_LookupPrivName *r)
2607 struct dcesrv_handle *h;
2608 struct lsa_policy_state *state;
2609 const char *privname;
2611 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2615 if (r->in.luid->high != 0) {
2616 return NT_STATUS_NO_SUCH_PRIVILEGE;
2619 privname = sec_privilege_name(r->in.luid->low);
2620 if (privname == NULL) {
2621 return NT_STATUS_NO_SUCH_PRIVILEGE;
2624 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2625 if (r->out.name == NULL) {
2626 return NT_STATUS_NO_MEMORY;
2628 r->out.name->string = privname;
2630 return NT_STATUS_OK;
2635 lsa_LookupPrivDisplayName
2637 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2638 TALLOC_CTX *mem_ctx,
2639 struct lsa_LookupPrivDisplayName *r)
2641 struct dcesrv_handle *h;
2642 struct lsa_policy_state *state;
2645 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2649 id = sec_privilege_id(r->in.name->string);
2651 return NT_STATUS_NO_SUCH_PRIVILEGE;
2654 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2655 if (r->out.disp_name == NULL) {
2656 return NT_STATUS_NO_MEMORY;
2659 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2660 if (r->out.disp_name->string == NULL) {
2661 return NT_STATUS_INTERNAL_ERROR;
2664 return NT_STATUS_OK;
2669 lsa_EnumAccountsWithUserRight
2671 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2672 TALLOC_CTX *mem_ctx,
2673 struct lsa_EnumAccountsWithUserRight *r)
2675 struct dcesrv_handle *h;
2676 struct lsa_policy_state *state;
2678 struct ldb_message **res;
2679 const char * const attrs[] = { "objectSid", NULL};
2680 const char *privname;
2682 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2686 if (r->in.name == NULL) {
2687 return NT_STATUS_NO_SUCH_PRIVILEGE;
2690 privname = r->in.name->string;
2691 if (sec_privilege_id(privname) == -1) {
2692 return NT_STATUS_NO_SUCH_PRIVILEGE;
2695 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2696 "privilege=%s", privname);
2698 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2701 return NT_STATUS_NO_MORE_ENTRIES;
2704 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2705 if (r->out.sids->sids == NULL) {
2706 return NT_STATUS_NO_MEMORY;
2708 for (i=0;i<ret;i++) {
2709 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2710 res[i], "objectSid");
2711 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2713 r->out.sids->num_sids = ret;
2715 return NT_STATUS_OK;
2720 lsa_AddAccountRights
2722 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2723 TALLOC_CTX *mem_ctx,
2724 struct lsa_AddAccountRights *r)
2726 struct dcesrv_handle *h;
2727 struct lsa_policy_state *state;
2729 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2733 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2735 r->in.sid, r->in.rights);
2740 lsa_RemoveAccountRights
2742 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2743 TALLOC_CTX *mem_ctx,
2744 struct lsa_RemoveAccountRights *r)
2746 struct dcesrv_handle *h;
2747 struct lsa_policy_state *state;
2749 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2753 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2754 LDB_FLAG_MOD_DELETE,
2755 r->in.sid, r->in.rights);
2760 lsa_StorePrivateData
2762 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2763 struct lsa_StorePrivateData *r)
2765 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2770 lsa_RetrievePrivateData
2772 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2773 struct lsa_RetrievePrivateData *r)
2775 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2782 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2783 struct lsa_GetUserName *r)
2785 NTSTATUS status = NT_STATUS_OK;
2786 const char *account_name;
2787 const char *authority_name;
2788 struct lsa_String *_account_name;
2789 struct lsa_StringPointer *_authority_name = NULL;
2791 /* this is what w2k3 does */
2792 r->out.account_name = r->in.account_name;
2793 r->out.authority_name = r->in.authority_name;
2795 if (r->in.account_name && r->in.account_name->string) {
2796 return NT_STATUS_INVALID_PARAMETER;
2799 if (r->in.authority_name &&
2800 r->in.authority_name->string &&
2801 r->in.authority_name->string->string) {
2802 return NT_STATUS_INVALID_PARAMETER;
2805 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2806 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2808 _account_name = talloc(mem_ctx, struct lsa_String);
2809 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2810 _account_name->string = account_name;
2812 if (r->in.authority_name) {
2813 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2814 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2815 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2816 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2817 _authority_name->string->string = authority_name;
2820 r->out.account_name = _account_name;
2821 r->out.authority_name = _authority_name;
2829 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2830 TALLOC_CTX *mem_ctx,
2831 struct lsa_SetInfoPolicy2 *r)
2833 /* need to support these */
2834 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2838 lsa_QueryDomainInformationPolicy
2840 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2841 TALLOC_CTX *mem_ctx,
2842 struct lsa_QueryDomainInformationPolicy *r)
2844 r->out.info = talloc(mem_ctx, union lsa_DomainInformationPolicy);
2846 return NT_STATUS_NO_MEMORY;
2849 switch (r->in.level) {
2850 case LSA_DOMAIN_INFO_POLICY_EFS:
2851 talloc_free(r->out.info);
2853 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2854 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
2856 struct lsa_DomainInfoKerberos *k = &r->out.info->kerberos_info;
2857 struct smb_krb5_context *smb_krb5_context;
2858 int ret = smb_krb5_init_context(mem_ctx,
2859 dce_call->event_ctx,
2860 dce_call->conn->dce_ctx->lp_ctx,
2863 talloc_free(r->out.info);
2865 return NT_STATUS_INTERNAL_ERROR;
2867 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
2868 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2869 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2870 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
2871 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
2872 talloc_free(smb_krb5_context);
2873 return NT_STATUS_OK;
2876 talloc_free(r->out.info);
2878 return NT_STATUS_INVALID_INFO_CLASS;
2883 lsa_SetDomInfoPolicy
2885 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2886 TALLOC_CTX *mem_ctx,
2887 struct lsa_SetDomainInformationPolicy *r)
2889 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2895 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
2896 TALLOC_CTX *mem_ctx,
2897 struct lsa_TestCall *r)
2899 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2905 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2906 struct lsa_CREDRWRITE *r)
2908 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2915 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2916 struct lsa_CREDRREAD *r)
2918 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2925 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2926 struct lsa_CREDRENUMERATE *r)
2928 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2933 lsa_CREDRWRITEDOMAINCREDENTIALS
2935 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2936 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2938 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2943 lsa_CREDRREADDOMAINCREDENTIALS
2945 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2946 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2948 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2955 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2956 struct lsa_CREDRDELETE *r)
2958 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2963 lsa_CREDRGETTARGETINFO
2965 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2966 struct lsa_CREDRGETTARGETINFO *r)
2968 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2973 lsa_CREDRPROFILELOADED
2975 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2976 struct lsa_CREDRPROFILELOADED *r)
2978 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2983 lsa_CREDRGETSESSIONTYPES
2985 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2986 struct lsa_CREDRGETSESSIONTYPES *r)
2988 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2993 lsa_LSARREGISTERAUDITEVENT
2995 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2996 struct lsa_LSARREGISTERAUDITEVENT *r)
2998 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3003 lsa_LSARGENAUDITEVENT
3005 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3006 struct lsa_LSARGENAUDITEVENT *r)
3008 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3013 lsa_LSARUNREGISTERAUDITEVENT
3015 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3016 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3018 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3023 lsa_lsaRQueryForestTrustInformation
3025 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3026 struct lsa_lsaRQueryForestTrustInformation *r)
3028 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3033 lsa_LSARSETFORESTTRUSTINFORMATION
3035 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3036 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3038 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3045 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3046 struct lsa_CREDRRENAME *r)
3048 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3054 lsa_LSAROPENPOLICYSCE
3056 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3057 struct lsa_LSAROPENPOLICYSCE *r)
3059 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3064 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3066 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3067 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3069 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3074 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3076 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3077 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3079 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3084 lsa_LSARADTREPORTSECURITYEVENT
3086 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3087 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3089 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3093 /* include the generated boilerplate */
3094 #include "librpc/gen_ndr/ndr_lsa_s.c"
3098 /*****************************************
3099 NOTE! The remaining calls below were
3100 removed in w2k3, so the DCESRV_FAULT()
3101 replies are the correct implementation. Do
3102 not try and fill these in with anything else
3103 ******************************************/
3106 dssetup_DsRoleDnsNameToFlatName
3108 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3109 struct dssetup_DsRoleDnsNameToFlatName *r)
3111 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3116 dssetup_DsRoleDcAsDc
3118 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3119 struct dssetup_DsRoleDcAsDc *r)
3121 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3126 dssetup_DsRoleDcAsReplica
3128 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3129 struct dssetup_DsRoleDcAsReplica *r)
3131 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3136 dssetup_DsRoleDemoteDc
3138 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3139 struct dssetup_DsRoleDemoteDc *r)
3141 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3146 dssetup_DsRoleGetDcOperationProgress
3148 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3149 struct dssetup_DsRoleGetDcOperationProgress *r)
3151 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3156 dssetup_DsRoleGetDcOperationResults
3158 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3159 struct dssetup_DsRoleGetDcOperationResults *r)
3161 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3166 dssetup_DsRoleCancel
3168 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3169 struct dssetup_DsRoleCancel *r)
3171 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3176 dssetup_DsRoleServerSaveStateForUpgrade
3178 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3179 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3181 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3186 dssetup_DsRoleUpgradeDownlevelServer
3188 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3189 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3191 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3196 dssetup_DsRoleAbortDownlevelServerUpgrade
3198 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3199 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3201 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3205 /* include the generated boilerplate */
3206 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3208 NTSTATUS dcerpc_server_lsa_init(void)
3212 ret = dcerpc_server_dssetup_init();
3213 if (!NT_STATUS_IS_OK(ret)) {
3216 ret = dcerpc_server_lsarpc_init();
3217 if (!NT_STATUS_IS_OK(ret)) {