2 Unix SMB/CIFS implementation.
4 endpoint server for the lsarpc pipe
6 Copyright (C) Andrew Tridgell 2004
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2007
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "rpc_server/lsa/lsa.h"
24 #include "util/util_ldb.h"
25 #include "libcli/ldap/ldap_ndr.h"
28 this type allows us to distinguish handle types
32 state associated with a lsa_OpenAccount() operation
34 struct lsa_account_state {
35 struct lsa_policy_state *policy;
37 struct dom_sid *account_sid;
42 state associated with a lsa_OpenSecret() operation
44 struct lsa_secret_state {
45 struct lsa_policy_state *policy;
47 struct ldb_dn *secret_dn;
48 struct ldb_context *sam_ldb;
53 state associated with a lsa_OpenTrustedDomain() operation
55 struct lsa_trusted_domain_state {
56 struct lsa_policy_state *policy;
58 struct ldb_dn *trusted_domain_dn;
61 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
63 struct lsa_EnumAccountRights *r);
65 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
67 struct lsa_policy_state *state,
70 const struct lsa_RightSet *rights);
75 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
78 struct dcesrv_handle *h;
80 *r->out.handle = *r->in.handle;
82 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
86 ZERO_STRUCTP(r->out.handle);
95 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
98 return NT_STATUS_NOT_SUPPORTED;
105 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
106 struct lsa_DeleteObject *r)
108 struct dcesrv_handle *h;
111 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
113 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
114 struct lsa_secret_state *secret_state = h->data;
116 /* Ensure user is permitted to delete this... */
117 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
119 case SECURITY_SYSTEM:
120 case SECURITY_ADMINISTRATOR:
123 /* Users and annonymous are not allowed delete things */
124 return NT_STATUS_ACCESS_DENIED;
127 ret = ldb_delete(secret_state->sam_ldb,
128 secret_state->secret_dn);
131 return NT_STATUS_INVALID_HANDLE;
134 ZERO_STRUCTP(r->out.handle);
137 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
138 struct lsa_trusted_domain_state *trusted_domain_state = h->data;
139 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
140 trusted_domain_state->trusted_domain_dn);
143 return NT_STATUS_INVALID_HANDLE;
146 ZERO_STRUCTP(r->out.handle);
149 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
150 struct lsa_RightSet *rights;
151 struct lsa_account_state *astate;
152 struct lsa_EnumAccountRights r2;
155 rights = talloc(mem_ctx, struct lsa_RightSet);
157 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
161 r2.in.handle = &astate->policy->handle->wire_handle;
162 r2.in.sid = astate->account_sid;
163 r2.out.rights = rights;
165 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
166 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
170 if (!NT_STATUS_IS_OK(status)) {
174 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
175 LDB_FLAG_MOD_DELETE, astate->account_sid,
177 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
181 if (!NT_STATUS_IS_OK(status)) {
185 ZERO_STRUCTP(r->out.handle);
188 return NT_STATUS_INVALID_HANDLE;
195 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
196 struct lsa_EnumPrivs *r)
198 struct dcesrv_handle *h;
199 struct lsa_policy_state *state;
201 const char *privname;
203 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
207 i = *r->in.resume_handle;
210 while ((privname = sec_privilege_name(i)) &&
211 r->out.privs->count < r->in.max_count) {
212 struct lsa_PrivEntry *e;
214 r->out.privs->privs = talloc_realloc(r->out.privs,
216 struct lsa_PrivEntry,
217 r->out.privs->count+1);
218 if (r->out.privs->privs == NULL) {
219 return NT_STATUS_NO_MEMORY;
221 e = &r->out.privs->privs[r->out.privs->count];
224 e->name.string = privname;
225 r->out.privs->count++;
229 *r->out.resume_handle = i;
238 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
239 struct lsa_QuerySecurity *r)
241 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
248 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
249 struct lsa_SetSecObj *r)
251 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
258 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
259 struct lsa_ChangePassword *r)
261 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
265 dssetup_DsRoleGetPrimaryDomainInformation
267 This is not an LSA call, but is the only call left on the DSSETUP
268 pipe (after the pipe was truncated), and needs lsa_get_policy_state
270 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
272 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
274 union dssetup_DsRoleInfo *info;
276 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
277 W_ERROR_HAVE_NO_MEMORY(info);
279 switch (r->in.level) {
280 case DS_ROLE_BASIC_INFORMATION:
282 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
284 const char *domain = NULL;
285 const char *dns_domain = NULL;
286 const char *forest = NULL;
287 struct GUID domain_guid;
288 struct lsa_policy_state *state;
290 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
291 if (!NT_STATUS_IS_OK(status)) {
292 return ntstatus_to_werror(status);
295 ZERO_STRUCT(domain_guid);
297 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
298 case ROLE_STANDALONE:
299 role = DS_ROLE_STANDALONE_SERVER;
301 case ROLE_DOMAIN_MEMBER:
302 role = DS_ROLE_MEMBER_SERVER;
304 case ROLE_DOMAIN_CONTROLLER:
305 if (samdb_is_pdc(state->sam_ldb)) {
306 role = DS_ROLE_PRIMARY_DC;
308 role = DS_ROLE_BACKUP_DC;
313 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
314 case ROLE_STANDALONE:
315 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
316 W_ERROR_HAVE_NO_MEMORY(domain);
318 case ROLE_DOMAIN_MEMBER:
319 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
320 W_ERROR_HAVE_NO_MEMORY(domain);
321 /* TODO: what is with dns_domain and forest and guid? */
323 case ROLE_DOMAIN_CONTROLLER:
324 flags = DS_ROLE_PRIMARY_DS_RUNNING;
326 if (state->mixed_domain == 1) {
327 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
330 domain = state->domain_name;
331 dns_domain = state->domain_dns;
332 forest = state->forest_dns;
334 domain_guid = state->domain_guid;
335 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
339 info->basic.role = role;
340 info->basic.flags = flags;
341 info->basic.domain = domain;
342 info->basic.dns_domain = dns_domain;
343 info->basic.forest = forest;
344 info->basic.domain_guid = domain_guid;
349 case DS_ROLE_UPGRADE_STATUS:
351 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
352 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
357 case DS_ROLE_OP_STATUS:
359 info->opstatus.status = DS_ROLE_OP_IDLE;
365 return WERR_INVALID_PARAM;
368 return WERR_INVALID_PARAM;
373 fill in the AccountDomain info
375 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
376 struct lsa_DomainInfo *info)
378 info->name.string = state->domain_name;
379 info->sid = state->domain_sid;
385 fill in the DNS domain info
387 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
388 struct lsa_DnsDomainInfo *info)
390 info->name.string = state->domain_name;
391 info->sid = state->domain_sid;
392 info->dns_domain.string = state->domain_dns;
393 info->dns_forest.string = state->forest_dns;
394 info->domain_guid = state->domain_guid;
402 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
403 struct lsa_QueryInfoPolicy2 *r)
405 struct lsa_policy_state *state;
406 struct dcesrv_handle *h;
410 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
414 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
416 return NT_STATUS_NO_MEMORY;
419 ZERO_STRUCTP(r->out.info);
421 switch (r->in.level) {
422 case LSA_POLICY_INFO_DOMAIN:
423 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
424 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
426 case LSA_POLICY_INFO_DNS:
427 return dcesrv_lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
428 case LSA_POLICY_INFO_DB:
429 case LSA_POLICY_INFO_AUDIT_FULL_SET:
430 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
431 return NT_STATUS_INVALID_PARAMETER;
434 return NT_STATUS_INVALID_INFO_CLASS;
440 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
441 struct lsa_QueryInfoPolicy *r)
443 struct lsa_QueryInfoPolicy2 r2;
446 r2.in.handle = r->in.handle;
447 r2.in.level = r->in.level;
449 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
451 r->out.info = r2.out.info;
459 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
460 struct lsa_SetInfoPolicy *r)
462 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
469 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
470 struct lsa_ClearAuditLog *r)
472 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
479 This call does not seem to have any long-term effects, hence no database operations
481 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
482 struct lsa_CreateAccount *r)
484 struct lsa_account_state *astate;
486 struct lsa_policy_state *state;
487 struct dcesrv_handle *h, *ah;
489 ZERO_STRUCTP(r->out.acct_handle);
491 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
495 astate = talloc(dce_call->conn, struct lsa_account_state);
496 if (astate == NULL) {
497 return NT_STATUS_NO_MEMORY;
500 astate->account_sid = dom_sid_dup(astate, r->in.sid);
501 if (astate->account_sid == NULL) {
503 return NT_STATUS_NO_MEMORY;
506 astate->policy = talloc_reference(astate, state);
507 astate->access_mask = r->in.access_mask;
509 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
512 return NT_STATUS_NO_MEMORY;
515 ah->data = talloc_steal(ah, astate);
517 *r->out.acct_handle = ah->wire_handle;
526 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
527 struct lsa_EnumAccounts *r)
529 struct dcesrv_handle *h;
530 struct lsa_policy_state *state;
532 struct ldb_message **res;
533 const char * const attrs[] = { "objectSid", NULL};
536 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
540 /* NOTE: This call must only return accounts that have at least
543 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
544 "(&(objectSid=*)(privilege=*))");
546 return NT_STATUS_NO_SUCH_USER;
549 if (*r->in.resume_handle >= ret) {
550 return NT_STATUS_NO_MORE_ENTRIES;
553 count = ret - *r->in.resume_handle;
554 if (count > r->in.num_entries) {
555 count = r->in.num_entries;
559 return NT_STATUS_NO_MORE_ENTRIES;
562 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
563 if (r->out.sids->sids == NULL) {
564 return NT_STATUS_NO_MEMORY;
567 for (i=0;i<count;i++) {
568 r->out.sids->sids[i].sid =
569 samdb_result_dom_sid(r->out.sids->sids,
570 res[i + *r->in.resume_handle],
572 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
575 r->out.sids->num_sids = count;
576 *r->out.resume_handle = count + *r->in.resume_handle;
584 lsa_CreateTrustedDomainEx2
586 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
588 struct lsa_CreateTrustedDomainEx2 *r)
590 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
594 lsa_CreateTrustedDomainEx
596 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
598 struct lsa_CreateTrustedDomainEx *r)
600 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
604 lsa_CreateTrustedDomain
606 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
607 struct lsa_CreateTrustedDomain *r)
609 struct dcesrv_handle *policy_handle;
610 struct lsa_policy_state *policy_state;
611 struct lsa_trusted_domain_state *trusted_domain_state;
612 struct dcesrv_handle *handle;
613 struct ldb_message **msgs, *msg;
614 const char *attrs[] = {
620 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
621 ZERO_STRUCTP(r->out.trustdom_handle);
623 policy_state = policy_handle->data;
625 if (!r->in.info->name.string) {
626 return NT_STATUS_INVALID_PARAMETER;
628 name = r->in.info->name.string;
630 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
631 if (!trusted_domain_state) {
632 return NT_STATUS_NO_MEMORY;
634 trusted_domain_state->policy = policy_state;
636 msg = ldb_msg_new(mem_ctx);
638 return NT_STATUS_NO_MEMORY;
641 /* search for the trusted_domain record */
642 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
643 mem_ctx, policy_state->system_dn, &msgs, attrs,
644 "(&(cn=%s)(objectclass=trustedDomain))",
645 ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
647 return NT_STATUS_OBJECT_NAME_COLLISION;
650 if (ret < 0 || ret > 1) {
651 DEBUG(0,("Found %d records matching DN %s\n", ret,
652 ldb_dn_get_linearized(policy_state->system_dn)));
653 return NT_STATUS_INTERNAL_DB_CORRUPTION;
656 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
657 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
658 return NT_STATUS_NO_MEMORY;
661 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
663 if (r->in.info->sid) {
664 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
666 return NT_STATUS_NO_MEMORY;
669 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
672 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
674 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
676 /* create the trusted_domain */
677 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
681 case LDB_ERR_ENTRY_ALREADY_EXISTS:
682 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
683 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
684 ldb_dn_get_linearized(msg->dn),
685 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
686 return NT_STATUS_DOMAIN_EXISTS;
687 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
688 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
689 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
690 ldb_dn_get_linearized(msg->dn),
691 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
692 return NT_STATUS_ACCESS_DENIED;
694 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
695 DEBUG(0,("Failed to create user record %s: %s\n",
696 ldb_dn_get_linearized(msg->dn),
697 ldb_errstring(trusted_domain_state->policy->sam_ldb)));
698 return NT_STATUS_INTERNAL_DB_CORRUPTION;
701 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
703 return NT_STATUS_NO_MEMORY;
706 handle->data = talloc_steal(handle, trusted_domain_state);
708 trusted_domain_state->access_mask = r->in.access_mask;
709 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
711 *r->out.trustdom_handle = handle->wire_handle;
717 lsa_OpenTrustedDomain
719 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
720 struct lsa_OpenTrustedDomain *r)
722 struct dcesrv_handle *policy_handle;
724 struct lsa_policy_state *policy_state;
725 struct lsa_trusted_domain_state *trusted_domain_state;
726 struct dcesrv_handle *handle;
727 struct ldb_message **msgs;
728 const char *attrs[] = {
732 const char *sid_string;
735 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
736 ZERO_STRUCTP(r->out.trustdom_handle);
737 policy_state = policy_handle->data;
739 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
740 if (!trusted_domain_state) {
741 return NT_STATUS_NO_MEMORY;
743 trusted_domain_state->policy = policy_state;
745 sid_string = dom_sid_string(mem_ctx, r->in.sid);
747 return NT_STATUS_NO_MEMORY;
750 /* search for the trusted_domain record */
751 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
752 mem_ctx, policy_state->system_dn, &msgs, attrs,
753 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
756 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
760 DEBUG(0,("Found %d records matching DN %s\n", ret,
761 ldb_dn_get_linearized(policy_state->system_dn)));
762 return NT_STATUS_INTERNAL_DB_CORRUPTION;
765 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
767 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
769 return NT_STATUS_NO_MEMORY;
772 handle->data = talloc_steal(handle, trusted_domain_state);
774 trusted_domain_state->access_mask = r->in.access_mask;
775 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
777 *r->out.trustdom_handle = handle->wire_handle;
784 lsa_OpenTrustedDomainByName
786 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
788 struct lsa_OpenTrustedDomainByName *r)
790 struct dcesrv_handle *policy_handle;
792 struct lsa_policy_state *policy_state;
793 struct lsa_trusted_domain_state *trusted_domain_state;
794 struct dcesrv_handle *handle;
795 struct ldb_message **msgs;
796 const char *attrs[] = {
802 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
803 ZERO_STRUCTP(r->out.trustdom_handle);
804 policy_state = policy_handle->data;
806 if (!r->in.name.string) {
807 return NT_STATUS_INVALID_PARAMETER;
810 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
811 if (!trusted_domain_state) {
812 return NT_STATUS_NO_MEMORY;
814 trusted_domain_state->policy = policy_state;
816 /* search for the trusted_domain record */
817 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
818 mem_ctx, policy_state->system_dn, &msgs, attrs,
819 "(&(flatname=%s)(objectclass=trustedDomain))",
820 ldb_binary_encode_string(mem_ctx, r->in.name.string));
822 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
826 DEBUG(0,("Found %d records matching DN %s\n", ret,
827 ldb_dn_get_linearized(policy_state->system_dn)));
828 return NT_STATUS_INTERNAL_DB_CORRUPTION;
831 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
833 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
835 return NT_STATUS_NO_MEMORY;
838 handle->data = talloc_steal(handle, trusted_domain_state);
840 trusted_domain_state->access_mask = r->in.access_mask;
841 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
843 *r->out.trustdom_handle = handle->wire_handle;
851 lsa_SetTrustedDomainInfo
853 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
854 struct lsa_SetTrustedDomainInfo *r)
856 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
862 lsa_SetInfomrationTrustedDomain
864 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
866 struct lsa_SetInformationTrustedDomain *r)
868 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
873 lsa_DeleteTrustedDomain
875 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
876 struct lsa_DeleteTrustedDomain *r)
879 struct lsa_OpenTrustedDomain open;
880 struct lsa_DeleteObject delete;
881 struct dcesrv_handle *h;
883 open.in.handle = r->in.handle;
884 open.in.sid = r->in.dom_sid;
885 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
886 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
887 if (!open.out.trustdom_handle) {
888 return NT_STATUS_NO_MEMORY;
890 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
891 if (!NT_STATUS_IS_OK(status)) {
895 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
896 talloc_steal(mem_ctx, h);
898 delete.in.handle = open.out.trustdom_handle;
899 delete.out.handle = open.out.trustdom_handle;
900 status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &delete);
901 if (!NT_STATUS_IS_OK(status)) {
907 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
908 struct ldb_message *msg,
909 struct lsa_TrustDomainInfoInfoEx *info_ex)
911 info_ex->domain_name.string
912 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
913 info_ex->netbios_name.string
914 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
916 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
917 info_ex->trust_direction
918 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
920 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
921 info_ex->trust_attributes
922 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
927 lsa_QueryTrustedDomainInfo
929 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
930 struct lsa_QueryTrustedDomainInfo *r)
932 struct dcesrv_handle *h;
933 struct lsa_trusted_domain_state *trusted_domain_state;
934 struct ldb_message *msg;
936 struct ldb_message **res;
937 const char *attrs[] = {
940 "securityIdentifier",
944 "msDs-supportedEncryptionTypes",
948 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
950 trusted_domain_state = h->data;
952 /* pull all the user attributes */
953 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
954 trusted_domain_state->trusted_domain_dn, &res, attrs);
956 return NT_STATUS_INTERNAL_DB_CORRUPTION;
960 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
962 return NT_STATUS_NO_MEMORY;
964 switch (r->in.level) {
965 case LSA_TRUSTED_DOMAIN_INFO_NAME:
966 r->out.info->name.netbios_name.string
967 = samdb_result_string(msg, "flatname", NULL);
969 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
970 r->out.info->posix_offset.posix_offset
971 = samdb_result_uint(msg, "posixOffset", 0);
973 #if 0 /* Win2k3 doesn't implement this */
974 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
975 r->out.info->info_basic.netbios_name.string
976 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
977 r->out.info->info_basic.sid
978 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
981 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
982 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
984 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
985 ZERO_STRUCT(r->out.info->full_info);
986 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
988 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
989 ZERO_STRUCT(r->out.info->info2_internal);
990 r->out.info->info2_internal.posix_offset.posix_offset
991 = samdb_result_uint(msg, "posixOffset", 0);
992 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info2_internal.info_ex);
994 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
995 r->out.info->enc_types.enc_types
996 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
999 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1000 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1001 /* oops, we don't want to return the info after all */
1002 talloc_free(r->out.info);
1004 return NT_STATUS_INVALID_PARAMETER;
1006 /* oops, we don't want to return the info after all */
1007 talloc_free(r->out.info);
1009 return NT_STATUS_INVALID_INFO_CLASS;
1012 return NT_STATUS_OK;
1017 lsa_QueryTrustedDomainInfoBySid
1019 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1020 struct lsa_QueryTrustedDomainInfoBySid *r)
1023 struct lsa_OpenTrustedDomain open;
1024 struct lsa_QueryTrustedDomainInfo query;
1025 struct dcesrv_handle *h;
1026 open.in.handle = r->in.handle;
1027 open.in.sid = r->in.dom_sid;
1028 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1029 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1030 if (!open.out.trustdom_handle) {
1031 return NT_STATUS_NO_MEMORY;
1033 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1034 if (!NT_STATUS_IS_OK(status)) {
1038 /* Ensure this handle goes away at the end of this call */
1039 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1040 talloc_steal(mem_ctx, h);
1042 query.in.trustdom_handle = open.out.trustdom_handle;
1043 query.in.level = r->in.level;
1044 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1045 if (!NT_STATUS_IS_OK(status)) {
1049 r->out.info = query.out.info;
1050 return NT_STATUS_OK;
1054 lsa_SetTrustedDomainInfoByName
1056 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1057 TALLOC_CTX *mem_ctx,
1058 struct lsa_SetTrustedDomainInfoByName *r)
1060 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1064 lsa_QueryTrustedDomainInfoByName
1066 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1067 TALLOC_CTX *mem_ctx,
1068 struct lsa_QueryTrustedDomainInfoByName *r)
1071 struct lsa_OpenTrustedDomainByName open;
1072 struct lsa_QueryTrustedDomainInfo query;
1073 struct dcesrv_handle *h;
1074 open.in.handle = r->in.handle;
1075 open.in.name = r->in.trusted_domain;
1076 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1077 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1078 if (!open.out.trustdom_handle) {
1079 return NT_STATUS_NO_MEMORY;
1081 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1082 if (!NT_STATUS_IS_OK(status)) {
1086 /* Ensure this handle goes away at the end of this call */
1087 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1088 talloc_steal(mem_ctx, h);
1090 query.in.trustdom_handle = open.out.trustdom_handle;
1091 query.in.level = r->in.level;
1092 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1093 if (!NT_STATUS_IS_OK(status)) {
1097 r->out.info = query.out.info;
1098 return NT_STATUS_OK;
1102 lsa_CloseTrustedDomainEx
1104 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1105 TALLOC_CTX *mem_ctx,
1106 struct lsa_CloseTrustedDomainEx *r)
1108 /* The result of a bad hair day from an IDL programmer? Not
1109 * implmented in Win2k3. You should always just lsa_Close
1111 return NT_STATUS_NOT_IMPLEMENTED;
1116 comparison function for sorting lsa_DomainInformation array
1118 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1120 return strcasecmp_m(e1->name.string, e2->name.string);
1126 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1127 struct lsa_EnumTrustDom *r)
1129 struct dcesrv_handle *policy_handle;
1130 struct lsa_DomainInfo *entries;
1131 struct lsa_policy_state *policy_state;
1132 struct ldb_message **domains;
1133 const char *attrs[] = {
1135 "securityIdentifier",
1142 *r->out.resume_handle = 0;
1144 r->out.domains->domains = NULL;
1145 r->out.domains->count = 0;
1147 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1149 policy_state = policy_handle->data;
1151 /* search for all users in this domain. This could possibly be cached and
1152 resumed based on resume_key */
1153 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1154 "objectclass=trustedDomain");
1156 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1159 /* convert to lsa_TrustInformation format */
1160 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1162 return NT_STATUS_NO_MEMORY;
1164 for (i=0;i<count;i++) {
1165 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1166 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1169 /* sort the results by name */
1170 qsort(entries, count, sizeof(*entries),
1171 (comparison_fn_t)compare_DomainInfo);
1173 if (*r->in.resume_handle >= count) {
1174 *r->out.resume_handle = -1;
1176 return NT_STATUS_NO_MORE_ENTRIES;
1179 /* return the rest, limit by max_size. Note that we
1180 use the w2k3 element size value of 60 */
1181 r->out.domains->count = count - *r->in.resume_handle;
1182 r->out.domains->count = MIN(r->out.domains->count,
1183 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1185 r->out.domains->domains = entries + *r->in.resume_handle;
1186 r->out.domains->count = r->out.domains->count;
1188 if (r->out.domains->count < count - *r->in.resume_handle) {
1189 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1190 return STATUS_MORE_ENTRIES;
1193 return NT_STATUS_OK;
1197 comparison function for sorting lsa_DomainInformation array
1199 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1201 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1205 lsa_EnumTrustedDomainsEx
1207 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1208 struct lsa_EnumTrustedDomainsEx *r)
1210 struct dcesrv_handle *policy_handle;
1211 struct lsa_TrustDomainInfoInfoEx *entries;
1212 struct lsa_policy_state *policy_state;
1213 struct ldb_message **domains;
1214 const char *attrs[] = {
1217 "securityIdentifier",
1227 *r->out.resume_handle = 0;
1229 r->out.domains->domains = NULL;
1230 r->out.domains->count = 0;
1232 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1234 policy_state = policy_handle->data;
1236 /* search for all users in this domain. This could possibly be cached and
1237 resumed based on resume_key */
1238 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1239 "objectclass=trustedDomain");
1241 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1244 /* convert to lsa_DomainInformation format */
1245 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1247 return NT_STATUS_NO_MEMORY;
1249 for (i=0;i<count;i++) {
1250 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1251 if (!NT_STATUS_IS_OK(nt_status)) {
1256 /* sort the results by name */
1257 qsort(entries, count, sizeof(*entries),
1258 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1260 if (*r->in.resume_handle >= count) {
1261 *r->out.resume_handle = -1;
1263 return NT_STATUS_NO_MORE_ENTRIES;
1266 /* return the rest, limit by max_size. Note that we
1267 use the w2k3 element size value of 60 */
1268 r->out.domains->count = count - *r->in.resume_handle;
1269 r->out.domains->count = MIN(r->out.domains->count,
1270 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1272 r->out.domains->domains = entries + *r->in.resume_handle;
1273 r->out.domains->count = r->out.domains->count;
1275 if (r->out.domains->count < count - *r->in.resume_handle) {
1276 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1277 return STATUS_MORE_ENTRIES;
1280 return NT_STATUS_OK;
1287 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1288 struct lsa_OpenAccount *r)
1290 struct dcesrv_handle *h, *ah;
1291 struct lsa_policy_state *state;
1292 struct lsa_account_state *astate;
1294 ZERO_STRUCTP(r->out.acct_handle);
1296 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1300 astate = talloc(dce_call->conn, struct lsa_account_state);
1301 if (astate == NULL) {
1302 return NT_STATUS_NO_MEMORY;
1305 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1306 if (astate->account_sid == NULL) {
1307 talloc_free(astate);
1308 return NT_STATUS_NO_MEMORY;
1311 astate->policy = talloc_reference(astate, state);
1312 astate->access_mask = r->in.access_mask;
1314 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1316 talloc_free(astate);
1317 return NT_STATUS_NO_MEMORY;
1320 ah->data = talloc_steal(ah, astate);
1322 *r->out.acct_handle = ah->wire_handle;
1324 return NT_STATUS_OK;
1329 lsa_EnumPrivsAccount
1331 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1332 TALLOC_CTX *mem_ctx,
1333 struct lsa_EnumPrivsAccount *r)
1335 struct dcesrv_handle *h;
1336 struct lsa_account_state *astate;
1338 struct ldb_message **res;
1339 const char * const attrs[] = { "privilege", NULL};
1340 struct ldb_message_element *el;
1343 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1347 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1348 r->out.privs->count = 0;
1349 r->out.privs->unknown = 0;
1350 r->out.privs->set = NULL;
1352 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1353 if (sidstr == NULL) {
1354 return NT_STATUS_NO_MEMORY;
1357 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1358 "objectSid=%s", sidstr);
1360 return NT_STATUS_OK;
1363 el = ldb_msg_find_element(res[0], "privilege");
1364 if (el == NULL || el->num_values == 0) {
1365 return NT_STATUS_OK;
1368 r->out.privs->set = talloc_array(r->out.privs,
1369 struct lsa_LUIDAttribute, el->num_values);
1370 if (r->out.privs->set == NULL) {
1371 return NT_STATUS_NO_MEMORY;
1374 for (i=0;i<el->num_values;i++) {
1375 int id = sec_privilege_id((const char *)el->values[i].data);
1377 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1379 r->out.privs->set[i].attribute = 0;
1380 r->out.privs->set[i].luid.low = id;
1381 r->out.privs->set[i].luid.high = 0;
1384 r->out.privs->count = el->num_values;
1386 return NT_STATUS_OK;
1390 lsa_EnumAccountRights
1392 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1393 TALLOC_CTX *mem_ctx,
1394 struct lsa_EnumAccountRights *r)
1396 struct dcesrv_handle *h;
1397 struct lsa_policy_state *state;
1399 struct ldb_message **res;
1400 const char * const attrs[] = { "privilege", NULL};
1402 struct ldb_message_element *el;
1404 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1408 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1409 if (sidstr == NULL) {
1410 return NT_STATUS_NO_MEMORY;
1413 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1414 "(&(objectSid=%s)(privilege=*))", sidstr);
1416 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1419 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1422 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1423 dom_sid_string(mem_ctx, r->in.sid),
1424 ldb_errstring(state->sam_ldb)));
1425 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1428 el = ldb_msg_find_element(res[0], "privilege");
1429 if (el == NULL || el->num_values == 0) {
1430 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1433 r->out.rights->count = el->num_values;
1434 r->out.rights->names = talloc_array(r->out.rights,
1435 struct lsa_StringLarge, r->out.rights->count);
1436 if (r->out.rights->names == NULL) {
1437 return NT_STATUS_NO_MEMORY;
1440 for (i=0;i<el->num_values;i++) {
1441 r->out.rights->names[i].string = (const char *)el->values[i].data;
1444 return NT_STATUS_OK;
1450 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1452 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1453 TALLOC_CTX *mem_ctx,
1454 struct lsa_policy_state *state,
1456 struct dom_sid *sid,
1457 const struct lsa_RightSet *rights)
1460 struct ldb_message *msg;
1461 struct ldb_message_element *el;
1463 struct lsa_EnumAccountRights r2;
1465 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1466 if (sidstr == NULL) {
1467 return NT_STATUS_NO_MEMORY;
1470 msg = ldb_msg_new(mem_ctx);
1472 return NT_STATUS_NO_MEMORY;
1475 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1476 NULL, "objectSid=%s", sidstr);
1477 if (msg->dn == NULL) {
1479 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1480 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1482 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1484 if (!NT_STATUS_IS_OK(status)) {
1487 return NT_STATUS_NO_SUCH_USER;
1490 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1491 return NT_STATUS_NO_MEMORY;
1494 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1497 r2.in.handle = &state->handle->wire_handle;
1499 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1501 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1502 if (!NT_STATUS_IS_OK(status)) {
1503 ZERO_STRUCTP(r2.out.rights);
1507 for (i=0;i<rights->count;i++) {
1508 if (sec_privilege_id(rights->names[i].string) == -1) {
1509 return NT_STATUS_NO_SUCH_PRIVILEGE;
1512 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1514 for (j=0;j<r2.out.rights->count;j++) {
1515 if (strcasecmp_m(r2.out.rights->names[j].string,
1516 rights->names[i].string) == 0) {
1520 if (j != r2.out.rights->count) continue;
1523 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1524 if (ret != LDB_SUCCESS) {
1525 return NT_STATUS_NO_MEMORY;
1529 el = ldb_msg_find_element(msg, "privilege");
1531 return NT_STATUS_OK;
1534 ret = ldb_modify(state->sam_ldb, msg);
1536 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1537 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1539 DEBUG(3, ("Could not %s attributes from %s: %s",
1540 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1541 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1542 return NT_STATUS_UNEXPECTED_IO_ERROR;
1545 return NT_STATUS_OK;
1549 lsa_AddPrivilegesToAccount
1551 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1552 struct lsa_AddPrivilegesToAccount *r)
1554 struct lsa_RightSet rights;
1555 struct dcesrv_handle *h;
1556 struct lsa_account_state *astate;
1559 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1563 rights.count = r->in.privs->count;
1564 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1565 if (rights.names == NULL) {
1566 return NT_STATUS_NO_MEMORY;
1568 for (i=0;i<rights.count;i++) {
1569 int id = r->in.privs->set[i].luid.low;
1570 if (r->in.privs->set[i].luid.high) {
1571 return NT_STATUS_NO_SUCH_PRIVILEGE;
1573 rights.names[i].string = sec_privilege_name(id);
1574 if (rights.names[i].string == NULL) {
1575 return NT_STATUS_NO_SUCH_PRIVILEGE;
1579 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1580 LDB_FLAG_MOD_ADD, astate->account_sid,
1586 lsa_RemovePrivilegesFromAccount
1588 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1589 struct lsa_RemovePrivilegesFromAccount *r)
1591 struct lsa_RightSet *rights;
1592 struct dcesrv_handle *h;
1593 struct lsa_account_state *astate;
1596 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1600 rights = talloc(mem_ctx, struct lsa_RightSet);
1602 if (r->in.remove_all == 1 &&
1603 r->in.privs == NULL) {
1604 struct lsa_EnumAccountRights r2;
1607 r2.in.handle = &astate->policy->handle->wire_handle;
1608 r2.in.sid = astate->account_sid;
1609 r2.out.rights = rights;
1611 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1612 if (!NT_STATUS_IS_OK(status)) {
1616 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1617 LDB_FLAG_MOD_DELETE, astate->account_sid,
1621 if (r->in.remove_all != 0) {
1622 return NT_STATUS_INVALID_PARAMETER;
1625 rights->count = r->in.privs->count;
1626 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
1627 if (rights->names == NULL) {
1628 return NT_STATUS_NO_MEMORY;
1630 for (i=0;i<rights->count;i++) {
1631 int id = r->in.privs->set[i].luid.low;
1632 if (r->in.privs->set[i].luid.high) {
1633 return NT_STATUS_NO_SUCH_PRIVILEGE;
1635 rights->names[i].string = sec_privilege_name(id);
1636 if (rights->names[i].string == NULL) {
1637 return NT_STATUS_NO_SUCH_PRIVILEGE;
1641 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1642 LDB_FLAG_MOD_DELETE, astate->account_sid,
1648 lsa_GetQuotasForAccount
1650 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1651 struct lsa_GetQuotasForAccount *r)
1653 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1658 lsa_SetQuotasForAccount
1660 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1661 struct lsa_SetQuotasForAccount *r)
1663 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1668 lsa_GetSystemAccessAccount
1670 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1671 struct lsa_GetSystemAccessAccount *r)
1673 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1678 lsa_SetSystemAccessAccount
1680 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1681 struct lsa_SetSystemAccessAccount *r)
1683 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1690 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1691 struct lsa_CreateSecret *r)
1693 struct dcesrv_handle *policy_handle;
1694 struct lsa_policy_state *policy_state;
1695 struct lsa_secret_state *secret_state;
1696 struct dcesrv_handle *handle;
1697 struct ldb_message **msgs, *msg;
1699 const char *attrs[] = {
1707 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1708 ZERO_STRUCTP(r->out.sec_handle);
1710 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
1712 case SECURITY_SYSTEM:
1713 case SECURITY_ADMINISTRATOR:
1716 /* Users and annonymous are not allowed create secrets */
1717 return NT_STATUS_ACCESS_DENIED;
1720 policy_state = policy_handle->data;
1722 if (!r->in.name.string) {
1723 return NT_STATUS_INVALID_PARAMETER;
1726 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1727 if (!secret_state) {
1728 return NT_STATUS_NO_MEMORY;
1730 secret_state->policy = policy_state;
1732 msg = ldb_msg_new(mem_ctx);
1734 return NT_STATUS_NO_MEMORY;
1737 if (strncmp("G$", r->in.name.string, 2) == 0) {
1739 name = &r->in.name.string[2];
1740 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1741 secret_state->global = true;
1743 if (strlen(name) < 1) {
1744 return NT_STATUS_INVALID_PARAMETER;
1747 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
1748 /* search for the secret record */
1749 ret = gendb_search(secret_state->sam_ldb,
1750 mem_ctx, policy_state->system_dn, &msgs, attrs,
1751 "(&(cn=%s)(objectclass=secret))",
1754 return NT_STATUS_OBJECT_NAME_COLLISION;
1758 DEBUG(0,("Failure searching for CN=%s: %s\n",
1759 name2, ldb_errstring(secret_state->sam_ldb)));
1760 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1763 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1764 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
1765 return NT_STATUS_NO_MEMORY;
1768 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
1771 secret_state->global = false;
1773 name = r->in.name.string;
1774 if (strlen(name) < 1) {
1775 return NT_STATUS_INVALID_PARAMETER;
1778 secret_state->sam_ldb = talloc_reference(secret_state,
1779 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
1780 /* search for the secret record */
1781 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1782 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1784 "(&(cn=%s)(objectclass=secret))",
1785 ldb_binary_encode_string(mem_ctx, name));
1787 return NT_STATUS_OBJECT_NAME_COLLISION;
1791 DEBUG(0,("Failure searching for CN=%s: %s\n",
1792 name, ldb_errstring(secret_state->sam_ldb)));
1793 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1796 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
1797 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
1800 /* pull in all the template attributes. Note this is always from the global samdb */
1801 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
1804 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
1806 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1809 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
1811 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1813 /* create the secret */
1814 ret = ldb_add(secret_state->sam_ldb, msg);
1816 DEBUG(0,("Failed to create secret record %s: %s\n",
1817 ldb_dn_get_linearized(msg->dn),
1818 ldb_errstring(secret_state->sam_ldb)));
1819 return NT_STATUS_ACCESS_DENIED;
1822 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1824 return NT_STATUS_NO_MEMORY;
1827 handle->data = talloc_steal(handle, secret_state);
1829 secret_state->access_mask = r->in.access_mask;
1830 secret_state->policy = talloc_reference(secret_state, policy_state);
1832 *r->out.sec_handle = handle->wire_handle;
1834 return NT_STATUS_OK;
1841 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1842 struct lsa_OpenSecret *r)
1844 struct dcesrv_handle *policy_handle;
1846 struct lsa_policy_state *policy_state;
1847 struct lsa_secret_state *secret_state;
1848 struct dcesrv_handle *handle;
1849 struct ldb_message **msgs;
1850 const char *attrs[] = {
1858 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1859 ZERO_STRUCTP(r->out.sec_handle);
1860 policy_state = policy_handle->data;
1862 if (!r->in.name.string) {
1863 return NT_STATUS_INVALID_PARAMETER;
1866 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
1868 case SECURITY_SYSTEM:
1869 case SECURITY_ADMINISTRATOR:
1872 /* Users and annonymous are not allowed to access secrets */
1873 return NT_STATUS_ACCESS_DENIED;
1876 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1877 if (!secret_state) {
1878 return NT_STATUS_NO_MEMORY;
1880 secret_state->policy = policy_state;
1882 if (strncmp("G$", r->in.name.string, 2) == 0) {
1883 name = &r->in.name.string[2];
1884 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1885 secret_state->global = true;
1887 if (strlen(name) < 1) {
1888 return NT_STATUS_INVALID_PARAMETER;
1891 /* search for the secret record */
1892 ret = gendb_search(secret_state->sam_ldb,
1893 mem_ctx, policy_state->system_dn, &msgs, attrs,
1894 "(&(cn=%s Secret)(objectclass=secret))",
1895 ldb_binary_encode_string(mem_ctx, name));
1897 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1901 DEBUG(0,("Found %d records matching DN %s\n", ret,
1902 ldb_dn_get_linearized(policy_state->system_dn)));
1903 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1907 secret_state->global = false;
1908 secret_state->sam_ldb = talloc_reference(secret_state,
1909 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
1911 name = r->in.name.string;
1912 if (strlen(name) < 1) {
1913 return NT_STATUS_INVALID_PARAMETER;
1916 /* search for the secret record */
1917 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1918 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1920 "(&(cn=%s)(objectclass=secret))",
1921 ldb_binary_encode_string(mem_ctx, name));
1923 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1927 DEBUG(0,("Found %d records matching CN=%s\n",
1928 ret, ldb_binary_encode_string(mem_ctx, name)));
1929 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1933 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1935 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1937 return NT_STATUS_NO_MEMORY;
1940 handle->data = talloc_steal(handle, secret_state);
1942 secret_state->access_mask = r->in.access_mask;
1943 secret_state->policy = talloc_reference(secret_state, policy_state);
1945 *r->out.sec_handle = handle->wire_handle;
1947 return NT_STATUS_OK;
1954 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1955 struct lsa_SetSecret *r)
1958 struct dcesrv_handle *h;
1959 struct lsa_secret_state *secret_state;
1960 struct ldb_message *msg;
1961 DATA_BLOB session_key;
1962 DATA_BLOB crypt_secret, secret;
1965 NTSTATUS status = NT_STATUS_OK;
1967 struct timeval now = timeval_current();
1968 NTTIME nt_now = timeval_to_nttime(&now);
1970 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
1972 secret_state = h->data;
1974 msg = ldb_msg_new(mem_ctx);
1976 return NT_STATUS_NO_MEMORY;
1979 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
1981 return NT_STATUS_NO_MEMORY;
1983 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
1984 if (!NT_STATUS_IS_OK(status)) {
1988 if (r->in.old_val) {
1990 crypt_secret.data = r->in.old_val->data;
1991 crypt_secret.length = r->in.old_val->size;
1993 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1994 if (!NT_STATUS_IS_OK(status)) {
1998 val.data = secret.data;
1999 val.length = secret.length;
2002 if (samdb_msg_add_value(secret_state->sam_ldb,
2003 mem_ctx, msg, "priorValue", &val) != 0) {
2004 return NT_STATUS_NO_MEMORY;
2007 /* set old value mtime */
2008 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2009 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2010 return NT_STATUS_NO_MEMORY;
2013 if (!r->in.new_val) {
2014 /* set old value mtime */
2015 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2016 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2017 return NT_STATUS_NO_MEMORY;
2019 if (samdb_msg_add_delete(secret_state->sam_ldb,
2020 mem_ctx, msg, "currentValue")) {
2021 return NT_STATUS_NO_MEMORY;
2026 if (r->in.new_val) {
2028 crypt_secret.data = r->in.new_val->data;
2029 crypt_secret.length = r->in.new_val->size;
2031 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2032 if (!NT_STATUS_IS_OK(status)) {
2036 val.data = secret.data;
2037 val.length = secret.length;
2040 if (samdb_msg_add_value(secret_state->sam_ldb,
2041 mem_ctx, msg, "currentValue", &val) != 0) {
2042 return NT_STATUS_NO_MEMORY;
2045 /* set new value mtime */
2046 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2047 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2048 return NT_STATUS_NO_MEMORY;
2051 /* If the old value is not set, then migrate the
2052 * current value to the old value */
2053 if (!r->in.old_val) {
2054 const struct ldb_val *new_val;
2055 NTTIME last_set_time;
2056 struct ldb_message **res;
2057 const char *attrs[] = {
2063 /* search for the secret record */
2064 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2065 secret_state->secret_dn, &res, attrs);
2067 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2071 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2072 ldb_dn_get_linearized(secret_state->secret_dn)));
2073 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2076 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2077 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2081 if (samdb_msg_add_value(secret_state->sam_ldb,
2082 mem_ctx, msg, "priorValue",
2084 return NT_STATUS_NO_MEMORY;
2088 /* set new value mtime */
2089 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2090 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2091 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2092 return NT_STATUS_NO_MEMORY;
2098 /* modify the samdb record */
2099 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2101 /* we really need samdb.c to return NTSTATUS */
2102 return NT_STATUS_UNSUCCESSFUL;
2105 return NT_STATUS_OK;
2112 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2113 struct lsa_QuerySecret *r)
2115 struct dcesrv_handle *h;
2116 struct lsa_secret_state *secret_state;
2117 struct ldb_message *msg;
2118 DATA_BLOB session_key;
2119 DATA_BLOB crypt_secret, secret;
2121 struct ldb_message **res;
2122 const char *attrs[] = {
2132 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2134 /* Ensure user is permitted to read this... */
2135 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2137 case SECURITY_SYSTEM:
2138 case SECURITY_ADMINISTRATOR:
2141 /* Users and annonymous are not allowed to read secrets */
2142 return NT_STATUS_ACCESS_DENIED;
2145 secret_state = h->data;
2147 /* pull all the user attributes */
2148 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2149 secret_state->secret_dn, &res, attrs);
2151 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2155 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2156 if (!NT_STATUS_IS_OK(nt_status)) {
2160 if (r->in.old_val) {
2161 const struct ldb_val *prior_val;
2162 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2163 if (!r->out.old_val) {
2164 return NT_STATUS_NO_MEMORY;
2166 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2168 if (prior_val && prior_val->length) {
2169 secret.data = prior_val->data;
2170 secret.length = prior_val->length;
2173 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2174 if (!crypt_secret.length) {
2175 return NT_STATUS_NO_MEMORY;
2177 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2178 if (!r->out.old_val->buf) {
2179 return NT_STATUS_NO_MEMORY;
2181 r->out.old_val->buf->size = crypt_secret.length;
2182 r->out.old_val->buf->length = crypt_secret.length;
2183 r->out.old_val->buf->data = crypt_secret.data;
2187 if (r->in.old_mtime) {
2188 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2189 if (!r->out.old_mtime) {
2190 return NT_STATUS_NO_MEMORY;
2192 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2195 if (r->in.new_val) {
2196 const struct ldb_val *new_val;
2197 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2198 if (!r->out.new_val) {
2199 return NT_STATUS_NO_MEMORY;
2202 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2204 if (new_val && new_val->length) {
2205 secret.data = new_val->data;
2206 secret.length = new_val->length;
2209 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2210 if (!crypt_secret.length) {
2211 return NT_STATUS_NO_MEMORY;
2213 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2214 if (!r->out.new_val->buf) {
2215 return NT_STATUS_NO_MEMORY;
2217 r->out.new_val->buf->length = crypt_secret.length;
2218 r->out.new_val->buf->size = crypt_secret.length;
2219 r->out.new_val->buf->data = crypt_secret.data;
2223 if (r->in.new_mtime) {
2224 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2225 if (!r->out.new_mtime) {
2226 return NT_STATUS_NO_MEMORY;
2228 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2231 return NT_STATUS_OK;
2238 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2239 TALLOC_CTX *mem_ctx,
2240 struct lsa_LookupPrivValue *r)
2242 struct dcesrv_handle *h;
2243 struct lsa_policy_state *state;
2246 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2250 id = sec_privilege_id(r->in.name->string);
2252 return NT_STATUS_NO_SUCH_PRIVILEGE;
2255 r->out.luid->low = id;
2256 r->out.luid->high = 0;
2258 return NT_STATUS_OK;
2265 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2266 TALLOC_CTX *mem_ctx,
2267 struct lsa_LookupPrivName *r)
2269 struct dcesrv_handle *h;
2270 struct lsa_policy_state *state;
2271 const char *privname;
2273 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2277 if (r->in.luid->high != 0) {
2278 return NT_STATUS_NO_SUCH_PRIVILEGE;
2281 privname = sec_privilege_name(r->in.luid->low);
2282 if (privname == NULL) {
2283 return NT_STATUS_NO_SUCH_PRIVILEGE;
2286 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2287 if (r->out.name == NULL) {
2288 return NT_STATUS_NO_MEMORY;
2290 r->out.name->string = privname;
2292 return NT_STATUS_OK;
2297 lsa_LookupPrivDisplayName
2299 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2300 TALLOC_CTX *mem_ctx,
2301 struct lsa_LookupPrivDisplayName *r)
2303 struct dcesrv_handle *h;
2304 struct lsa_policy_state *state;
2307 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2311 id = sec_privilege_id(r->in.name->string);
2313 return NT_STATUS_NO_SUCH_PRIVILEGE;
2316 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2317 if (r->out.disp_name == NULL) {
2318 return NT_STATUS_NO_MEMORY;
2321 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2322 if (r->out.disp_name->string == NULL) {
2323 return NT_STATUS_INTERNAL_ERROR;
2326 return NT_STATUS_OK;
2331 lsa_EnumAccountsWithUserRight
2333 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2334 TALLOC_CTX *mem_ctx,
2335 struct lsa_EnumAccountsWithUserRight *r)
2337 struct dcesrv_handle *h;
2338 struct lsa_policy_state *state;
2340 struct ldb_message **res;
2341 const char * const attrs[] = { "objectSid", NULL};
2342 const char *privname;
2344 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2348 if (r->in.name == NULL) {
2349 return NT_STATUS_NO_SUCH_PRIVILEGE;
2352 privname = r->in.name->string;
2353 if (sec_privilege_id(privname) == -1) {
2354 return NT_STATUS_NO_SUCH_PRIVILEGE;
2357 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2358 "privilege=%s", privname);
2360 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2363 return NT_STATUS_NO_MORE_ENTRIES;
2366 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2367 if (r->out.sids->sids == NULL) {
2368 return NT_STATUS_NO_MEMORY;
2370 for (i=0;i<ret;i++) {
2371 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2372 res[i], "objectSid");
2373 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2375 r->out.sids->num_sids = ret;
2377 return NT_STATUS_OK;
2382 lsa_AddAccountRights
2384 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2385 TALLOC_CTX *mem_ctx,
2386 struct lsa_AddAccountRights *r)
2388 struct dcesrv_handle *h;
2389 struct lsa_policy_state *state;
2391 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2395 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2397 r->in.sid, r->in.rights);
2402 lsa_RemoveAccountRights
2404 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2405 TALLOC_CTX *mem_ctx,
2406 struct lsa_RemoveAccountRights *r)
2408 struct dcesrv_handle *h;
2409 struct lsa_policy_state *state;
2411 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2415 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2416 LDB_FLAG_MOD_DELETE,
2417 r->in.sid, r->in.rights);
2422 lsa_StorePrivateData
2424 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2425 struct lsa_StorePrivateData *r)
2427 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2432 lsa_RetrievePrivateData
2434 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2435 struct lsa_RetrievePrivateData *r)
2437 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2444 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2445 struct lsa_GetUserName *r)
2447 NTSTATUS status = NT_STATUS_OK;
2448 const char *account_name;
2449 const char *authority_name;
2450 struct lsa_String *_account_name;
2451 struct lsa_StringPointer *_authority_name = NULL;
2453 /* this is what w2k3 does */
2454 r->out.account_name = r->in.account_name;
2455 r->out.authority_name = r->in.authority_name;
2457 if (r->in.account_name && r->in.account_name->string) {
2458 return NT_STATUS_INVALID_PARAMETER;
2461 if (r->in.authority_name &&
2462 r->in.authority_name->string &&
2463 r->in.authority_name->string->string) {
2464 return NT_STATUS_INVALID_PARAMETER;
2467 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2468 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2470 _account_name = talloc(mem_ctx, struct lsa_String);
2471 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2472 _account_name->string = account_name;
2474 if (r->in.authority_name) {
2475 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2476 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2477 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2478 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2479 _authority_name->string->string = authority_name;
2482 r->out.account_name = _account_name;
2483 r->out.authority_name = _authority_name;
2491 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2492 TALLOC_CTX *mem_ctx,
2493 struct lsa_SetInfoPolicy2 *r)
2495 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2499 lsa_QueryDomainInformationPolicy
2501 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2502 TALLOC_CTX *mem_ctx,
2503 struct lsa_QueryDomainInformationPolicy *r)
2505 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2509 lsa_SetDomInfoPolicy
2511 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2512 TALLOC_CTX *mem_ctx,
2513 struct lsa_SetDomainInformationPolicy *r)
2515 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2521 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
2522 TALLOC_CTX *mem_ctx,
2523 struct lsa_TestCall *r)
2525 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2531 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2532 struct lsa_CREDRWRITE *r)
2534 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2541 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2542 struct lsa_CREDRREAD *r)
2544 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2551 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2552 struct lsa_CREDRENUMERATE *r)
2554 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2559 lsa_CREDRWRITEDOMAINCREDENTIALS
2561 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2562 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2564 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2569 lsa_CREDRREADDOMAINCREDENTIALS
2571 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2572 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2574 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2581 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2582 struct lsa_CREDRDELETE *r)
2584 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2589 lsa_CREDRGETTARGETINFO
2591 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2592 struct lsa_CREDRGETTARGETINFO *r)
2594 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2599 lsa_CREDRPROFILELOADED
2601 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2602 struct lsa_CREDRPROFILELOADED *r)
2604 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2609 lsa_CREDRGETSESSIONTYPES
2611 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2612 struct lsa_CREDRGETSESSIONTYPES *r)
2614 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2619 lsa_LSARREGISTERAUDITEVENT
2621 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2622 struct lsa_LSARREGISTERAUDITEVENT *r)
2624 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2629 lsa_LSARGENAUDITEVENT
2631 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2632 struct lsa_LSARGENAUDITEVENT *r)
2634 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2639 lsa_LSARUNREGISTERAUDITEVENT
2641 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2642 struct lsa_LSARUNREGISTERAUDITEVENT *r)
2644 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2649 lsa_lsaRQueryForestTrustInformation
2651 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2652 struct lsa_lsaRQueryForestTrustInformation *r)
2654 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2659 lsa_LSARSETFORESTTRUSTINFORMATION
2661 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2662 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2664 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2671 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2672 struct lsa_CREDRRENAME *r)
2674 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2680 lsa_LSAROPENPOLICYSCE
2682 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2683 struct lsa_LSAROPENPOLICYSCE *r)
2685 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2690 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
2692 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2693 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2695 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2700 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
2702 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2703 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2705 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2710 lsa_LSARADTREPORTSECURITYEVENT
2712 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2713 struct lsa_LSARADTREPORTSECURITYEVENT *r)
2715 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2719 /* include the generated boilerplate */
2720 #include "librpc/gen_ndr/ndr_lsa_s.c"
2724 /*****************************************
2725 NOTE! The remaining calls below were
2726 removed in w2k3, so the DCESRV_FAULT()
2727 replies are the correct implementation. Do
2728 not try and fill these in with anything else
2729 ******************************************/
2732 dssetup_DsRoleDnsNameToFlatName
2734 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2735 struct dssetup_DsRoleDnsNameToFlatName *r)
2737 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2742 dssetup_DsRoleDcAsDc
2744 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2745 struct dssetup_DsRoleDcAsDc *r)
2747 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2752 dssetup_DsRoleDcAsReplica
2754 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2755 struct dssetup_DsRoleDcAsReplica *r)
2757 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2762 dssetup_DsRoleDemoteDc
2764 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2765 struct dssetup_DsRoleDemoteDc *r)
2767 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2772 dssetup_DsRoleGetDcOperationProgress
2774 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2775 struct dssetup_DsRoleGetDcOperationProgress *r)
2777 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2782 dssetup_DsRoleGetDcOperationResults
2784 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2785 struct dssetup_DsRoleGetDcOperationResults *r)
2787 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2792 dssetup_DsRoleCancel
2794 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2795 struct dssetup_DsRoleCancel *r)
2797 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2802 dssetup_DsRoleServerSaveStateForUpgrade
2804 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2805 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
2807 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2812 dssetup_DsRoleUpgradeDownlevelServer
2814 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2815 struct dssetup_DsRoleUpgradeDownlevelServer *r)
2817 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2822 dssetup_DsRoleAbortDownlevelServerUpgrade
2824 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2825 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
2827 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2831 /* include the generated boilerplate */
2832 #include "librpc/gen_ndr/ndr_dssetup_s.c"
2834 NTSTATUS dcerpc_server_lsa_init(void)
2838 ret = dcerpc_server_dssetup_init();
2839 if (!NT_STATUS_IS_OK(ret)) {
2842 ret = dcerpc_server_lsarpc_init();
2843 if (!NT_STATUS_IS_OK(ret)) {