1 /* need access mask/acl implementation */
4 Unix SMB/CIFS implementation.
6 endpoint server for the lsarpc pipe
8 Copyright (C) Andrew Tridgell 2004
9 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "rpc_server/lsa/lsa.h"
26 #include "system/kerberos.h"
27 #include "auth/kerberos/kerberos.h"
28 #include "librpc/gen_ndr/ndr_drsblobs.h"
29 #include "librpc/gen_ndr/ndr_lsa.h"
30 #include "../lib/crypto/crypto.h"
33 this type allows us to distinguish handle types
37 state associated with a lsa_OpenAccount() operation
39 struct lsa_account_state {
40 struct lsa_policy_state *policy;
42 struct dom_sid *account_sid;
47 state associated with a lsa_OpenSecret() operation
49 struct lsa_secret_state {
50 struct lsa_policy_state *policy;
52 struct ldb_dn *secret_dn;
53 struct ldb_context *sam_ldb;
58 state associated with a lsa_OpenTrustedDomain() operation
60 struct lsa_trusted_domain_state {
61 struct lsa_policy_state *policy;
63 struct ldb_dn *trusted_domain_dn;
64 struct ldb_dn *trusted_domain_user_dn;
67 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
69 struct lsa_EnumAccountRights *r);
71 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
73 struct lsa_policy_state *state,
76 const struct lsa_RightSet *rights);
81 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
84 struct dcesrv_handle *h;
86 *r->out.handle = *r->in.handle;
88 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
92 ZERO_STRUCTP(r->out.handle);
101 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
102 struct lsa_Delete *r)
104 return NT_STATUS_NOT_SUPPORTED;
111 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
112 struct lsa_DeleteObject *r)
114 struct dcesrv_handle *h;
117 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
119 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
120 struct lsa_secret_state *secret_state = h->data;
122 /* Ensure user is permitted to delete this... */
123 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
125 case SECURITY_SYSTEM:
126 case SECURITY_ADMINISTRATOR:
129 /* Users and annonymous are not allowed delete things */
130 return NT_STATUS_ACCESS_DENIED;
133 ret = ldb_delete(secret_state->sam_ldb,
134 secret_state->secret_dn);
137 return NT_STATUS_INVALID_HANDLE;
140 ZERO_STRUCTP(r->out.handle);
143 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
144 struct lsa_trusted_domain_state *trusted_domain_state =
145 talloc_get_type(h->data, struct lsa_trusted_domain_state);
146 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
148 return NT_STATUS_INTERNAL_DB_CORRUPTION;
151 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
152 trusted_domain_state->trusted_domain_dn);
154 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
155 return NT_STATUS_INVALID_HANDLE;
158 if (trusted_domain_state->trusted_domain_user_dn) {
159 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
160 trusted_domain_state->trusted_domain_user_dn);
162 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
163 return NT_STATUS_INVALID_HANDLE;
167 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
169 return NT_STATUS_INTERNAL_DB_CORRUPTION;
172 ZERO_STRUCTP(r->out.handle);
175 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
176 struct lsa_RightSet *rights;
177 struct lsa_account_state *astate;
178 struct lsa_EnumAccountRights r2;
181 rights = talloc(mem_ctx, struct lsa_RightSet);
183 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
187 r2.in.handle = &astate->policy->handle->wire_handle;
188 r2.in.sid = astate->account_sid;
189 r2.out.rights = rights;
191 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
192 but we have a LSA_HANDLE_ACCOUNT here, so this call
194 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
195 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
199 if (!NT_STATUS_IS_OK(status)) {
203 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
204 LDB_FLAG_MOD_DELETE, astate->account_sid,
206 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
210 if (!NT_STATUS_IS_OK(status)) {
214 ZERO_STRUCTP(r->out.handle);
217 return NT_STATUS_INVALID_HANDLE;
224 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
225 struct lsa_EnumPrivs *r)
227 struct dcesrv_handle *h;
228 struct lsa_policy_state *state;
230 const char *privname;
232 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
236 i = *r->in.resume_handle;
239 while ((privname = sec_privilege_name(i)) &&
240 r->out.privs->count < r->in.max_count) {
241 struct lsa_PrivEntry *e;
243 r->out.privs->privs = talloc_realloc(r->out.privs,
245 struct lsa_PrivEntry,
246 r->out.privs->count+1);
247 if (r->out.privs->privs == NULL) {
248 return NT_STATUS_NO_MEMORY;
250 e = &r->out.privs->privs[r->out.privs->count];
253 e->name.string = privname;
254 r->out.privs->count++;
258 *r->out.resume_handle = i;
267 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
268 struct lsa_QuerySecurity *r)
270 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
277 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
278 struct lsa_SetSecObj *r)
280 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
287 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
288 struct lsa_ChangePassword *r)
290 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
294 dssetup_DsRoleGetPrimaryDomainInformation
296 This is not an LSA call, but is the only call left on the DSSETUP
297 pipe (after the pipe was truncated), and needs lsa_get_policy_state
299 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
301 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
303 union dssetup_DsRoleInfo *info;
305 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
306 W_ERROR_HAVE_NO_MEMORY(info);
308 switch (r->in.level) {
309 case DS_ROLE_BASIC_INFORMATION:
311 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
313 const char *domain = NULL;
314 const char *dns_domain = NULL;
315 const char *forest = NULL;
316 struct GUID domain_guid;
317 struct lsa_policy_state *state;
319 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
320 if (!NT_STATUS_IS_OK(status)) {
321 return ntstatus_to_werror(status);
324 ZERO_STRUCT(domain_guid);
326 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
327 case ROLE_STANDALONE:
328 role = DS_ROLE_STANDALONE_SERVER;
330 case ROLE_DOMAIN_MEMBER:
331 role = DS_ROLE_MEMBER_SERVER;
333 case ROLE_DOMAIN_CONTROLLER:
334 if (samdb_is_pdc(state->sam_ldb)) {
335 role = DS_ROLE_PRIMARY_DC;
337 role = DS_ROLE_BACKUP_DC;
342 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
343 case ROLE_STANDALONE:
344 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
345 W_ERROR_HAVE_NO_MEMORY(domain);
347 case ROLE_DOMAIN_MEMBER:
348 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
349 W_ERROR_HAVE_NO_MEMORY(domain);
350 /* TODO: what is with dns_domain and forest and guid? */
352 case ROLE_DOMAIN_CONTROLLER:
353 flags = DS_ROLE_PRIMARY_DS_RUNNING;
355 if (state->mixed_domain == 1) {
356 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
359 domain = state->domain_name;
360 dns_domain = state->domain_dns;
361 forest = state->forest_dns;
363 domain_guid = state->domain_guid;
364 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
368 info->basic.role = role;
369 info->basic.flags = flags;
370 info->basic.domain = domain;
371 info->basic.dns_domain = dns_domain;
372 info->basic.forest = forest;
373 info->basic.domain_guid = domain_guid;
378 case DS_ROLE_UPGRADE_STATUS:
380 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
381 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
386 case DS_ROLE_OP_STATUS:
388 info->opstatus.status = DS_ROLE_OP_IDLE;
394 return WERR_INVALID_PARAM;
397 return WERR_INVALID_PARAM;
401 fill in the AccountDomain info
403 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
404 struct lsa_DomainInfo *info)
406 info->name.string = state->domain_name;
407 info->sid = state->domain_sid;
413 fill in the DNS domain info
415 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
416 struct lsa_DnsDomainInfo *info)
418 info->name.string = state->domain_name;
419 info->sid = state->domain_sid;
420 info->dns_domain.string = state->domain_dns;
421 info->dns_forest.string = state->forest_dns;
422 info->domain_guid = state->domain_guid;
430 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
431 struct lsa_QueryInfoPolicy2 *r)
433 struct lsa_policy_state *state;
434 struct dcesrv_handle *h;
435 union lsa_PolicyInformation *info;
439 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
443 info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
445 return NT_STATUS_NO_MEMORY;
449 switch (r->in.level) {
450 case LSA_POLICY_INFO_AUDIT_LOG:
451 /* we don't need to fill in any of this */
452 ZERO_STRUCT(info->audit_log);
454 case LSA_POLICY_INFO_AUDIT_EVENTS:
455 /* we don't need to fill in any of this */
456 ZERO_STRUCT(info->audit_events);
458 case LSA_POLICY_INFO_PD:
459 /* we don't need to fill in any of this */
460 ZERO_STRUCT(info->pd);
463 case LSA_POLICY_INFO_DOMAIN:
464 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
465 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
466 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
467 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
468 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
471 case LSA_POLICY_INFO_ROLE:
472 info->role.role = LSA_ROLE_PRIMARY;
475 case LSA_POLICY_INFO_DNS:
476 case LSA_POLICY_INFO_DNS_INT:
477 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
479 case LSA_POLICY_INFO_REPLICA:
480 ZERO_STRUCT(info->replica);
483 case LSA_POLICY_INFO_QUOTA:
484 ZERO_STRUCT(info->quota);
487 case LSA_POLICY_INFO_MOD:
488 case LSA_POLICY_INFO_AUDIT_FULL_SET:
489 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
490 /* windows gives INVALID_PARAMETER */
492 return NT_STATUS_INVALID_PARAMETER;
496 return NT_STATUS_INVALID_INFO_CLASS;
502 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
503 struct lsa_QueryInfoPolicy *r)
505 struct lsa_QueryInfoPolicy2 r2;
510 r2.in.handle = r->in.handle;
511 r2.in.level = r->in.level;
512 r2.out.info = r->out.info;
514 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
522 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
523 struct lsa_SetInfoPolicy *r)
525 /* need to support this */
526 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
533 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
534 struct lsa_ClearAuditLog *r)
536 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
543 This call does not seem to have any long-term effects, hence no database operations
545 we need to talk to the MS product group to find out what this account database means!
547 answer is that the lsa database is totally separate from the SAM and
548 ldap databases. We are going to need a separate ldb to store these
549 accounts. The SIDs on this account bear no relation to the SIDs in
552 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
553 struct lsa_CreateAccount *r)
555 struct lsa_account_state *astate;
557 struct lsa_policy_state *state;
558 struct dcesrv_handle *h, *ah;
560 ZERO_STRUCTP(r->out.acct_handle);
562 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
566 astate = talloc(dce_call->conn, struct lsa_account_state);
567 if (astate == NULL) {
568 return NT_STATUS_NO_MEMORY;
571 astate->account_sid = dom_sid_dup(astate, r->in.sid);
572 if (astate->account_sid == NULL) {
574 return NT_STATUS_NO_MEMORY;
577 astate->policy = talloc_reference(astate, state);
578 astate->access_mask = r->in.access_mask;
580 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
583 return NT_STATUS_NO_MEMORY;
586 ah->data = talloc_steal(ah, astate);
588 *r->out.acct_handle = ah->wire_handle;
597 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
598 struct lsa_EnumAccounts *r)
600 struct dcesrv_handle *h;
601 struct lsa_policy_state *state;
603 struct ldb_message **res;
604 const char * const attrs[] = { "objectSid", NULL};
607 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
611 /* NOTE: This call must only return accounts that have at least
614 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
615 "(&(objectSid=*)(privilege=*))");
617 return NT_STATUS_NO_SUCH_USER;
620 if (*r->in.resume_handle >= ret) {
621 return NT_STATUS_NO_MORE_ENTRIES;
624 count = ret - *r->in.resume_handle;
625 if (count > r->in.num_entries) {
626 count = r->in.num_entries;
630 return NT_STATUS_NO_MORE_ENTRIES;
633 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
634 if (r->out.sids->sids == NULL) {
635 return NT_STATUS_NO_MEMORY;
638 for (i=0;i<count;i++) {
639 r->out.sids->sids[i].sid =
640 samdb_result_dom_sid(r->out.sids->sids,
641 res[i + *r->in.resume_handle],
643 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
646 r->out.sids->num_sids = count;
647 *r->out.resume_handle = count + *r->in.resume_handle;
655 lsa_CreateTrustedDomainEx2
657 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
659 struct lsa_CreateTrustedDomainEx2 *r,
662 struct dcesrv_handle *policy_handle;
663 struct lsa_policy_state *policy_state;
664 struct lsa_trusted_domain_state *trusted_domain_state;
665 struct dcesrv_handle *handle;
666 struct ldb_message **msgs, *msg, *msg_user;
667 const char *attrs[] = {
670 const char *netbios_name;
671 const char *dns_name;
673 DATA_BLOB session_key = data_blob(NULL, 0);
674 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
675 struct trustDomainPasswords auth_struct;
678 enum ndr_err_code ndr_err;
680 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
681 ZERO_STRUCTP(r->out.trustdom_handle);
683 policy_state = policy_handle->data;
685 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
686 if (!NT_STATUS_IS_OK(nt_status)) {
690 netbios_name = r->in.info->netbios_name.string;
692 return NT_STATUS_INVALID_PARAMETER;
695 dns_name = r->in.info->domain_name.string;
697 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
698 if (!trusted_domain_state) {
699 return NT_STATUS_NO_MEMORY;
701 trusted_domain_state->policy = policy_state;
703 if (strcasecmp(netbios_name, "BUILTIN") == 0
704 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
705 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
706 return NT_STATUS_INVALID_PARAMETER;;
709 if (strcasecmp(netbios_name, policy_state->domain_name) == 0
710 || strcasecmp(netbios_name, policy_state->domain_dns) == 0
711 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)
712 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
713 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
714 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
717 /* While this is a REF pointer, some of the functions that wrap this don't provide this */
718 if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
719 /* No secrets are created at this time, for this function */
720 auth_struct.outgoing.count = 0;
721 auth_struct.incoming.count = 0;
723 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data, r->in.auth_info->auth_blob.size);
724 arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key);
725 ndr_err = ndr_pull_struct_blob(&auth_blob, mem_ctx,
726 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
728 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
729 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
730 return NT_STATUS_INVALID_PARAMETER;
733 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
734 if (auth_struct.incoming.count > 1) {
735 return NT_STATUS_INVALID_PARAMETER;
740 if (auth_struct.incoming.count) {
742 struct trustAuthInOutBlob incoming;
744 incoming.count = auth_struct.incoming.count;
745 incoming.current = talloc(mem_ctx, struct AuthenticationInformationArray);
746 if (!incoming.current) {
747 return NT_STATUS_NO_MEMORY;
750 incoming.current->array = *auth_struct.incoming.current;
751 if (!incoming.current->array) {
752 return NT_STATUS_NO_MEMORY;
755 incoming.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
756 if (!incoming.previous) {
757 return NT_STATUS_NO_MEMORY;
759 incoming.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, incoming.count);
760 if (!incoming.previous->array) {
761 return NT_STATUS_NO_MEMORY;
764 for (i = 0; i < incoming.count; i++) {
765 incoming.previous->array[i].LastUpdateTime = 0;
766 incoming.previous->array[i].AuthType = 0;
768 ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx,
769 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
771 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
772 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
773 return NT_STATUS_INVALID_PARAMETER;
776 trustAuthIncoming = data_blob(NULL, 0);
779 if (auth_struct.outgoing.count) {
781 struct trustAuthInOutBlob outgoing;
783 outgoing.count = auth_struct.outgoing.count;
784 outgoing.current = talloc(mem_ctx, struct AuthenticationInformationArray);
785 if (!outgoing.current) {
786 return NT_STATUS_NO_MEMORY;
789 outgoing.current->array = *auth_struct.outgoing.current;
790 if (!outgoing.current->array) {
791 return NT_STATUS_NO_MEMORY;
794 outgoing.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
795 if (!outgoing.previous) {
796 return NT_STATUS_NO_MEMORY;
798 outgoing.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, outgoing.count);
799 if (!outgoing.previous->array) {
800 return NT_STATUS_NO_MEMORY;
803 for (i = 0; i < outgoing.count; i++) {
804 outgoing.previous->array[i].LastUpdateTime = 0;
805 outgoing.previous->array[i].AuthType = 0;
807 ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx,
808 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
810 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
811 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
812 return NT_STATUS_INVALID_PARAMETER;
815 trustAuthOutgoing = data_blob(NULL, 0);
818 ret = ldb_transaction_start(policy_state->sam_ldb);
819 if (ret != LDB_SUCCESS) {
820 return NT_STATUS_INTERNAL_DB_CORRUPTION;
824 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
825 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
826 /* search for the trusted_domain record */
827 ret = gendb_search(policy_state->sam_ldb,
828 mem_ctx, policy_state->system_dn, &msgs, attrs,
829 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
830 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
832 ldb_transaction_cancel(policy_state->sam_ldb);
833 return NT_STATUS_OBJECT_NAME_COLLISION;
836 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
837 /* search for the trusted_domain record */
838 ret = gendb_search(policy_state->sam_ldb,
839 mem_ctx, policy_state->system_dn, &msgs, attrs,
840 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))",
841 netbios_encoded, netbios_encoded, netbios_encoded);
843 ldb_transaction_cancel(policy_state->sam_ldb);
844 return NT_STATUS_OBJECT_NAME_COLLISION;
849 ldb_transaction_cancel(policy_state->sam_ldb);
850 return NT_STATUS_INTERNAL_DB_CORRUPTION;
853 name = dns_name ? dns_name : netbios_name;
855 msg = ldb_msg_new(mem_ctx);
857 return NT_STATUS_NO_MEMORY;
860 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
861 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
862 ldb_transaction_cancel(policy_state->sam_ldb);
863 return NT_STATUS_NO_MEMORY;
866 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", netbios_name);
868 if (r->in.info->sid) {
869 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
871 ldb_transaction_cancel(policy_state->sam_ldb);
872 return NT_STATUS_NO_MEMORY;
875 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
878 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
880 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
882 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
884 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
887 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
890 if (trustAuthIncoming.data) {
891 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
892 if (ret != LDB_SUCCESS) {
893 ldb_transaction_cancel(policy_state->sam_ldb);
894 return NT_STATUS_NO_MEMORY;
897 if (trustAuthOutgoing.data) {
898 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
899 if (ret != LDB_SUCCESS) {
900 ldb_transaction_cancel(policy_state->sam_ldb);
901 return NT_STATUS_NO_MEMORY;
905 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
907 /* create the trusted_domain */
908 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
912 case LDB_ERR_ENTRY_ALREADY_EXISTS:
913 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
914 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
915 ldb_dn_get_linearized(msg->dn),
916 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
917 return NT_STATUS_DOMAIN_EXISTS;
918 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
919 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
920 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
921 ldb_dn_get_linearized(msg->dn),
922 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
923 return NT_STATUS_ACCESS_DENIED;
925 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
926 DEBUG(0,("Failed to create user record %s: %s\n",
927 ldb_dn_get_linearized(msg->dn),
928 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
929 return NT_STATUS_INTERNAL_DB_CORRUPTION;
932 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
933 msg_user = ldb_msg_new(mem_ctx);
934 if (msg_user == NULL) {
935 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
936 return NT_STATUS_NO_MEMORY;
939 /* Inbound trusts must also create a cn=users object to match */
941 trusted_domain_state->trusted_domain_user_dn = msg_user->dn
942 = ldb_dn_copy(trusted_domain_state, policy_state->domain_dn);
943 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=users")) {
944 ldb_transaction_cancel(policy_state->sam_ldb);
945 return NT_STATUS_NO_MEMORY;
948 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=%s", netbios_name)) {
949 ldb_transaction_cancel(policy_state->sam_ldb);
950 return NT_STATUS_NO_MEMORY;
953 ldb_msg_add_string(msg_user, "objectClass", "user");
955 ldb_msg_add_steal_string(msg_user, "samAccountName",
956 talloc_asprintf(mem_ctx, "%s$", netbios_name));
958 if (samdb_msg_add_uint(trusted_domain_state->policy->sam_ldb, mem_ctx, msg_user,
959 "userAccountControl",
960 UF_INTERDOMAIN_TRUST_ACCOUNT) != 0) {
961 ldb_transaction_cancel(policy_state->sam_ldb);
962 return NT_STATUS_NO_MEMORY;
965 if (auth_struct.incoming.count) {
967 for (i=0; i < auth_struct.incoming.count; i++ ) {
968 if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_NT4OWF) {
969 samdb_msg_add_hash(trusted_domain_state->policy->sam_ldb,
970 mem_ctx, msg_user, "unicodePwd",
971 &auth_struct.incoming.current[i]->AuthInfo.nt4owf.password);
972 } else if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_CLEAR) {
973 DATA_BLOB new_password = data_blob_const(auth_struct.incoming.current[i]->AuthInfo.clear.password,
974 auth_struct.incoming.current[i]->AuthInfo.clear.size);
975 ret = ldb_msg_add_value(msg_user, "clearTextPassword", &new_password, NULL);
976 if (ret != LDB_SUCCESS) {
977 ldb_transaction_cancel(policy_state->sam_ldb);
978 return NT_STATUS_NO_MEMORY;
984 /* create the cn=users trusted_domain account */
985 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg_user);
989 case LDB_ERR_ENTRY_ALREADY_EXISTS:
990 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
991 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
992 ldb_dn_get_linearized(msg_user->dn),
993 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
994 return NT_STATUS_DOMAIN_EXISTS;
995 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
996 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
997 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
998 ldb_dn_get_linearized(msg_user->dn),
999 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1000 return NT_STATUS_ACCESS_DENIED;
1002 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1003 DEBUG(0,("Failed to create user record %s: %s\n",
1004 ldb_dn_get_linearized(msg_user->dn),
1005 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1006 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1010 ret = ldb_transaction_commit(policy_state->sam_ldb);
1011 if (ret != LDB_SUCCESS) {
1012 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1015 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1017 return NT_STATUS_NO_MEMORY;
1020 handle->data = talloc_steal(handle, trusted_domain_state);
1022 trusted_domain_state->access_mask = r->in.access_mask;
1023 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1025 *r->out.trustdom_handle = handle->wire_handle;
1027 return NT_STATUS_OK;
1031 lsa_CreateTrustedDomainEx2
1033 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1034 TALLOC_CTX *mem_ctx,
1035 struct lsa_CreateTrustedDomainEx2 *r)
1037 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
1040 lsa_CreateTrustedDomainEx
1042 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1043 TALLOC_CTX *mem_ctx,
1044 struct lsa_CreateTrustedDomainEx *r)
1046 struct lsa_CreateTrustedDomainEx2 r2;
1048 r2.in.policy_handle = r->in.policy_handle;
1049 r2.in.info = r->in.info;
1050 r2.in.auth_info = r->in.auth_info;
1051 r2.out.trustdom_handle = r->out.trustdom_handle;
1052 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
1056 lsa_CreateTrustedDomain
1058 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1059 struct lsa_CreateTrustedDomain *r)
1061 struct lsa_CreateTrustedDomainEx2 r2;
1063 r2.in.policy_handle = r->in.policy_handle;
1064 r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1066 return NT_STATUS_NO_MEMORY;
1069 r2.in.info->domain_name.string = NULL;
1070 r2.in.info->netbios_name = r->in.info->name;
1071 r2.in.info->sid = r->in.info->sid;
1072 r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1073 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1074 r2.in.info->trust_attributes = 0;
1076 r2.in.access_mask = r->in.access_mask;
1077 r2.out.trustdom_handle = r->out.trustdom_handle;
1079 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1084 lsa_OpenTrustedDomain
1086 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1087 struct lsa_OpenTrustedDomain *r)
1089 struct dcesrv_handle *policy_handle;
1091 struct lsa_policy_state *policy_state;
1092 struct lsa_trusted_domain_state *trusted_domain_state;
1093 struct dcesrv_handle *handle;
1094 struct ldb_message **msgs;
1095 const char *attrs[] = {
1101 const char *sid_string;
1104 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1105 ZERO_STRUCTP(r->out.trustdom_handle);
1106 policy_state = policy_handle->data;
1108 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1109 if (!trusted_domain_state) {
1110 return NT_STATUS_NO_MEMORY;
1112 trusted_domain_state->policy = policy_state;
1114 sid_string = dom_sid_string(mem_ctx, r->in.sid);
1116 return NT_STATUS_NO_MEMORY;
1119 /* search for the trusted_domain record */
1120 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1121 mem_ctx, policy_state->system_dn, &msgs, attrs,
1122 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
1125 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1129 DEBUG(0,("Found %d records matching DN %s\n", ret,
1130 ldb_dn_get_linearized(policy_state->system_dn)));
1131 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1134 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1136 trusted_domain_state->trusted_domain_user_dn = NULL;
1138 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1139 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1140 /* search for the trusted_domain record */
1141 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1142 mem_ctx, policy_state->domain_dn, &msgs, attrs,
1143 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%d))",
1144 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1146 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1149 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1151 return NT_STATUS_NO_MEMORY;
1154 handle->data = talloc_steal(handle, trusted_domain_state);
1156 trusted_domain_state->access_mask = r->in.access_mask;
1157 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1159 *r->out.trustdom_handle = handle->wire_handle;
1161 return NT_STATUS_OK;
1166 lsa_OpenTrustedDomainByName
1168 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1169 TALLOC_CTX *mem_ctx,
1170 struct lsa_OpenTrustedDomainByName *r)
1172 struct dcesrv_handle *policy_handle;
1174 struct lsa_policy_state *policy_state;
1175 struct lsa_trusted_domain_state *trusted_domain_state;
1176 struct dcesrv_handle *handle;
1177 struct ldb_message **msgs;
1178 const char *attrs[] = {
1184 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1185 ZERO_STRUCTP(r->out.trustdom_handle);
1186 policy_state = policy_handle->data;
1188 if (!r->in.name.string) {
1189 return NT_STATUS_INVALID_PARAMETER;
1192 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1193 if (!trusted_domain_state) {
1194 return NT_STATUS_NO_MEMORY;
1196 trusted_domain_state->policy = policy_state;
1198 /* search for the trusted_domain record */
1199 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1200 mem_ctx, policy_state->system_dn, &msgs, attrs,
1201 "(&(flatname=%s)(objectclass=trustedDomain))",
1202 ldb_binary_encode_string(mem_ctx, r->in.name.string));
1204 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1208 DEBUG(0,("Found %d records matching DN %s\n", ret,
1209 ldb_dn_get_linearized(policy_state->system_dn)));
1210 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1213 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1215 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1217 return NT_STATUS_NO_MEMORY;
1220 handle->data = talloc_steal(handle, trusted_domain_state);
1222 trusted_domain_state->access_mask = r->in.access_mask;
1223 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1225 *r->out.trustdom_handle = handle->wire_handle;
1227 return NT_STATUS_OK;
1233 lsa_SetTrustedDomainInfo
1235 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1236 struct lsa_SetTrustedDomainInfo *r)
1238 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1244 lsa_SetInfomrationTrustedDomain
1246 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1247 TALLOC_CTX *mem_ctx,
1248 struct lsa_SetInformationTrustedDomain *r)
1250 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1255 lsa_DeleteTrustedDomain
1257 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1258 struct lsa_DeleteTrustedDomain *r)
1261 struct lsa_OpenTrustedDomain opn;
1262 struct lsa_DeleteObject del;
1263 struct dcesrv_handle *h;
1265 opn.in.handle = r->in.handle;
1266 opn.in.sid = r->in.dom_sid;
1267 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1268 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1269 if (!opn.out.trustdom_handle) {
1270 return NT_STATUS_NO_MEMORY;
1272 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1273 if (!NT_STATUS_IS_OK(status)) {
1277 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1278 talloc_steal(mem_ctx, h);
1280 del.in.handle = opn.out.trustdom_handle;
1281 del.out.handle = opn.out.trustdom_handle;
1282 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
1283 if (!NT_STATUS_IS_OK(status)) {
1286 return NT_STATUS_OK;
1289 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1290 struct ldb_message *msg,
1291 struct lsa_TrustDomainInfoInfoEx *info_ex)
1293 info_ex->domain_name.string
1294 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1295 info_ex->netbios_name.string
1296 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1298 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1299 info_ex->trust_direction
1300 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1302 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1303 info_ex->trust_attributes
1304 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1305 return NT_STATUS_OK;
1309 lsa_QueryTrustedDomainInfo
1311 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1312 struct lsa_QueryTrustedDomainInfo *r)
1314 union lsa_TrustedDomainInfo *info = NULL;
1315 struct dcesrv_handle *h;
1316 struct lsa_trusted_domain_state *trusted_domain_state;
1317 struct ldb_message *msg;
1319 struct ldb_message **res;
1320 const char *attrs[] = {
1323 "securityIdentifier",
1327 "msDs-supportedEncryptionTypes",
1331 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1333 trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1335 /* pull all the user attributes */
1336 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1337 trusted_domain_state->trusted_domain_dn, &res, attrs);
1339 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1343 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
1345 return NT_STATUS_NO_MEMORY;
1347 *r->out.info = info;
1349 switch (r->in.level) {
1350 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1351 info->name.netbios_name.string
1352 = samdb_result_string(msg, "flatname", NULL);
1354 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1355 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, &info->info_ex);
1369 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1370 ZERO_STRUCT(info->full_info);
1371 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
1373 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1374 ZERO_STRUCT(info->full_info2_internal);
1375 info->full_info2_internal.posix_offset.posix_offset
1376 = samdb_result_uint(msg, "posixOffset", 0);
1377 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
1379 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1380 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 */
1388 *r->out.info = NULL;
1389 return NT_STATUS_INVALID_PARAMETER;
1391 /* oops, we don't want to return the info after all */
1393 *r->out.info = NULL;
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 opn;
1409 struct lsa_QueryTrustedDomainInfo query;
1410 struct dcesrv_handle *h;
1412 opn.in.handle = r->in.handle;
1413 opn.in.sid = r->in.dom_sid;
1414 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1415 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1416 if (!opn.out.trustdom_handle) {
1417 return NT_STATUS_NO_MEMORY;
1419 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1420 if (!NT_STATUS_IS_OK(status)) {
1424 /* Ensure this handle goes away at the end of this call */
1425 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1426 talloc_steal(mem_ctx, h);
1428 query.in.trustdom_handle = opn.out.trustdom_handle;
1429 query.in.level = r->in.level;
1430 query.out.info = r->out.info;
1431 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1432 if (!NT_STATUS_IS_OK(status)) {
1436 return NT_STATUS_OK;
1440 lsa_SetTrustedDomainInfoByName
1442 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1443 TALLOC_CTX *mem_ctx,
1444 struct lsa_SetTrustedDomainInfoByName *r)
1446 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1450 lsa_QueryTrustedDomainInfoByName
1452 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1453 TALLOC_CTX *mem_ctx,
1454 struct lsa_QueryTrustedDomainInfoByName *r)
1457 struct lsa_OpenTrustedDomainByName opn;
1458 struct lsa_QueryTrustedDomainInfo query;
1459 struct dcesrv_handle *h;
1461 opn.in.handle = r->in.handle;
1462 opn.in.name = *r->in.trusted_domain;
1463 opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1464 opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1465 if (!opn.out.trustdom_handle) {
1466 return NT_STATUS_NO_MEMORY;
1468 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
1469 if (!NT_STATUS_IS_OK(status)) {
1473 /* Ensure this handle goes away at the end of this call */
1474 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1475 talloc_steal(mem_ctx, h);
1477 query.in.trustdom_handle = opn.out.trustdom_handle;
1478 query.in.level = r->in.level;
1479 query.out.info = r->out.info;
1480 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1481 if (!NT_STATUS_IS_OK(status)) {
1485 return NT_STATUS_OK;
1489 lsa_CloseTrustedDomainEx
1491 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1492 TALLOC_CTX *mem_ctx,
1493 struct lsa_CloseTrustedDomainEx *r)
1495 /* The result of a bad hair day from an IDL programmer? Not
1496 * implmented in Win2k3. You should always just lsa_Close
1498 return NT_STATUS_NOT_IMPLEMENTED;
1503 comparison function for sorting lsa_DomainInformation array
1505 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1507 return strcasecmp_m(e1->name.string, e2->name.string);
1513 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1514 struct lsa_EnumTrustDom *r)
1516 struct dcesrv_handle *policy_handle;
1517 struct lsa_DomainInfo *entries;
1518 struct lsa_policy_state *policy_state;
1519 struct ldb_message **domains;
1520 const char *attrs[] = {
1522 "securityIdentifier",
1529 *r->out.resume_handle = 0;
1531 r->out.domains->domains = NULL;
1532 r->out.domains->count = 0;
1534 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1536 policy_state = policy_handle->data;
1538 /* search for all users in this domain. This could possibly be cached and
1539 resumed based on resume_key */
1540 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1541 "objectclass=trustedDomain");
1543 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1546 /* convert to lsa_TrustInformation format */
1547 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1549 return NT_STATUS_NO_MEMORY;
1551 for (i=0;i<count;i++) {
1552 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1553 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1556 /* sort the results by name */
1557 qsort(entries, count, sizeof(*entries),
1558 (comparison_fn_t)compare_DomainInfo);
1560 if (*r->in.resume_handle >= count) {
1561 *r->out.resume_handle = -1;
1563 return NT_STATUS_NO_MORE_ENTRIES;
1566 /* return the rest, limit by max_size. Note that we
1567 use the w2k3 element size value of 60 */
1568 r->out.domains->count = count - *r->in.resume_handle;
1569 r->out.domains->count = MIN(r->out.domains->count,
1570 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1572 r->out.domains->domains = entries + *r->in.resume_handle;
1573 r->out.domains->count = r->out.domains->count;
1575 if (r->out.domains->count < count - *r->in.resume_handle) {
1576 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1577 return STATUS_MORE_ENTRIES;
1580 return NT_STATUS_OK;
1584 comparison function for sorting lsa_DomainInformation array
1586 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1588 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1592 lsa_EnumTrustedDomainsEx
1594 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1595 struct lsa_EnumTrustedDomainsEx *r)
1597 struct dcesrv_handle *policy_handle;
1598 struct lsa_TrustDomainInfoInfoEx *entries;
1599 struct lsa_policy_state *policy_state;
1600 struct ldb_message **domains;
1601 const char *attrs[] = {
1604 "securityIdentifier",
1614 *r->out.resume_handle = 0;
1616 r->out.domains->domains = NULL;
1617 r->out.domains->count = 0;
1619 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1621 policy_state = policy_handle->data;
1623 /* search for all users in this domain. This could possibly be cached and
1624 resumed based on resume_key */
1625 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1626 "objectclass=trustedDomain");
1628 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1631 /* convert to lsa_DomainInformation format */
1632 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1634 return NT_STATUS_NO_MEMORY;
1636 for (i=0;i<count;i++) {
1637 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1638 if (!NT_STATUS_IS_OK(nt_status)) {
1643 /* sort the results by name */
1644 qsort(entries, count, sizeof(*entries),
1645 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1647 if (*r->in.resume_handle >= count) {
1648 *r->out.resume_handle = -1;
1650 return NT_STATUS_NO_MORE_ENTRIES;
1653 /* return the rest, limit by max_size. Note that we
1654 use the w2k3 element size value of 60 */
1655 r->out.domains->count = count - *r->in.resume_handle;
1656 r->out.domains->count = MIN(r->out.domains->count,
1657 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1659 r->out.domains->domains = entries + *r->in.resume_handle;
1660 r->out.domains->count = r->out.domains->count;
1662 if (r->out.domains->count < count - *r->in.resume_handle) {
1663 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1664 return STATUS_MORE_ENTRIES;
1667 return NT_STATUS_OK;
1674 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1675 struct lsa_OpenAccount *r)
1677 struct dcesrv_handle *h, *ah;
1678 struct lsa_policy_state *state;
1679 struct lsa_account_state *astate;
1681 ZERO_STRUCTP(r->out.acct_handle);
1683 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1687 astate = talloc(dce_call->conn, struct lsa_account_state);
1688 if (astate == NULL) {
1689 return NT_STATUS_NO_MEMORY;
1692 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1693 if (astate->account_sid == NULL) {
1694 talloc_free(astate);
1695 return NT_STATUS_NO_MEMORY;
1698 astate->policy = talloc_reference(astate, state);
1699 astate->access_mask = r->in.access_mask;
1701 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1703 talloc_free(astate);
1704 return NT_STATUS_NO_MEMORY;
1707 ah->data = talloc_steal(ah, astate);
1709 *r->out.acct_handle = ah->wire_handle;
1711 return NT_STATUS_OK;
1716 lsa_EnumPrivsAccount
1718 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1719 TALLOC_CTX *mem_ctx,
1720 struct lsa_EnumPrivsAccount *r)
1722 struct dcesrv_handle *h;
1723 struct lsa_account_state *astate;
1725 struct ldb_message **res;
1726 const char * const attrs[] = { "privilege", NULL};
1727 struct ldb_message_element *el;
1729 struct lsa_PrivilegeSet *privs;
1731 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1735 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1736 if (privs == NULL) {
1737 return NT_STATUS_NO_MEMORY;
1743 *r->out.privs = privs;
1745 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1746 if (sidstr == NULL) {
1747 return NT_STATUS_NO_MEMORY;
1750 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1751 "objectSid=%s", sidstr);
1753 return NT_STATUS_OK;
1756 el = ldb_msg_find_element(res[0], "privilege");
1757 if (el == NULL || el->num_values == 0) {
1758 return NT_STATUS_OK;
1761 privs->set = talloc_array(privs,
1762 struct lsa_LUIDAttribute, el->num_values);
1763 if (privs->set == NULL) {
1764 return NT_STATUS_NO_MEMORY;
1767 for (i=0;i<el->num_values;i++) {
1768 int id = sec_privilege_id((const char *)el->values[i].data);
1770 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1772 privs->set[i].attribute = 0;
1773 privs->set[i].luid.low = id;
1774 privs->set[i].luid.high = 0;
1777 privs->count = el->num_values;
1779 return NT_STATUS_OK;
1783 lsa_EnumAccountRights
1785 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1786 TALLOC_CTX *mem_ctx,
1787 struct lsa_EnumAccountRights *r)
1789 struct dcesrv_handle *h;
1790 struct lsa_policy_state *state;
1792 struct ldb_message **res;
1793 const char * const attrs[] = { "privilege", NULL};
1795 struct ldb_message_element *el;
1797 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1801 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1802 if (sidstr == NULL) {
1803 return NT_STATUS_NO_MEMORY;
1806 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1807 "(&(objectSid=%s)(privilege=*))", sidstr);
1809 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1812 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1815 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1816 dom_sid_string(mem_ctx, r->in.sid),
1817 ldb_errstring(state->sam_ldb)));
1818 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1821 el = ldb_msg_find_element(res[0], "privilege");
1822 if (el == NULL || el->num_values == 0) {
1823 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1826 r->out.rights->count = el->num_values;
1827 r->out.rights->names = talloc_array(r->out.rights,
1828 struct lsa_StringLarge, r->out.rights->count);
1829 if (r->out.rights->names == NULL) {
1830 return NT_STATUS_NO_MEMORY;
1833 for (i=0;i<el->num_values;i++) {
1834 r->out.rights->names[i].string = (const char *)el->values[i].data;
1837 return NT_STATUS_OK;
1843 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1845 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1846 TALLOC_CTX *mem_ctx,
1847 struct lsa_policy_state *state,
1849 struct dom_sid *sid,
1850 const struct lsa_RightSet *rights)
1853 struct ldb_message *msg;
1854 struct ldb_message_element *el;
1856 struct lsa_EnumAccountRights r2;
1858 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1859 if (sidstr == NULL) {
1860 return NT_STATUS_NO_MEMORY;
1863 msg = ldb_msg_new(mem_ctx);
1865 return NT_STATUS_NO_MEMORY;
1868 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1869 NULL, "objectSid=%s", sidstr);
1870 if (msg->dn == NULL) {
1872 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1873 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1875 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1877 if (!NT_STATUS_IS_OK(status)) {
1880 return NT_STATUS_NO_SUCH_USER;
1883 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1884 return NT_STATUS_NO_MEMORY;
1887 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1890 r2.in.handle = &state->handle->wire_handle;
1892 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1894 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1895 if (!NT_STATUS_IS_OK(status)) {
1896 ZERO_STRUCTP(r2.out.rights);
1900 for (i=0;i<rights->count;i++) {
1901 if (sec_privilege_id(rights->names[i].string) == -1) {
1902 return NT_STATUS_NO_SUCH_PRIVILEGE;
1905 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1907 for (j=0;j<r2.out.rights->count;j++) {
1908 if (strcasecmp_m(r2.out.rights->names[j].string,
1909 rights->names[i].string) == 0) {
1913 if (j != r2.out.rights->count) continue;
1916 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1917 if (ret != LDB_SUCCESS) {
1918 return NT_STATUS_NO_MEMORY;
1922 el = ldb_msg_find_element(msg, "privilege");
1924 return NT_STATUS_OK;
1927 ret = ldb_modify(state->sam_ldb, msg);
1929 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1930 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1932 DEBUG(3, ("Could not %s attributes from %s: %s",
1933 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1934 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1935 return NT_STATUS_UNEXPECTED_IO_ERROR;
1938 return NT_STATUS_OK;
1942 lsa_AddPrivilegesToAccount
1944 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1945 struct lsa_AddPrivilegesToAccount *r)
1947 struct lsa_RightSet rights;
1948 struct dcesrv_handle *h;
1949 struct lsa_account_state *astate;
1952 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1956 rights.count = r->in.privs->count;
1957 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1958 if (rights.names == NULL) {
1959 return NT_STATUS_NO_MEMORY;
1961 for (i=0;i<rights.count;i++) {
1962 int id = r->in.privs->set[i].luid.low;
1963 if (r->in.privs->set[i].luid.high) {
1964 return NT_STATUS_NO_SUCH_PRIVILEGE;
1966 rights.names[i].string = sec_privilege_name(id);
1967 if (rights.names[i].string == NULL) {
1968 return NT_STATUS_NO_SUCH_PRIVILEGE;
1972 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1973 LDB_FLAG_MOD_ADD, astate->account_sid,
1979 lsa_RemovePrivilegesFromAccount
1981 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1982 struct lsa_RemovePrivilegesFromAccount *r)
1984 struct lsa_RightSet *rights;
1985 struct dcesrv_handle *h;
1986 struct lsa_account_state *astate;
1989 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1993 rights = talloc(mem_ctx, struct lsa_RightSet);
1995 if (r->in.remove_all == 1 &&
1996 r->in.privs == NULL) {
1997 struct lsa_EnumAccountRights r2;
2000 r2.in.handle = &astate->policy->handle->wire_handle;
2001 r2.in.sid = astate->account_sid;
2002 r2.out.rights = rights;
2004 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2005 if (!NT_STATUS_IS_OK(status)) {
2009 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2010 LDB_FLAG_MOD_DELETE, astate->account_sid,
2014 if (r->in.remove_all != 0) {
2015 return NT_STATUS_INVALID_PARAMETER;
2018 rights->count = r->in.privs->count;
2019 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2020 if (rights->names == NULL) {
2021 return NT_STATUS_NO_MEMORY;
2023 for (i=0;i<rights->count;i++) {
2024 int id = r->in.privs->set[i].luid.low;
2025 if (r->in.privs->set[i].luid.high) {
2026 return NT_STATUS_NO_SUCH_PRIVILEGE;
2028 rights->names[i].string = sec_privilege_name(id);
2029 if (rights->names[i].string == NULL) {
2030 return NT_STATUS_NO_SUCH_PRIVILEGE;
2034 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2035 LDB_FLAG_MOD_DELETE, astate->account_sid,
2041 lsa_GetQuotasForAccount
2043 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2044 struct lsa_GetQuotasForAccount *r)
2046 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2051 lsa_SetQuotasForAccount
2053 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2054 struct lsa_SetQuotasForAccount *r)
2056 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2061 lsa_GetSystemAccessAccount
2063 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2064 struct lsa_GetSystemAccessAccount *r)
2068 struct lsa_EnumPrivsAccount enumPrivs;
2069 struct lsa_PrivilegeSet *privs;
2071 privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2073 return NT_STATUS_NO_MEMORY;
2079 enumPrivs.in.handle = r->in.handle;
2080 enumPrivs.out.privs = &privs;
2082 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2083 if (!NT_STATUS_IS_OK(status)) {
2087 *(r->out.access_mask) = 0x00000000;
2089 for (i = 0; i < privs->count; i++) {
2090 int priv = privs->set[i].luid.low;
2093 case SEC_PRIV_INTERACTIVE_LOGON:
2094 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2096 case SEC_PRIV_NETWORK_LOGON:
2097 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2099 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2100 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2105 return NT_STATUS_OK;
2110 lsa_SetSystemAccessAccount
2112 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2113 struct lsa_SetSystemAccessAccount *r)
2115 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2122 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2123 struct lsa_CreateSecret *r)
2125 struct dcesrv_handle *policy_handle;
2126 struct lsa_policy_state *policy_state;
2127 struct lsa_secret_state *secret_state;
2128 struct dcesrv_handle *handle;
2129 struct ldb_message **msgs, *msg;
2130 const char *attrs[] = {
2138 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2139 ZERO_STRUCTP(r->out.sec_handle);
2141 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2143 case SECURITY_SYSTEM:
2144 case SECURITY_ADMINISTRATOR:
2147 /* Users and annonymous are not allowed create secrets */
2148 return NT_STATUS_ACCESS_DENIED;
2151 policy_state = policy_handle->data;
2153 if (!r->in.name.string) {
2154 return NT_STATUS_INVALID_PARAMETER;
2157 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2158 if (!secret_state) {
2159 return NT_STATUS_NO_MEMORY;
2161 secret_state->policy = policy_state;
2163 msg = ldb_msg_new(mem_ctx);
2165 return NT_STATUS_NO_MEMORY;
2168 if (strncmp("G$", r->in.name.string, 2) == 0) {
2170 name = &r->in.name.string[2];
2171 /* 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) */
2172 secret_state->sam_ldb = talloc_reference(secret_state,
2173 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)));
2174 secret_state->global = true;
2176 if (strlen(name) < 1) {
2177 return NT_STATUS_INVALID_PARAMETER;
2180 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2181 /* search for the secret record */
2182 ret = gendb_search(secret_state->sam_ldb,
2183 mem_ctx, policy_state->system_dn, &msgs, attrs,
2184 "(&(cn=%s)(objectclass=secret))",
2187 return NT_STATUS_OBJECT_NAME_COLLISION;
2191 DEBUG(0,("Failure searching for CN=%s: %s\n",
2192 name2, ldb_errstring(secret_state->sam_ldb)));
2193 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2196 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2197 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2198 return NT_STATUS_NO_MEMORY;
2201 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2204 secret_state->global = false;
2206 name = r->in.name.string;
2207 if (strlen(name) < 1) {
2208 return NT_STATUS_INVALID_PARAMETER;
2211 secret_state->sam_ldb = talloc_reference(secret_state,
2212 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2213 /* search for the secret record */
2214 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2215 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2217 "(&(cn=%s)(objectclass=secret))",
2218 ldb_binary_encode_string(mem_ctx, name));
2220 return NT_STATUS_OBJECT_NAME_COLLISION;
2224 DEBUG(0,("Failure searching for CN=%s: %s\n",
2225 name, ldb_errstring(secret_state->sam_ldb)));
2226 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2229 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2230 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2233 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2235 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2237 /* create the secret */
2238 ret = ldb_add(secret_state->sam_ldb, msg);
2240 DEBUG(0,("Failed to create secret record %s: %s\n",
2241 ldb_dn_get_linearized(msg->dn),
2242 ldb_errstring(secret_state->sam_ldb)));
2243 return NT_STATUS_ACCESS_DENIED;
2246 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2248 return NT_STATUS_NO_MEMORY;
2251 handle->data = talloc_steal(handle, secret_state);
2253 secret_state->access_mask = r->in.access_mask;
2254 secret_state->policy = talloc_reference(secret_state, policy_state);
2256 *r->out.sec_handle = handle->wire_handle;
2258 return NT_STATUS_OK;
2265 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2266 struct lsa_OpenSecret *r)
2268 struct dcesrv_handle *policy_handle;
2270 struct lsa_policy_state *policy_state;
2271 struct lsa_secret_state *secret_state;
2272 struct dcesrv_handle *handle;
2273 struct ldb_message **msgs;
2274 const char *attrs[] = {
2282 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2283 ZERO_STRUCTP(r->out.sec_handle);
2284 policy_state = policy_handle->data;
2286 if (!r->in.name.string) {
2287 return NT_STATUS_INVALID_PARAMETER;
2290 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2292 case SECURITY_SYSTEM:
2293 case SECURITY_ADMINISTRATOR:
2296 /* Users and annonymous are not allowed to access secrets */
2297 return NT_STATUS_ACCESS_DENIED;
2300 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2301 if (!secret_state) {
2302 return NT_STATUS_NO_MEMORY;
2304 secret_state->policy = policy_state;
2306 if (strncmp("G$", r->in.name.string, 2) == 0) {
2307 name = &r->in.name.string[2];
2308 /* 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) */
2309 secret_state->sam_ldb = talloc_reference(secret_state,
2310 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)));
2311 secret_state->global = true;
2313 if (strlen(name) < 1) {
2314 return NT_STATUS_INVALID_PARAMETER;
2317 /* search for the secret record */
2318 ret = gendb_search(secret_state->sam_ldb,
2319 mem_ctx, policy_state->system_dn, &msgs, attrs,
2320 "(&(cn=%s Secret)(objectclass=secret))",
2321 ldb_binary_encode_string(mem_ctx, name));
2323 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2327 DEBUG(0,("Found %d records matching DN %s\n", ret,
2328 ldb_dn_get_linearized(policy_state->system_dn)));
2329 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2333 secret_state->global = false;
2334 secret_state->sam_ldb = talloc_reference(secret_state,
2335 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2337 name = r->in.name.string;
2338 if (strlen(name) < 1) {
2339 return NT_STATUS_INVALID_PARAMETER;
2342 /* search for the secret record */
2343 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2344 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2346 "(&(cn=%s)(objectclass=secret))",
2347 ldb_binary_encode_string(mem_ctx, name));
2349 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2353 DEBUG(0,("Found %d records matching CN=%s\n",
2354 ret, ldb_binary_encode_string(mem_ctx, name)));
2355 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2359 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2361 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2363 return NT_STATUS_NO_MEMORY;
2366 handle->data = talloc_steal(handle, secret_state);
2368 secret_state->access_mask = r->in.access_mask;
2369 secret_state->policy = talloc_reference(secret_state, policy_state);
2371 *r->out.sec_handle = handle->wire_handle;
2373 return NT_STATUS_OK;
2380 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2381 struct lsa_SetSecret *r)
2384 struct dcesrv_handle *h;
2385 struct lsa_secret_state *secret_state;
2386 struct ldb_message *msg;
2387 DATA_BLOB session_key;
2388 DATA_BLOB crypt_secret, secret;
2391 NTSTATUS status = NT_STATUS_OK;
2393 struct timeval now = timeval_current();
2394 NTTIME nt_now = timeval_to_nttime(&now);
2396 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2398 secret_state = h->data;
2400 msg = ldb_msg_new(mem_ctx);
2402 return NT_STATUS_NO_MEMORY;
2405 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2407 return NT_STATUS_NO_MEMORY;
2409 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2410 if (!NT_STATUS_IS_OK(status)) {
2414 if (r->in.old_val) {
2416 crypt_secret.data = r->in.old_val->data;
2417 crypt_secret.length = r->in.old_val->size;
2419 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2420 if (!NT_STATUS_IS_OK(status)) {
2424 val.data = secret.data;
2425 val.length = secret.length;
2428 if (samdb_msg_add_value(secret_state->sam_ldb,
2429 mem_ctx, msg, "priorValue", &val) != 0) {
2430 return NT_STATUS_NO_MEMORY;
2433 /* set old value mtime */
2434 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2435 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2436 return NT_STATUS_NO_MEMORY;
2440 /* If the old value is not set, then migrate the
2441 * current value to the old value */
2442 const struct ldb_val *old_val;
2443 NTTIME last_set_time;
2444 struct ldb_message **res;
2445 const char *attrs[] = {
2451 /* search for the secret record */
2452 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2453 secret_state->secret_dn, &res, attrs);
2455 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2459 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2460 ldb_dn_get_linearized(secret_state->secret_dn)));
2461 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2464 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2465 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2469 if (samdb_msg_add_value(secret_state->sam_ldb,
2470 mem_ctx, msg, "priorValue",
2472 return NT_STATUS_NO_MEMORY;
2475 if (samdb_msg_add_delete(secret_state->sam_ldb,
2476 mem_ctx, msg, "priorValue")) {
2477 return NT_STATUS_NO_MEMORY;
2482 /* set old value mtime */
2483 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2484 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2485 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2486 return NT_STATUS_NO_MEMORY;
2489 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2490 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2491 return NT_STATUS_NO_MEMORY;
2496 if (r->in.new_val) {
2498 crypt_secret.data = r->in.new_val->data;
2499 crypt_secret.length = r->in.new_val->size;
2501 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2502 if (!NT_STATUS_IS_OK(status)) {
2506 val.data = secret.data;
2507 val.length = secret.length;
2510 if (samdb_msg_add_value(secret_state->sam_ldb,
2511 mem_ctx, msg, "currentValue", &val) != 0) {
2512 return NT_STATUS_NO_MEMORY;
2515 /* set new value mtime */
2516 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2517 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2518 return NT_STATUS_NO_MEMORY;
2522 /* NULL out the NEW value */
2523 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2524 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2525 return NT_STATUS_NO_MEMORY;
2527 if (samdb_msg_add_delete(secret_state->sam_ldb,
2528 mem_ctx, msg, "currentValue")) {
2529 return NT_STATUS_NO_MEMORY;
2533 /* modify the samdb record */
2534 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2536 /* we really need samdb.c to return NTSTATUS */
2537 return NT_STATUS_UNSUCCESSFUL;
2540 return NT_STATUS_OK;
2547 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2548 struct lsa_QuerySecret *r)
2550 struct dcesrv_handle *h;
2551 struct lsa_secret_state *secret_state;
2552 struct ldb_message *msg;
2553 DATA_BLOB session_key;
2554 DATA_BLOB crypt_secret, secret;
2556 struct ldb_message **res;
2557 const char *attrs[] = {
2567 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2569 /* Ensure user is permitted to read this... */
2570 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2572 case SECURITY_SYSTEM:
2573 case SECURITY_ADMINISTRATOR:
2576 /* Users and annonymous are not allowed to read secrets */
2577 return NT_STATUS_ACCESS_DENIED;
2580 secret_state = h->data;
2582 /* pull all the user attributes */
2583 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2584 secret_state->secret_dn, &res, attrs);
2586 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2590 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2591 if (!NT_STATUS_IS_OK(nt_status)) {
2595 if (r->in.old_val) {
2596 const struct ldb_val *prior_val;
2597 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2598 if (!r->out.old_val) {
2599 return NT_STATUS_NO_MEMORY;
2601 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2603 if (prior_val && prior_val->length) {
2604 secret.data = prior_val->data;
2605 secret.length = prior_val->length;
2608 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2609 if (!crypt_secret.length) {
2610 return NT_STATUS_NO_MEMORY;
2612 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2613 if (!r->out.old_val->buf) {
2614 return NT_STATUS_NO_MEMORY;
2616 r->out.old_val->buf->size = crypt_secret.length;
2617 r->out.old_val->buf->length = crypt_secret.length;
2618 r->out.old_val->buf->data = crypt_secret.data;
2622 if (r->in.old_mtime) {
2623 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2624 if (!r->out.old_mtime) {
2625 return NT_STATUS_NO_MEMORY;
2627 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2630 if (r->in.new_val) {
2631 const struct ldb_val *new_val;
2632 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2633 if (!r->out.new_val) {
2634 return NT_STATUS_NO_MEMORY;
2637 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2639 if (new_val && new_val->length) {
2640 secret.data = new_val->data;
2641 secret.length = new_val->length;
2644 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2645 if (!crypt_secret.length) {
2646 return NT_STATUS_NO_MEMORY;
2648 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2649 if (!r->out.new_val->buf) {
2650 return NT_STATUS_NO_MEMORY;
2652 r->out.new_val->buf->length = crypt_secret.length;
2653 r->out.new_val->buf->size = crypt_secret.length;
2654 r->out.new_val->buf->data = crypt_secret.data;
2658 if (r->in.new_mtime) {
2659 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2660 if (!r->out.new_mtime) {
2661 return NT_STATUS_NO_MEMORY;
2663 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2666 return NT_STATUS_OK;
2673 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2674 TALLOC_CTX *mem_ctx,
2675 struct lsa_LookupPrivValue *r)
2677 struct dcesrv_handle *h;
2678 struct lsa_policy_state *state;
2681 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2685 id = sec_privilege_id(r->in.name->string);
2687 return NT_STATUS_NO_SUCH_PRIVILEGE;
2690 r->out.luid->low = id;
2691 r->out.luid->high = 0;
2693 return NT_STATUS_OK;
2700 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2701 TALLOC_CTX *mem_ctx,
2702 struct lsa_LookupPrivName *r)
2704 struct dcesrv_handle *h;
2705 struct lsa_policy_state *state;
2706 struct lsa_StringLarge *name;
2707 const char *privname;
2709 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2713 if (r->in.luid->high != 0) {
2714 return NT_STATUS_NO_SUCH_PRIVILEGE;
2717 privname = sec_privilege_name(r->in.luid->low);
2718 if (privname == NULL) {
2719 return NT_STATUS_NO_SUCH_PRIVILEGE;
2722 name = talloc(mem_ctx, struct lsa_StringLarge);
2724 return NT_STATUS_NO_MEMORY;
2727 name->string = privname;
2729 *r->out.name = name;
2731 return NT_STATUS_OK;
2736 lsa_LookupPrivDisplayName
2738 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2739 TALLOC_CTX *mem_ctx,
2740 struct lsa_LookupPrivDisplayName *r)
2742 struct dcesrv_handle *h;
2743 struct lsa_policy_state *state;
2744 struct lsa_StringLarge *disp_name = NULL;
2747 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2751 id = sec_privilege_id(r->in.name->string);
2753 return NT_STATUS_NO_SUCH_PRIVILEGE;
2756 disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2757 if (disp_name == NULL) {
2758 return NT_STATUS_NO_MEMORY;
2761 disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
2762 if (disp_name->string == NULL) {
2763 return NT_STATUS_INTERNAL_ERROR;
2766 *r->out.disp_name = disp_name;
2767 *r->out.returned_language_id = 0;
2769 return NT_STATUS_OK;
2774 lsa_EnumAccountsWithUserRight
2776 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2777 TALLOC_CTX *mem_ctx,
2778 struct lsa_EnumAccountsWithUserRight *r)
2780 struct dcesrv_handle *h;
2781 struct lsa_policy_state *state;
2783 struct ldb_message **res;
2784 const char * const attrs[] = { "objectSid", NULL};
2785 const char *privname;
2787 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2791 if (r->in.name == NULL) {
2792 return NT_STATUS_NO_SUCH_PRIVILEGE;
2795 privname = r->in.name->string;
2796 if (sec_privilege_id(privname) == -1) {
2797 return NT_STATUS_NO_SUCH_PRIVILEGE;
2800 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2801 "privilege=%s", privname);
2803 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2806 return NT_STATUS_NO_MORE_ENTRIES;
2809 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2810 if (r->out.sids->sids == NULL) {
2811 return NT_STATUS_NO_MEMORY;
2813 for (i=0;i<ret;i++) {
2814 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2815 res[i], "objectSid");
2816 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2818 r->out.sids->num_sids = ret;
2820 return NT_STATUS_OK;
2825 lsa_AddAccountRights
2827 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2828 TALLOC_CTX *mem_ctx,
2829 struct lsa_AddAccountRights *r)
2831 struct dcesrv_handle *h;
2832 struct lsa_policy_state *state;
2834 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2838 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2840 r->in.sid, r->in.rights);
2845 lsa_RemoveAccountRights
2847 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2848 TALLOC_CTX *mem_ctx,
2849 struct lsa_RemoveAccountRights *r)
2851 struct dcesrv_handle *h;
2852 struct lsa_policy_state *state;
2854 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2858 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2859 LDB_FLAG_MOD_DELETE,
2860 r->in.sid, r->in.rights);
2865 lsa_StorePrivateData
2867 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2868 struct lsa_StorePrivateData *r)
2870 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2875 lsa_RetrievePrivateData
2877 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2878 struct lsa_RetrievePrivateData *r)
2880 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2887 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2888 struct lsa_GetUserName *r)
2890 NTSTATUS status = NT_STATUS_OK;
2891 const char *account_name;
2892 const char *authority_name;
2893 struct lsa_String *_account_name;
2894 struct lsa_String *_authority_name = NULL;
2896 /* this is what w2k3 does */
2897 r->out.account_name = r->in.account_name;
2898 r->out.authority_name = r->in.authority_name;
2900 if (r->in.account_name
2901 && *r->in.account_name
2902 /* && *(*r->in.account_name)->string */
2904 return NT_STATUS_INVALID_PARAMETER;
2907 if (r->in.authority_name
2908 && *r->in.authority_name
2909 /* && *(*r->in.authority_name)->string */
2911 return NT_STATUS_INVALID_PARAMETER;
2914 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2915 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2917 _account_name = talloc(mem_ctx, struct lsa_String);
2918 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2919 _account_name->string = account_name;
2921 if (r->in.authority_name) {
2922 _authority_name = talloc(mem_ctx, struct lsa_String);
2923 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2924 _authority_name->string = authority_name;
2927 *r->out.account_name = _account_name;
2928 if (r->out.authority_name) {
2929 *r->out.authority_name = _authority_name;
2938 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2939 TALLOC_CTX *mem_ctx,
2940 struct lsa_SetInfoPolicy2 *r)
2942 /* need to support these */
2943 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2947 lsa_QueryDomainInformationPolicy
2949 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2950 TALLOC_CTX *mem_ctx,
2951 struct lsa_QueryDomainInformationPolicy *r)
2953 union lsa_DomainInformationPolicy *info;
2955 info = talloc(r->out.info, union lsa_DomainInformationPolicy);
2957 return NT_STATUS_NO_MEMORY;
2960 switch (r->in.level) {
2961 case LSA_DOMAIN_INFO_POLICY_EFS:
2963 *r->out.info = NULL;
2964 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2965 case LSA_DOMAIN_INFO_POLICY_KERBEROS:
2967 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
2968 struct smb_krb5_context *smb_krb5_context;
2969 int ret = smb_krb5_init_context(mem_ctx,
2970 dce_call->event_ctx,
2971 dce_call->conn->dce_ctx->lp_ctx,
2975 *r->out.info = NULL;
2976 return NT_STATUS_INTERNAL_ERROR;
2978 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
2979 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2980 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2981 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
2982 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
2983 talloc_free(smb_krb5_context);
2984 *r->out.info = info;
2985 return NT_STATUS_OK;
2989 *r->out.info = NULL;
2990 return NT_STATUS_INVALID_INFO_CLASS;
2995 lsa_SetDomInfoPolicy
2997 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2998 TALLOC_CTX *mem_ctx,
2999 struct lsa_SetDomainInformationPolicy *r)
3001 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3007 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
3008 TALLOC_CTX *mem_ctx,
3009 struct lsa_TestCall *r)
3011 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3017 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3018 struct lsa_CREDRWRITE *r)
3020 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3027 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3028 struct lsa_CREDRREAD *r)
3030 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3037 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3038 struct lsa_CREDRENUMERATE *r)
3040 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3045 lsa_CREDRWRITEDOMAINCREDENTIALS
3047 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3048 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3050 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3055 lsa_CREDRREADDOMAINCREDENTIALS
3057 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3058 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3060 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3067 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3068 struct lsa_CREDRDELETE *r)
3070 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3075 lsa_CREDRGETTARGETINFO
3077 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3078 struct lsa_CREDRGETTARGETINFO *r)
3080 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3085 lsa_CREDRPROFILELOADED
3087 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3088 struct lsa_CREDRPROFILELOADED *r)
3090 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3095 lsa_CREDRGETSESSIONTYPES
3097 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3098 struct lsa_CREDRGETSESSIONTYPES *r)
3100 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3105 lsa_LSARREGISTERAUDITEVENT
3107 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3108 struct lsa_LSARREGISTERAUDITEVENT *r)
3110 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3115 lsa_LSARGENAUDITEVENT
3117 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3118 struct lsa_LSARGENAUDITEVENT *r)
3120 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3125 lsa_LSARUNREGISTERAUDITEVENT
3127 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3128 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3130 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3135 lsa_lsaRQueryForestTrustInformation
3137 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3138 struct lsa_lsaRQueryForestTrustInformation *r)
3140 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3145 lsa_LSARSETFORESTTRUSTINFORMATION
3147 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3148 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3150 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3157 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3158 struct lsa_CREDRRENAME *r)
3160 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3166 lsa_LSAROPENPOLICYSCE
3168 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3169 struct lsa_LSAROPENPOLICYSCE *r)
3171 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3176 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3178 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3179 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3181 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3186 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3188 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3189 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3191 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3196 lsa_LSARADTREPORTSECURITYEVENT
3198 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3199 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3201 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3205 /* include the generated boilerplate */
3206 #include "librpc/gen_ndr/ndr_lsa_s.c"
3210 /*****************************************
3211 NOTE! The remaining calls below were
3212 removed in w2k3, so the DCESRV_FAULT()
3213 replies are the correct implementation. Do
3214 not try and fill these in with anything else
3215 ******************************************/
3218 dssetup_DsRoleDnsNameToFlatName
3220 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3221 struct dssetup_DsRoleDnsNameToFlatName *r)
3223 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3228 dssetup_DsRoleDcAsDc
3230 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3231 struct dssetup_DsRoleDcAsDc *r)
3233 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3238 dssetup_DsRoleDcAsReplica
3240 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3241 struct dssetup_DsRoleDcAsReplica *r)
3243 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3248 dssetup_DsRoleDemoteDc
3250 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3251 struct dssetup_DsRoleDemoteDc *r)
3253 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3258 dssetup_DsRoleGetDcOperationProgress
3260 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3261 struct dssetup_DsRoleGetDcOperationProgress *r)
3263 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3268 dssetup_DsRoleGetDcOperationResults
3270 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3271 struct dssetup_DsRoleGetDcOperationResults *r)
3273 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3278 dssetup_DsRoleCancel
3280 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3281 struct dssetup_DsRoleCancel *r)
3283 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3288 dssetup_DsRoleServerSaveStateForUpgrade
3290 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3291 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3293 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3298 dssetup_DsRoleUpgradeDownlevelServer
3300 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3301 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3303 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3308 dssetup_DsRoleAbortDownlevelServerUpgrade
3310 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3311 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3313 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3317 /* include the generated boilerplate */
3318 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3320 NTSTATUS dcerpc_server_lsa_init(void)
3324 ret = dcerpc_server_dssetup_init();
3325 if (!NT_STATUS_IS_OK(ret)) {
3328 ret = dcerpc_server_lsarpc_init();
3329 if (!NT_STATUS_IS_OK(ret)) {