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 struct dcesrv_handle *h;
101 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
102 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
103 struct lsa_secret_state *secret_state = h->data;
104 ret = ldb_delete(secret_state->sam_ldb,
105 secret_state->secret_dn);
108 return NT_STATUS_INVALID_HANDLE;
112 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
113 struct lsa_trusted_domain_state *trusted_domain_state = h->data;
114 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
115 trusted_domain_state->trusted_domain_dn);
118 return NT_STATUS_INVALID_HANDLE;
122 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
123 struct lsa_RightSet *rights;
124 struct lsa_account_state *astate;
125 struct lsa_EnumAccountRights r2;
128 rights = talloc(mem_ctx, struct lsa_RightSet);
130 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
134 r2.in.handle = &astate->policy->handle->wire_handle;
135 r2.in.sid = astate->account_sid;
136 r2.out.rights = rights;
138 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
139 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
143 if (!NT_STATUS_IS_OK(status)) {
147 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
148 LDB_FLAG_MOD_DELETE, astate->account_sid,
150 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
154 if (!NT_STATUS_IS_OK(status)) {
159 return NT_STATUS_INVALID_HANDLE;
166 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
167 struct lsa_EnumPrivs *r)
169 struct dcesrv_handle *h;
170 struct lsa_policy_state *state;
172 const char *privname;
174 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
178 i = *r->in.resume_handle;
181 while ((privname = sec_privilege_name(i)) &&
182 r->out.privs->count < r->in.max_count) {
183 struct lsa_PrivEntry *e;
185 r->out.privs->privs = talloc_realloc(r->out.privs,
187 struct lsa_PrivEntry,
188 r->out.privs->count+1);
189 if (r->out.privs->privs == NULL) {
190 return NT_STATUS_NO_MEMORY;
192 e = &r->out.privs->privs[r->out.privs->count];
195 e->name.string = privname;
196 r->out.privs->count++;
200 *r->out.resume_handle = i;
209 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
210 struct lsa_QuerySecurity *r)
212 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
219 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
220 struct lsa_SetSecObj *r)
222 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
229 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
230 struct lsa_ChangePassword *r)
232 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
236 dssetup_DsRoleGetPrimaryDomainInformation
238 This is not an LSA call, but is the only call left on the DSSETUP
239 pipe (after the pipe was truncated), and needs lsa_get_policy_state
241 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
243 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
245 union dssetup_DsRoleInfo *info;
247 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
248 W_ERROR_HAVE_NO_MEMORY(info);
250 switch (r->in.level) {
251 case DS_ROLE_BASIC_INFORMATION:
253 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
255 const char *domain = NULL;
256 const char *dns_domain = NULL;
257 const char *forest = NULL;
258 struct GUID domain_guid;
259 struct lsa_policy_state *state;
261 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
262 if (!NT_STATUS_IS_OK(status)) {
263 return ntstatus_to_werror(status);
266 ZERO_STRUCT(domain_guid);
268 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
269 case ROLE_STANDALONE:
270 role = DS_ROLE_STANDALONE_SERVER;
272 case ROLE_DOMAIN_MEMBER:
273 role = DS_ROLE_MEMBER_SERVER;
275 case ROLE_DOMAIN_CONTROLLER:
276 if (samdb_is_pdc(state->sam_ldb)) {
277 role = DS_ROLE_PRIMARY_DC;
279 role = DS_ROLE_BACKUP_DC;
284 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
285 case ROLE_STANDALONE:
286 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
287 W_ERROR_HAVE_NO_MEMORY(domain);
289 case ROLE_DOMAIN_MEMBER:
290 domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
291 W_ERROR_HAVE_NO_MEMORY(domain);
292 /* TODO: what is with dns_domain and forest and guid? */
294 case ROLE_DOMAIN_CONTROLLER:
295 flags = DS_ROLE_PRIMARY_DS_RUNNING;
297 if (state->mixed_domain == 1) {
298 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
301 domain = state->domain_name;
302 dns_domain = state->domain_dns;
303 forest = state->forest_dns;
305 domain_guid = state->domain_guid;
306 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
310 info->basic.role = role;
311 info->basic.flags = flags;
312 info->basic.domain = domain;
313 info->basic.dns_domain = dns_domain;
314 info->basic.forest = forest;
315 info->basic.domain_guid = domain_guid;
320 case DS_ROLE_UPGRADE_STATUS:
322 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
323 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
328 case DS_ROLE_OP_STATUS:
330 info->opstatus.status = DS_ROLE_OP_IDLE;
336 return WERR_INVALID_PARAM;
339 return WERR_INVALID_PARAM;
344 fill in the AccountDomain info
346 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
347 struct lsa_DomainInfo *info)
349 info->name.string = state->domain_name;
350 info->sid = state->domain_sid;
356 fill in the DNS domain info
358 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
359 struct lsa_DnsDomainInfo *info)
361 info->name.string = state->domain_name;
362 info->sid = state->domain_sid;
363 info->dns_domain.string = state->domain_dns;
364 info->dns_forest.string = state->forest_dns;
365 info->domain_guid = state->domain_guid;
373 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
374 struct lsa_QueryInfoPolicy2 *r)
376 struct lsa_policy_state *state;
377 struct dcesrv_handle *h;
381 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
385 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
387 return NT_STATUS_NO_MEMORY;
390 ZERO_STRUCTP(r->out.info);
392 switch (r->in.level) {
393 case LSA_POLICY_INFO_DOMAIN:
394 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
395 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
397 case LSA_POLICY_INFO_DNS:
398 return dcesrv_lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
399 case LSA_POLICY_INFO_DB:
400 case LSA_POLICY_INFO_AUDIT_FULL_SET:
401 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
402 return NT_STATUS_INVALID_PARAMETER;
405 return NT_STATUS_INVALID_INFO_CLASS;
411 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
412 struct lsa_QueryInfoPolicy *r)
414 struct lsa_QueryInfoPolicy2 r2;
417 r2.in.handle = r->in.handle;
418 r2.in.level = r->in.level;
420 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
422 r->out.info = r2.out.info;
430 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
431 struct lsa_SetInfoPolicy *r)
433 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
440 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
441 struct lsa_ClearAuditLog *r)
443 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
450 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
451 struct lsa_CreateAccount *r)
453 struct lsa_account_state *astate;
455 struct lsa_policy_state *state;
456 struct dcesrv_handle *h, *ah;
458 ZERO_STRUCTP(r->out.acct_handle);
460 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
464 astate = talloc(dce_call->conn, struct lsa_account_state);
465 if (astate == NULL) {
466 return NT_STATUS_NO_MEMORY;
469 astate->account_sid = dom_sid_dup(astate, r->in.sid);
470 if (astate->account_sid == NULL) {
472 return NT_STATUS_NO_MEMORY;
475 astate->policy = talloc_reference(astate, state);
476 astate->access_mask = r->in.access_mask;
478 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
481 return NT_STATUS_NO_MEMORY;
484 ah->data = talloc_steal(ah, astate);
486 *r->out.acct_handle = ah->wire_handle;
495 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
496 struct lsa_EnumAccounts *r)
498 struct dcesrv_handle *h;
499 struct lsa_policy_state *state;
501 struct ldb_message **res;
502 const char * const attrs[] = { "objectSid", NULL};
505 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
509 /* NOTE: This call must only return accounts that have at least
512 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
513 "(&(objectSid=*)(privilege=*))");
515 return NT_STATUS_NO_SUCH_USER;
518 if (*r->in.resume_handle >= ret) {
519 return NT_STATUS_NO_MORE_ENTRIES;
522 count = ret - *r->in.resume_handle;
523 if (count > r->in.num_entries) {
524 count = r->in.num_entries;
528 return NT_STATUS_NO_MORE_ENTRIES;
531 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
532 if (r->out.sids->sids == NULL) {
533 return NT_STATUS_NO_MEMORY;
536 for (i=0;i<count;i++) {
537 r->out.sids->sids[i].sid =
538 samdb_result_dom_sid(r->out.sids->sids,
539 res[i + *r->in.resume_handle],
541 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
544 r->out.sids->num_sids = count;
545 *r->out.resume_handle = count + *r->in.resume_handle;
553 lsa_CreateTrustedDomainEx2
555 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
557 struct lsa_CreateTrustedDomainEx2 *r)
559 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
563 lsa_CreateTrustedDomainEx
565 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
567 struct lsa_CreateTrustedDomainEx *r)
569 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
573 lsa_CreateTrustedDomain
575 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
576 struct lsa_CreateTrustedDomain *r)
578 struct dcesrv_handle *policy_handle;
579 struct lsa_policy_state *policy_state;
580 struct lsa_trusted_domain_state *trusted_domain_state;
581 struct dcesrv_handle *handle;
582 struct ldb_message **msgs, *msg;
583 const char *attrs[] = {
589 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
590 ZERO_STRUCTP(r->out.trustdom_handle);
592 policy_state = policy_handle->data;
594 if (!r->in.info->name.string) {
595 return NT_STATUS_INVALID_PARAMETER;
597 name = r->in.info->name.string;
599 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
600 if (!trusted_domain_state) {
601 return NT_STATUS_NO_MEMORY;
603 trusted_domain_state->policy = policy_state;
605 msg = ldb_msg_new(mem_ctx);
607 return NT_STATUS_NO_MEMORY;
610 /* search for the trusted_domain record */
611 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
612 mem_ctx, policy_state->system_dn, &msgs, attrs,
613 "(&(cn=%s)(objectclass=trustedDomain))",
614 ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
616 return NT_STATUS_OBJECT_NAME_COLLISION;
619 if (ret < 0 || ret > 1) {
620 DEBUG(0,("Found %d records matching DN %s\n", ret,
621 ldb_dn_get_linearized(policy_state->system_dn)));
622 return NT_STATUS_INTERNAL_DB_CORRUPTION;
625 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
626 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
627 return NT_STATUS_NO_MEMORY;
630 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
632 if (r->in.info->sid) {
633 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
635 return NT_STATUS_NO_MEMORY;
638 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
641 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
643 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
645 /* create the trusted_domain */
646 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
647 if (ret != LDB_SUCCESS) {
648 DEBUG(0,("Failed to create trusted_domain record %s: %s\n",
649 ldb_dn_get_linearized(msg->dn), ldb_errstring(trusted_domain_state->policy->sam_ldb)));
650 return NT_STATUS_INTERNAL_DB_CORRUPTION;
653 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
655 return NT_STATUS_NO_MEMORY;
658 handle->data = talloc_steal(handle, trusted_domain_state);
660 trusted_domain_state->access_mask = r->in.access_mask;
661 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
663 *r->out.trustdom_handle = handle->wire_handle;
669 lsa_OpenTrustedDomain
671 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
672 struct lsa_OpenTrustedDomain *r)
674 struct dcesrv_handle *policy_handle;
676 struct lsa_policy_state *policy_state;
677 struct lsa_trusted_domain_state *trusted_domain_state;
678 struct dcesrv_handle *handle;
679 struct ldb_message **msgs;
680 const char *attrs[] = {
684 const char *sid_string;
687 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
688 ZERO_STRUCTP(r->out.trustdom_handle);
689 policy_state = policy_handle->data;
691 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
692 if (!trusted_domain_state) {
693 return NT_STATUS_NO_MEMORY;
695 trusted_domain_state->policy = policy_state;
697 sid_string = dom_sid_string(mem_ctx, r->in.sid);
699 return NT_STATUS_NO_MEMORY;
702 /* search for the trusted_domain record */
703 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
704 mem_ctx, policy_state->system_dn, &msgs, attrs,
705 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
708 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
712 DEBUG(0,("Found %d records matching DN %s\n", ret,
713 ldb_dn_get_linearized(policy_state->system_dn)));
714 return NT_STATUS_INTERNAL_DB_CORRUPTION;
717 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
719 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
721 return NT_STATUS_NO_MEMORY;
724 handle->data = talloc_steal(handle, trusted_domain_state);
726 trusted_domain_state->access_mask = r->in.access_mask;
727 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
729 *r->out.trustdom_handle = handle->wire_handle;
736 lsa_OpenTrustedDomainByName
738 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
740 struct lsa_OpenTrustedDomainByName *r)
742 struct dcesrv_handle *policy_handle;
744 struct lsa_policy_state *policy_state;
745 struct lsa_trusted_domain_state *trusted_domain_state;
746 struct dcesrv_handle *handle;
747 struct ldb_message **msgs;
748 const char *attrs[] = {
754 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
755 ZERO_STRUCTP(r->out.trustdom_handle);
756 policy_state = policy_handle->data;
758 if (!r->in.name.string) {
759 return NT_STATUS_INVALID_PARAMETER;
762 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
763 if (!trusted_domain_state) {
764 return NT_STATUS_NO_MEMORY;
766 trusted_domain_state->policy = policy_state;
768 /* search for the trusted_domain record */
769 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
770 mem_ctx, policy_state->system_dn, &msgs, attrs,
771 "(&(flatname=%s)(objectclass=trustedDomain))",
772 ldb_binary_encode_string(mem_ctx, r->in.name.string));
774 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
778 DEBUG(0,("Found %d records matching DN %s\n", ret,
779 ldb_dn_get_linearized(policy_state->system_dn)));
780 return NT_STATUS_INTERNAL_DB_CORRUPTION;
783 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
785 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
787 return NT_STATUS_NO_MEMORY;
790 handle->data = talloc_steal(handle, trusted_domain_state);
792 trusted_domain_state->access_mask = r->in.access_mask;
793 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
795 *r->out.trustdom_handle = handle->wire_handle;
803 lsa_SetTrustedDomainInfo
805 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
806 struct lsa_SetTrustedDomainInfo *r)
808 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
814 lsa_SetInfomrationTrustedDomain
816 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
818 struct lsa_SetInformationTrustedDomain *r)
820 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
825 lsa_DeleteTrustedDomain
827 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
828 struct lsa_DeleteTrustedDomain *r)
831 struct lsa_OpenTrustedDomain open;
832 struct lsa_Delete delete;
833 struct dcesrv_handle *h;
835 open.in.handle = r->in.handle;
836 open.in.sid = r->in.dom_sid;
837 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
838 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
839 if (!open.out.trustdom_handle) {
840 return NT_STATUS_NO_MEMORY;
842 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
843 if (!NT_STATUS_IS_OK(status)) {
847 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
848 talloc_steal(mem_ctx, h);
850 delete.in.handle = open.out.trustdom_handle;
851 status = dcesrv_lsa_Delete(dce_call, mem_ctx, &delete);
852 if (!NT_STATUS_IS_OK(status)) {
858 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
859 struct ldb_message *msg,
860 struct lsa_TrustDomainInfoInfoEx *info_ex)
862 info_ex->domain_name.string
863 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
864 info_ex->netbios_name.string
865 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
867 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
868 info_ex->trust_direction
869 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
871 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
872 info_ex->trust_attributes
873 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
878 lsa_QueryTrustedDomainInfo
880 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
881 struct lsa_QueryTrustedDomainInfo *r)
883 struct dcesrv_handle *h;
884 struct lsa_trusted_domain_state *trusted_domain_state;
885 struct ldb_message *msg;
887 struct ldb_message **res;
888 const char *attrs[] = {
891 "securityIdentifier",
898 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
900 trusted_domain_state = h->data;
902 /* pull all the user attributes */
903 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
904 trusted_domain_state->trusted_domain_dn, &res, attrs);
906 return NT_STATUS_INTERNAL_DB_CORRUPTION;
910 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
912 return NT_STATUS_NO_MEMORY;
914 switch (r->in.level) {
915 case LSA_TRUSTED_DOMAIN_INFO_NAME:
916 r->out.info->name.netbios_name.string
917 = samdb_result_string(msg, "flatname", NULL);
919 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
920 r->out.info->posix_offset.posix_offset
921 = samdb_result_uint(msg, "posixOffset", 0);
923 #if 0 /* Win2k3 doesn't implement this */
924 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
925 r->out.info->info_basic.netbios_name.string
926 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
927 r->out.info->info_basic.sid
928 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
931 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
932 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
934 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
935 ZERO_STRUCT(r->out.info->full_info);
936 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
938 case LSA_TRUSTED_DOMAIN_INFO_INFO_ALL:
939 ZERO_STRUCT(r->out.info->info_all);
940 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_all.info_ex);
942 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO:
943 case LSA_TRUSTED_DOMAIN_INFO_11:
944 /* oops, we don't want to return the info after all */
945 talloc_free(r->out.info);
947 return NT_STATUS_INVALID_PARAMETER;
949 /* oops, we don't want to return the info after all */
950 talloc_free(r->out.info);
952 return NT_STATUS_INVALID_INFO_CLASS;
960 lsa_QueryTrustedDomainInfoBySid
962 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
963 struct lsa_QueryTrustedDomainInfoBySid *r)
966 struct lsa_OpenTrustedDomain open;
967 struct lsa_QueryTrustedDomainInfo query;
968 struct dcesrv_handle *h;
969 open.in.handle = r->in.handle;
970 open.in.sid = r->in.dom_sid;
971 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
972 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
973 if (!open.out.trustdom_handle) {
974 return NT_STATUS_NO_MEMORY;
976 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
977 if (!NT_STATUS_IS_OK(status)) {
981 /* Ensure this handle goes away at the end of this call */
982 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
983 talloc_steal(mem_ctx, h);
985 query.in.trustdom_handle = open.out.trustdom_handle;
986 query.in.level = r->in.level;
987 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
988 if (!NT_STATUS_IS_OK(status)) {
992 r->out.info = query.out.info;
997 lsa_SetTrustedDomainInfoByName
999 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1000 TALLOC_CTX *mem_ctx,
1001 struct lsa_SetTrustedDomainInfoByName *r)
1003 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1007 lsa_QueryTrustedDomainInfoByName
1009 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1010 TALLOC_CTX *mem_ctx,
1011 struct lsa_QueryTrustedDomainInfoByName *r)
1014 struct lsa_OpenTrustedDomainByName open;
1015 struct lsa_QueryTrustedDomainInfo query;
1016 struct dcesrv_handle *h;
1017 open.in.handle = r->in.handle;
1018 open.in.name = r->in.trusted_domain;
1019 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1020 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1021 if (!open.out.trustdom_handle) {
1022 return NT_STATUS_NO_MEMORY;
1024 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1025 if (!NT_STATUS_IS_OK(status)) {
1029 /* Ensure this handle goes away at the end of this call */
1030 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1031 talloc_steal(mem_ctx, h);
1033 query.in.trustdom_handle = open.out.trustdom_handle;
1034 query.in.level = r->in.level;
1035 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1036 if (!NT_STATUS_IS_OK(status)) {
1040 r->out.info = query.out.info;
1041 return NT_STATUS_OK;
1045 lsa_CloseTrustedDomainEx
1047 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1048 TALLOC_CTX *mem_ctx,
1049 struct lsa_CloseTrustedDomainEx *r)
1051 /* The result of a bad hair day from an IDL programmer? Not
1052 * implmented in Win2k3. You should always just lsa_Close
1054 return NT_STATUS_NOT_IMPLEMENTED;
1059 comparison function for sorting lsa_DomainInformation array
1061 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1063 return strcasecmp_m(e1->name.string, e2->name.string);
1069 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1070 struct lsa_EnumTrustDom *r)
1072 struct dcesrv_handle *policy_handle;
1073 struct lsa_DomainInfo *entries;
1074 struct lsa_policy_state *policy_state;
1075 struct ldb_message **domains;
1076 const char *attrs[] = {
1078 "securityIdentifier",
1085 *r->out.resume_handle = 0;
1087 r->out.domains->domains = NULL;
1088 r->out.domains->count = 0;
1090 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1092 policy_state = policy_handle->data;
1094 /* search for all users in this domain. This could possibly be cached and
1095 resumed based on resume_key */
1096 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1097 "objectclass=trustedDomain");
1099 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1101 if (count == 0 || r->in.max_size == 0) {
1102 return NT_STATUS_OK;
1105 /* convert to lsa_TrustInformation format */
1106 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1108 return NT_STATUS_NO_MEMORY;
1110 for (i=0;i<count;i++) {
1111 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1112 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1115 /* sort the results by name */
1116 qsort(entries, count, sizeof(*entries),
1117 (comparison_fn_t)compare_DomainInfo);
1119 if (*r->in.resume_handle >= count) {
1120 *r->out.resume_handle = -1;
1122 return NT_STATUS_NO_MORE_ENTRIES;
1125 /* return the rest, limit by max_size. Note that we
1126 use the w2k3 element size value of 60 */
1127 r->out.domains->count = count - *r->in.resume_handle;
1128 r->out.domains->count = MIN(r->out.domains->count,
1129 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1131 r->out.domains->domains = entries + *r->in.resume_handle;
1132 r->out.domains->count = r->out.domains->count;
1134 if (r->out.domains->count < count - *r->in.resume_handle) {
1135 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1136 return STATUS_MORE_ENTRIES;
1139 return NT_STATUS_OK;
1143 comparison function for sorting lsa_DomainInformation array
1145 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1147 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1151 lsa_EnumTrustedDomainsEx
1153 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1154 struct lsa_EnumTrustedDomainsEx *r)
1156 struct dcesrv_handle *policy_handle;
1157 struct lsa_TrustDomainInfoInfoEx *entries;
1158 struct lsa_policy_state *policy_state;
1159 struct ldb_message **domains;
1160 const char *attrs[] = {
1163 "securityIdentifier",
1173 *r->out.resume_handle = 0;
1175 r->out.domains->domains = NULL;
1176 r->out.domains->count = 0;
1178 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1180 policy_state = policy_handle->data;
1182 /* search for all users in this domain. This could possibly be cached and
1183 resumed based on resume_key */
1184 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1185 "objectclass=trustedDomain");
1187 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1189 if (count == 0 || r->in.max_size == 0) {
1190 return NT_STATUS_OK;
1193 /* convert to lsa_DomainInformation format */
1194 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1196 return NT_STATUS_NO_MEMORY;
1198 for (i=0;i<count;i++) {
1199 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1200 if (!NT_STATUS_IS_OK(nt_status)) {
1205 /* sort the results by name */
1206 qsort(entries, count, sizeof(*entries),
1207 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1209 if (*r->in.resume_handle >= count) {
1210 *r->out.resume_handle = -1;
1212 return NT_STATUS_NO_MORE_ENTRIES;
1215 /* return the rest, limit by max_size. Note that we
1216 use the w2k3 element size value of 60 */
1217 r->out.domains->count = count - *r->in.resume_handle;
1218 r->out.domains->count = MIN(r->out.domains->count,
1219 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1221 r->out.domains->domains = entries + *r->in.resume_handle;
1222 r->out.domains->count = r->out.domains->count;
1224 if (r->out.domains->count < count - *r->in.resume_handle) {
1225 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1226 return STATUS_MORE_ENTRIES;
1229 return NT_STATUS_OK;
1236 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1237 struct lsa_OpenAccount *r)
1239 struct dcesrv_handle *h, *ah;
1240 struct lsa_policy_state *state;
1241 struct lsa_account_state *astate;
1243 ZERO_STRUCTP(r->out.acct_handle);
1245 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1249 astate = talloc(dce_call->conn, struct lsa_account_state);
1250 if (astate == NULL) {
1251 return NT_STATUS_NO_MEMORY;
1254 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1255 if (astate->account_sid == NULL) {
1256 talloc_free(astate);
1257 return NT_STATUS_NO_MEMORY;
1260 astate->policy = talloc_reference(astate, state);
1261 astate->access_mask = r->in.access_mask;
1263 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1265 talloc_free(astate);
1266 return NT_STATUS_NO_MEMORY;
1269 ah->data = talloc_steal(ah, astate);
1271 *r->out.acct_handle = ah->wire_handle;
1273 return NT_STATUS_OK;
1278 lsa_EnumPrivsAccount
1280 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1281 TALLOC_CTX *mem_ctx,
1282 struct lsa_EnumPrivsAccount *r)
1284 struct dcesrv_handle *h;
1285 struct lsa_account_state *astate;
1287 struct ldb_message **res;
1288 const char * const attrs[] = { "privilege", NULL};
1289 struct ldb_message_element *el;
1292 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1296 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1297 r->out.privs->count = 0;
1298 r->out.privs->unknown = 0;
1299 r->out.privs->set = NULL;
1301 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1302 if (sidstr == NULL) {
1303 return NT_STATUS_NO_MEMORY;
1306 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1307 "objectSid=%s", sidstr);
1309 return NT_STATUS_OK;
1312 el = ldb_msg_find_element(res[0], "privilege");
1313 if (el == NULL || el->num_values == 0) {
1314 return NT_STATUS_OK;
1317 r->out.privs->set = talloc_array(r->out.privs,
1318 struct lsa_LUIDAttribute, el->num_values);
1319 if (r->out.privs->set == NULL) {
1320 return NT_STATUS_NO_MEMORY;
1323 for (i=0;i<el->num_values;i++) {
1324 int id = sec_privilege_id((const char *)el->values[i].data);
1326 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1328 r->out.privs->set[i].attribute = 0;
1329 r->out.privs->set[i].luid.low = id;
1330 r->out.privs->set[i].luid.high = 0;
1333 r->out.privs->count = el->num_values;
1335 return NT_STATUS_OK;
1339 lsa_EnumAccountRights
1341 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1342 TALLOC_CTX *mem_ctx,
1343 struct lsa_EnumAccountRights *r)
1345 struct dcesrv_handle *h;
1346 struct lsa_policy_state *state;
1348 struct ldb_message **res;
1349 const char * const attrs[] = { "privilege", NULL};
1351 struct ldb_message_element *el;
1353 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1357 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1358 if (sidstr == NULL) {
1359 return NT_STATUS_NO_MEMORY;
1362 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1363 "(&(objectSid=%s)(privilege=*))", sidstr);
1365 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1368 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1371 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1372 dom_sid_string(mem_ctx, r->in.sid),
1373 ldb_errstring(state->sam_ldb)));
1374 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1377 el = ldb_msg_find_element(res[0], "privilege");
1378 if (el == NULL || el->num_values == 0) {
1379 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1382 r->out.rights->count = el->num_values;
1383 r->out.rights->names = talloc_array(r->out.rights,
1384 struct lsa_StringLarge, r->out.rights->count);
1385 if (r->out.rights->names == NULL) {
1386 return NT_STATUS_NO_MEMORY;
1389 for (i=0;i<el->num_values;i++) {
1390 r->out.rights->names[i].string = (const char *)el->values[i].data;
1393 return NT_STATUS_OK;
1399 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1401 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1402 TALLOC_CTX *mem_ctx,
1403 struct lsa_policy_state *state,
1405 struct dom_sid *sid,
1406 const struct lsa_RightSet *rights)
1409 struct ldb_message *msg;
1410 struct ldb_message_element *el;
1412 struct lsa_EnumAccountRights r2;
1414 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1415 if (sidstr == NULL) {
1416 return NT_STATUS_NO_MEMORY;
1419 msg = ldb_msg_new(mem_ctx);
1421 return NT_STATUS_NO_MEMORY;
1424 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1425 NULL, "objectSid=%s", sidstr);
1426 if (msg->dn == NULL) {
1428 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1429 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1431 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1433 if (!NT_STATUS_IS_OK(status)) {
1436 return NT_STATUS_NO_SUCH_USER;
1439 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1440 return NT_STATUS_NO_MEMORY;
1443 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1446 r2.in.handle = &state->handle->wire_handle;
1448 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1450 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1451 if (!NT_STATUS_IS_OK(status)) {
1452 ZERO_STRUCTP(r2.out.rights);
1456 for (i=0;i<rights->count;i++) {
1457 if (sec_privilege_id(rights->names[i].string) == -1) {
1458 return NT_STATUS_NO_SUCH_PRIVILEGE;
1461 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1463 for (j=0;j<r2.out.rights->count;j++) {
1464 if (strcasecmp_m(r2.out.rights->names[j].string,
1465 rights->names[i].string) == 0) {
1469 if (j != r2.out.rights->count) continue;
1472 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1473 if (ret != LDB_SUCCESS) {
1474 return NT_STATUS_NO_MEMORY;
1478 el = ldb_msg_find_element(msg, "privilege");
1480 return NT_STATUS_OK;
1483 ret = ldb_modify(state->sam_ldb, msg);
1485 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1486 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1488 DEBUG(3, ("Could not %s attributes from %s: %s",
1489 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1490 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1491 return NT_STATUS_UNEXPECTED_IO_ERROR;
1494 return NT_STATUS_OK;
1498 lsa_AddPrivilegesToAccount
1500 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1501 struct lsa_AddPrivilegesToAccount *r)
1503 struct lsa_RightSet rights;
1504 struct dcesrv_handle *h;
1505 struct lsa_account_state *astate;
1508 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1512 rights.count = r->in.privs->count;
1513 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1514 if (rights.names == NULL) {
1515 return NT_STATUS_NO_MEMORY;
1517 for (i=0;i<rights.count;i++) {
1518 int id = r->in.privs->set[i].luid.low;
1519 if (r->in.privs->set[i].luid.high) {
1520 return NT_STATUS_NO_SUCH_PRIVILEGE;
1522 rights.names[i].string = sec_privilege_name(id);
1523 if (rights.names[i].string == NULL) {
1524 return NT_STATUS_NO_SUCH_PRIVILEGE;
1528 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1529 LDB_FLAG_MOD_ADD, astate->account_sid,
1535 lsa_RemovePrivilegesFromAccount
1537 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1538 struct lsa_RemovePrivilegesFromAccount *r)
1540 struct lsa_RightSet *rights;
1541 struct dcesrv_handle *h;
1542 struct lsa_account_state *astate;
1545 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1549 rights = talloc(mem_ctx, struct lsa_RightSet);
1551 if (r->in.remove_all == 1 &&
1552 r->in.privs == NULL) {
1553 struct lsa_EnumAccountRights r2;
1556 r2.in.handle = &astate->policy->handle->wire_handle;
1557 r2.in.sid = astate->account_sid;
1558 r2.out.rights = rights;
1560 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1561 if (!NT_STATUS_IS_OK(status)) {
1565 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1566 LDB_FLAG_MOD_DELETE, astate->account_sid,
1570 if (r->in.remove_all != 0) {
1571 return NT_STATUS_INVALID_PARAMETER;
1574 rights->count = r->in.privs->count;
1575 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
1576 if (rights->names == NULL) {
1577 return NT_STATUS_NO_MEMORY;
1579 for (i=0;i<rights->count;i++) {
1580 int id = r->in.privs->set[i].luid.low;
1581 if (r->in.privs->set[i].luid.high) {
1582 return NT_STATUS_NO_SUCH_PRIVILEGE;
1584 rights->names[i].string = sec_privilege_name(id);
1585 if (rights->names[i].string == NULL) {
1586 return NT_STATUS_NO_SUCH_PRIVILEGE;
1590 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1591 LDB_FLAG_MOD_DELETE, astate->account_sid,
1597 lsa_GetQuotasForAccount
1599 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1600 struct lsa_GetQuotasForAccount *r)
1602 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1607 lsa_SetQuotasForAccount
1609 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1610 struct lsa_SetQuotasForAccount *r)
1612 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1617 lsa_GetSystemAccessAccount
1619 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1620 struct lsa_GetSystemAccessAccount *r)
1622 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1627 lsa_SetSystemAccessAccount
1629 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1630 struct lsa_SetSystemAccessAccount *r)
1632 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1639 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1640 struct lsa_CreateSecret *r)
1642 struct dcesrv_handle *policy_handle;
1643 struct lsa_policy_state *policy_state;
1644 struct lsa_secret_state *secret_state;
1645 struct dcesrv_handle *handle;
1646 struct ldb_message **msgs, *msg;
1648 const char *attrs[] = {
1656 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1657 ZERO_STRUCTP(r->out.sec_handle);
1659 policy_state = policy_handle->data;
1661 if (!r->in.name.string) {
1662 return NT_STATUS_INVALID_PARAMETER;
1665 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1666 if (!secret_state) {
1667 return NT_STATUS_NO_MEMORY;
1669 secret_state->policy = policy_state;
1671 msg = ldb_msg_new(mem_ctx);
1673 return NT_STATUS_NO_MEMORY;
1676 if (strncmp("G$", r->in.name.string, 2) == 0) {
1678 name = &r->in.name.string[2];
1679 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1680 secret_state->global = true;
1682 if (strlen(name) < 1) {
1683 return NT_STATUS_INVALID_PARAMETER;
1686 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
1687 /* search for the secret record */
1688 ret = gendb_search(secret_state->sam_ldb,
1689 mem_ctx, policy_state->system_dn, &msgs, attrs,
1690 "(&(cn=%s)(objectclass=secret))",
1693 return NT_STATUS_OBJECT_NAME_COLLISION;
1697 DEBUG(0,("Failure searching for CN=%s: %s\n",
1698 name2, ldb_errstring(secret_state->sam_ldb)));
1699 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1702 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1703 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
1704 return NT_STATUS_NO_MEMORY;
1707 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
1710 secret_state->global = false;
1712 name = r->in.name.string;
1713 if (strlen(name) < 1) {
1714 return NT_STATUS_INVALID_PARAMETER;
1717 secret_state->sam_ldb = talloc_reference(secret_state,
1718 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
1719 /* search for the secret record */
1720 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1721 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1723 "(&(cn=%s)(objectclass=secret))",
1724 ldb_binary_encode_string(mem_ctx, name));
1726 return NT_STATUS_OBJECT_NAME_COLLISION;
1730 DEBUG(0,("Failure searching for CN=%s: %s\n",
1731 name, ldb_errstring(secret_state->sam_ldb)));
1732 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1735 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
1736 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
1739 /* pull in all the template attributes. Note this is always from the global samdb */
1740 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
1743 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
1745 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1748 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
1750 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1752 /* create the secret */
1753 ret = ldb_add(secret_state->sam_ldb, msg);
1755 DEBUG(0,("Failed to create secret record %s: %s\n",
1756 ldb_dn_get_linearized(msg->dn),
1757 ldb_errstring(secret_state->sam_ldb)));
1758 return NT_STATUS_ACCESS_DENIED;
1761 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1763 return NT_STATUS_NO_MEMORY;
1766 handle->data = talloc_steal(handle, secret_state);
1768 secret_state->access_mask = r->in.access_mask;
1769 secret_state->policy = talloc_reference(secret_state, policy_state);
1771 *r->out.sec_handle = handle->wire_handle;
1773 return NT_STATUS_OK;
1780 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1781 struct lsa_OpenSecret *r)
1783 struct dcesrv_handle *policy_handle;
1785 struct lsa_policy_state *policy_state;
1786 struct lsa_secret_state *secret_state;
1787 struct dcesrv_handle *handle;
1788 struct ldb_message **msgs;
1789 const char *attrs[] = {
1797 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1798 ZERO_STRUCTP(r->out.sec_handle);
1799 policy_state = policy_handle->data;
1801 if (!r->in.name.string) {
1802 return NT_STATUS_INVALID_PARAMETER;
1805 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1806 if (!secret_state) {
1807 return NT_STATUS_NO_MEMORY;
1809 secret_state->policy = policy_state;
1811 if (strncmp("G$", r->in.name.string, 2) == 0) {
1812 name = &r->in.name.string[2];
1813 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1814 secret_state->global = true;
1816 if (strlen(name) < 1) {
1817 return NT_STATUS_INVALID_PARAMETER;
1820 /* search for the secret record */
1821 ret = gendb_search(secret_state->sam_ldb,
1822 mem_ctx, policy_state->system_dn, &msgs, attrs,
1823 "(&(cn=%s Secret)(objectclass=secret))",
1824 ldb_binary_encode_string(mem_ctx, name));
1826 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1830 DEBUG(0,("Found %d records matching DN %s\n", ret,
1831 ldb_dn_get_linearized(policy_state->system_dn)));
1832 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1836 secret_state->sam_ldb = talloc_reference(secret_state,
1837 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
1839 secret_state->global = false;
1840 name = r->in.name.string;
1841 if (strlen(name) < 1) {
1842 return NT_STATUS_INVALID_PARAMETER;
1845 /* search for the secret record */
1846 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1847 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1849 "(&(cn=%s)(objectclass=secret))",
1850 ldb_binary_encode_string(mem_ctx, name));
1852 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1856 DEBUG(0,("Found %d records matching CN=%s\n",
1857 ret, ldb_binary_encode_string(mem_ctx, name)));
1858 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1862 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1864 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1866 return NT_STATUS_NO_MEMORY;
1869 handle->data = talloc_steal(handle, secret_state);
1871 secret_state->access_mask = r->in.access_mask;
1872 secret_state->policy = talloc_reference(secret_state, policy_state);
1874 *r->out.sec_handle = handle->wire_handle;
1876 return NT_STATUS_OK;
1883 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1884 struct lsa_SetSecret *r)
1887 struct dcesrv_handle *h;
1888 struct lsa_secret_state *secret_state;
1889 struct ldb_message *msg;
1890 DATA_BLOB session_key;
1891 DATA_BLOB crypt_secret, secret;
1894 NTSTATUS status = NT_STATUS_OK;
1896 struct timeval now = timeval_current();
1897 NTTIME nt_now = timeval_to_nttime(&now);
1899 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
1901 secret_state = h->data;
1903 msg = ldb_msg_new(mem_ctx);
1905 return NT_STATUS_NO_MEMORY;
1908 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
1910 return NT_STATUS_NO_MEMORY;
1912 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
1913 if (!NT_STATUS_IS_OK(status)) {
1917 if (r->in.old_val) {
1919 crypt_secret.data = r->in.old_val->data;
1920 crypt_secret.length = r->in.old_val->size;
1922 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1923 if (!NT_STATUS_IS_OK(status)) {
1927 val.data = secret.data;
1928 val.length = secret.length;
1931 if (samdb_msg_add_value(secret_state->sam_ldb,
1932 mem_ctx, msg, "priorValue", &val) != 0) {
1933 return NT_STATUS_NO_MEMORY;
1936 /* set old value mtime */
1937 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1938 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
1939 return NT_STATUS_NO_MEMORY;
1942 if (!r->in.new_val) {
1943 /* This behaviour varies depending of if this is a local, or a global secret... */
1944 if (secret_state->global) {
1945 /* set old value mtime */
1946 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1947 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
1948 return NT_STATUS_NO_MEMORY;
1951 if (samdb_msg_add_delete(secret_state->sam_ldb,
1952 mem_ctx, msg, "currentValue")) {
1953 return NT_STATUS_NO_MEMORY;
1955 if (samdb_msg_add_delete(secret_state->sam_ldb,
1956 mem_ctx, msg, "lastSetTime")) {
1957 return NT_STATUS_NO_MEMORY;
1963 if (r->in.new_val) {
1965 crypt_secret.data = r->in.new_val->data;
1966 crypt_secret.length = r->in.new_val->size;
1968 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1969 if (!NT_STATUS_IS_OK(status)) {
1973 val.data = secret.data;
1974 val.length = secret.length;
1977 if (samdb_msg_add_value(secret_state->sam_ldb,
1978 mem_ctx, msg, "currentValue", &val) != 0) {
1979 return NT_STATUS_NO_MEMORY;
1982 /* set new value mtime */
1983 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1984 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
1985 return NT_STATUS_NO_MEMORY;
1988 /* If the old value is not set, then migrate the
1989 * current value to the old value */
1990 if (!r->in.old_val) {
1991 const struct ldb_val *new_val;
1992 NTTIME last_set_time;
1993 struct ldb_message **res;
1994 const char *attrs[] = {
2000 /* search for the secret record */
2001 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2002 secret_state->secret_dn, &res, attrs);
2004 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2008 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2009 ldb_dn_get_linearized(secret_state->secret_dn)));
2010 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2013 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2014 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2018 if (samdb_msg_add_value(secret_state->sam_ldb,
2019 mem_ctx, msg, "priorValue",
2021 return NT_STATUS_NO_MEMORY;
2025 /* set new value mtime */
2026 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2027 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2028 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2029 return NT_STATUS_NO_MEMORY;
2035 /* modify the samdb record */
2036 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2038 /* we really need samdb.c to return NTSTATUS */
2039 return NT_STATUS_UNSUCCESSFUL;
2042 return NT_STATUS_OK;
2049 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2050 struct lsa_QuerySecret *r)
2052 struct dcesrv_handle *h;
2053 struct lsa_secret_state *secret_state;
2054 struct ldb_message *msg;
2055 DATA_BLOB session_key;
2056 DATA_BLOB crypt_secret, secret;
2058 struct ldb_message **res;
2059 const char *attrs[] = {
2069 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2071 secret_state = h->data;
2073 /* pull all the user attributes */
2074 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2075 secret_state->secret_dn, &res, attrs);
2077 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2081 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2082 if (!NT_STATUS_IS_OK(nt_status)) {
2086 if (r->in.old_val) {
2087 const struct ldb_val *prior_val;
2088 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2089 if (!r->out.old_val) {
2090 return NT_STATUS_NO_MEMORY;
2092 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2094 if (prior_val && prior_val->length) {
2095 secret.data = prior_val->data;
2096 secret.length = prior_val->length;
2099 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2100 if (!crypt_secret.length) {
2101 return NT_STATUS_NO_MEMORY;
2103 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2104 if (!r->out.old_val->buf) {
2105 return NT_STATUS_NO_MEMORY;
2107 r->out.old_val->buf->size = crypt_secret.length;
2108 r->out.old_val->buf->length = crypt_secret.length;
2109 r->out.old_val->buf->data = crypt_secret.data;
2113 if (r->in.old_mtime) {
2114 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2115 if (!r->out.old_mtime) {
2116 return NT_STATUS_NO_MEMORY;
2118 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2121 if (r->in.new_val) {
2122 const struct ldb_val *new_val;
2123 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2124 if (!r->out.new_val) {
2125 return NT_STATUS_NO_MEMORY;
2128 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2130 if (new_val && new_val->length) {
2131 secret.data = new_val->data;
2132 secret.length = new_val->length;
2135 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2136 if (!crypt_secret.length) {
2137 return NT_STATUS_NO_MEMORY;
2139 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2140 if (!r->out.new_val->buf) {
2141 return NT_STATUS_NO_MEMORY;
2143 r->out.new_val->buf->length = crypt_secret.length;
2144 r->out.new_val->buf->size = crypt_secret.length;
2145 r->out.new_val->buf->data = crypt_secret.data;
2149 if (r->in.new_mtime) {
2150 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2151 if (!r->out.new_mtime) {
2152 return NT_STATUS_NO_MEMORY;
2154 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2157 return NT_STATUS_OK;
2164 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2165 TALLOC_CTX *mem_ctx,
2166 struct lsa_LookupPrivValue *r)
2168 struct dcesrv_handle *h;
2169 struct lsa_policy_state *state;
2172 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2176 id = sec_privilege_id(r->in.name->string);
2178 return NT_STATUS_NO_SUCH_PRIVILEGE;
2181 r->out.luid->low = id;
2182 r->out.luid->high = 0;
2184 return NT_STATUS_OK;
2191 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2192 TALLOC_CTX *mem_ctx,
2193 struct lsa_LookupPrivName *r)
2195 struct dcesrv_handle *h;
2196 struct lsa_policy_state *state;
2197 const char *privname;
2199 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2203 if (r->in.luid->high != 0) {
2204 return NT_STATUS_NO_SUCH_PRIVILEGE;
2207 privname = sec_privilege_name(r->in.luid->low);
2208 if (privname == NULL) {
2209 return NT_STATUS_NO_SUCH_PRIVILEGE;
2212 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2213 if (r->out.name == NULL) {
2214 return NT_STATUS_NO_MEMORY;
2216 r->out.name->string = privname;
2218 return NT_STATUS_OK;
2223 lsa_LookupPrivDisplayName
2225 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2226 TALLOC_CTX *mem_ctx,
2227 struct lsa_LookupPrivDisplayName *r)
2229 struct dcesrv_handle *h;
2230 struct lsa_policy_state *state;
2233 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2237 id = sec_privilege_id(r->in.name->string);
2239 return NT_STATUS_NO_SUCH_PRIVILEGE;
2242 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2243 if (r->out.disp_name == NULL) {
2244 return NT_STATUS_NO_MEMORY;
2247 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2248 if (r->out.disp_name->string == NULL) {
2249 return NT_STATUS_INTERNAL_ERROR;
2252 return NT_STATUS_OK;
2259 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2260 struct lsa_DeleteObject *r)
2262 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2267 lsa_EnumAccountsWithUserRight
2269 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2270 TALLOC_CTX *mem_ctx,
2271 struct lsa_EnumAccountsWithUserRight *r)
2273 struct dcesrv_handle *h;
2274 struct lsa_policy_state *state;
2276 struct ldb_message **res;
2277 const char * const attrs[] = { "objectSid", NULL};
2278 const char *privname;
2280 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2284 if (r->in.name == NULL) {
2285 return NT_STATUS_NO_SUCH_PRIVILEGE;
2288 privname = r->in.name->string;
2289 if (sec_privilege_id(privname) == -1) {
2290 return NT_STATUS_NO_SUCH_PRIVILEGE;
2293 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2294 "privilege=%s", privname);
2296 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2299 return NT_STATUS_NO_MORE_ENTRIES;
2302 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2303 if (r->out.sids->sids == NULL) {
2304 return NT_STATUS_NO_MEMORY;
2306 for (i=0;i<ret;i++) {
2307 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2308 res[i], "objectSid");
2309 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2311 r->out.sids->num_sids = ret;
2313 return NT_STATUS_OK;
2318 lsa_AddAccountRights
2320 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2321 TALLOC_CTX *mem_ctx,
2322 struct lsa_AddAccountRights *r)
2324 struct dcesrv_handle *h;
2325 struct lsa_policy_state *state;
2327 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2331 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2333 r->in.sid, r->in.rights);
2338 lsa_RemoveAccountRights
2340 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2341 TALLOC_CTX *mem_ctx,
2342 struct lsa_RemoveAccountRights *r)
2344 struct dcesrv_handle *h;
2345 struct lsa_policy_state *state;
2347 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2351 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2352 LDB_FLAG_MOD_DELETE,
2353 r->in.sid, r->in.rights);
2358 lsa_StorePrivateData
2360 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2361 struct lsa_StorePrivateData *r)
2363 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2368 lsa_RetrievePrivateData
2370 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2371 struct lsa_RetrievePrivateData *r)
2373 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2380 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2381 struct lsa_GetUserName *r)
2383 NTSTATUS status = NT_STATUS_OK;
2384 const char *account_name;
2385 const char *authority_name;
2386 struct lsa_String *_account_name;
2387 struct lsa_StringPointer *_authority_name = NULL;
2389 /* this is what w2k3 does */
2390 r->out.account_name = r->in.account_name;
2391 r->out.authority_name = r->in.authority_name;
2393 if (r->in.account_name && r->in.account_name->string) {
2394 return NT_STATUS_INVALID_PARAMETER;
2397 if (r->in.authority_name &&
2398 r->in.authority_name->string &&
2399 r->in.authority_name->string->string) {
2400 return NT_STATUS_INVALID_PARAMETER;
2403 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2404 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2406 _account_name = talloc(mem_ctx, struct lsa_String);
2407 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2408 _account_name->string = account_name;
2410 if (r->in.authority_name) {
2411 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2412 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2413 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2414 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2415 _authority_name->string->string = authority_name;
2418 r->out.account_name = _account_name;
2419 r->out.authority_name = _authority_name;
2427 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2428 TALLOC_CTX *mem_ctx,
2429 struct lsa_SetInfoPolicy2 *r)
2431 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2435 lsa_QueryDomainInformationPolicy
2437 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2438 TALLOC_CTX *mem_ctx,
2439 struct lsa_QueryDomainInformationPolicy *r)
2441 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2445 lsa_SetDomInfoPolicy
2447 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2448 TALLOC_CTX *mem_ctx,
2449 struct lsa_SetDomainInformationPolicy *r)
2451 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2457 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
2458 TALLOC_CTX *mem_ctx,
2459 struct lsa_TestCall *r)
2461 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2467 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2468 struct lsa_CREDRWRITE *r)
2470 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2477 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2478 struct lsa_CREDRREAD *r)
2480 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2487 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2488 struct lsa_CREDRENUMERATE *r)
2490 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2495 lsa_CREDRWRITEDOMAINCREDENTIALS
2497 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2498 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2500 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2505 lsa_CREDRREADDOMAINCREDENTIALS
2507 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2508 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2510 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2517 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2518 struct lsa_CREDRDELETE *r)
2520 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2525 lsa_CREDRGETTARGETINFO
2527 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2528 struct lsa_CREDRGETTARGETINFO *r)
2530 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2535 lsa_CREDRPROFILELOADED
2537 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2538 struct lsa_CREDRPROFILELOADED *r)
2540 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2545 lsa_CREDRGETSESSIONTYPES
2547 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2548 struct lsa_CREDRGETSESSIONTYPES *r)
2550 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2555 lsa_LSARREGISTERAUDITEVENT
2557 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2558 struct lsa_LSARREGISTERAUDITEVENT *r)
2560 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2565 lsa_LSARGENAUDITEVENT
2567 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2568 struct lsa_LSARGENAUDITEVENT *r)
2570 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2575 lsa_LSARUNREGISTERAUDITEVENT
2577 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2578 struct lsa_LSARUNREGISTERAUDITEVENT *r)
2580 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2585 lsa_lsaRQueryForestTrustInformation
2587 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2588 struct lsa_lsaRQueryForestTrustInformation *r)
2590 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2595 lsa_LSARSETFORESTTRUSTINFORMATION
2597 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2598 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2600 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2607 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2608 struct lsa_CREDRRENAME *r)
2610 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2616 lsa_LSAROPENPOLICYSCE
2618 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2619 struct lsa_LSAROPENPOLICYSCE *r)
2621 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2626 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
2628 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2629 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2631 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2636 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
2638 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2639 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2641 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2646 lsa_LSARADTREPORTSECURITYEVENT
2648 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2649 struct lsa_LSARADTREPORTSECURITYEVENT *r)
2651 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2655 /* include the generated boilerplate */
2656 #include "librpc/gen_ndr/ndr_lsa_s.c"
2660 /*****************************************
2661 NOTE! The remaining calls below were
2662 removed in w2k3, so the DCESRV_FAULT()
2663 replies are the correct implementation. Do
2664 not try and fill these in with anything else
2665 ******************************************/
2668 dssetup_DsRoleDnsNameToFlatName
2670 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2671 struct dssetup_DsRoleDnsNameToFlatName *r)
2673 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2678 dssetup_DsRoleDcAsDc
2680 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2681 struct dssetup_DsRoleDcAsDc *r)
2683 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2688 dssetup_DsRoleDcAsReplica
2690 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2691 struct dssetup_DsRoleDcAsReplica *r)
2693 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2698 dssetup_DsRoleDemoteDc
2700 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2701 struct dssetup_DsRoleDemoteDc *r)
2703 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2708 dssetup_DsRoleGetDcOperationProgress
2710 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2711 struct dssetup_DsRoleGetDcOperationProgress *r)
2713 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2718 dssetup_DsRoleGetDcOperationResults
2720 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2721 struct dssetup_DsRoleGetDcOperationResults *r)
2723 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2728 dssetup_DsRoleCancel
2730 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2731 struct dssetup_DsRoleCancel *r)
2733 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2738 dssetup_DsRoleServerSaveStateForUpgrade
2740 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2741 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
2743 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2748 dssetup_DsRoleUpgradeDownlevelServer
2750 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2751 struct dssetup_DsRoleUpgradeDownlevelServer *r)
2753 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2758 dssetup_DsRoleAbortDownlevelServerUpgrade
2760 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2761 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
2763 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2767 /* include the generated boilerplate */
2768 #include "librpc/gen_ndr/ndr_dssetup_s.c"
2770 NTSTATUS dcerpc_server_lsa_init(void)
2774 ret = dcerpc_server_dssetup_init();
2775 if (!NT_STATUS_IS_OK(ret)) {
2778 ret = dcerpc_server_lsarpc_init();
2779 if (!NT_STATUS_IS_OK(ret)) {