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"
26 this type allows us to distinguish handle types
30 state associated with a lsa_OpenAccount() operation
32 struct lsa_account_state {
33 struct lsa_policy_state *policy;
35 struct dom_sid *account_sid;
40 state associated with a lsa_OpenSecret() operation
42 struct lsa_secret_state {
43 struct lsa_policy_state *policy;
45 struct ldb_dn *secret_dn;
46 struct ldb_context *sam_ldb;
51 state associated with a lsa_OpenTrustedDomain() operation
53 struct lsa_trusted_domain_state {
54 struct lsa_policy_state *policy;
56 struct ldb_dn *trusted_domain_dn;
59 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
61 struct lsa_EnumAccountRights *r);
63 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
65 struct lsa_policy_state *state,
68 const struct lsa_RightSet *rights);
73 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
76 struct dcesrv_handle *h;
78 *r->out.handle = *r->in.handle;
80 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
84 ZERO_STRUCTP(r->out.handle);
93 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
96 struct dcesrv_handle *h;
99 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
100 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
101 struct lsa_secret_state *secret_state = h->data;
102 ret = samdb_delete(secret_state->sam_ldb, mem_ctx, secret_state->secret_dn);
105 return NT_STATUS_INVALID_HANDLE;
109 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
110 struct lsa_trusted_domain_state *trusted_domain_state = h->data;
111 ret = samdb_delete(trusted_domain_state->policy->sam_ldb, mem_ctx,
112 trusted_domain_state->trusted_domain_dn);
115 return NT_STATUS_INVALID_HANDLE;
119 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
120 struct lsa_RightSet *rights;
121 struct lsa_account_state *astate;
122 struct lsa_EnumAccountRights r2;
125 rights = talloc(mem_ctx, struct lsa_RightSet);
127 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
131 r2.in.handle = &astate->policy->handle->wire_handle;
132 r2.in.sid = astate->account_sid;
133 r2.out.rights = rights;
135 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
136 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
140 if (!NT_STATUS_IS_OK(status)) {
144 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
145 LDB_FLAG_MOD_DELETE, astate->account_sid,
147 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
151 if (!NT_STATUS_IS_OK(status)) {
156 return NT_STATUS_INVALID_HANDLE;
163 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
164 struct lsa_EnumPrivs *r)
166 struct dcesrv_handle *h;
167 struct lsa_policy_state *state;
169 const char *privname;
171 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
175 i = *r->in.resume_handle;
178 while ((privname = sec_privilege_name(i)) &&
179 r->out.privs->count < r->in.max_count) {
180 struct lsa_PrivEntry *e;
182 r->out.privs->privs = talloc_realloc(r->out.privs,
184 struct lsa_PrivEntry,
185 r->out.privs->count+1);
186 if (r->out.privs->privs == NULL) {
187 return NT_STATUS_NO_MEMORY;
189 e = &r->out.privs->privs[r->out.privs->count];
192 e->name.string = privname;
193 r->out.privs->count++;
197 *r->out.resume_handle = i;
206 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
207 struct lsa_QuerySecurity *r)
209 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
216 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
217 struct lsa_SetSecObj *r)
219 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
226 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
227 struct lsa_ChangePassword *r)
229 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
233 dssetup_DsRoleGetPrimaryDomainInformation
235 This is not an LSA call, but is the only call left on the DSSETUP
236 pipe (after the pipe was truncated), and needs lsa_get_policy_state
238 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
240 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
242 union dssetup_DsRoleInfo *info;
244 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
245 W_ERROR_HAVE_NO_MEMORY(info);
247 switch (r->in.level) {
248 case DS_ROLE_BASIC_INFORMATION:
250 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
252 const char *domain = NULL;
253 const char *dns_domain = NULL;
254 const char *forest = NULL;
255 struct GUID domain_guid;
256 struct lsa_policy_state *state;
258 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
259 if (!NT_STATUS_IS_OK(status)) {
260 return ntstatus_to_werror(status);
263 ZERO_STRUCT(domain_guid);
265 switch (lp_server_role(global_loadparm)) {
266 case ROLE_STANDALONE:
267 role = DS_ROLE_STANDALONE_SERVER;
269 case ROLE_DOMAIN_MEMBER:
270 role = DS_ROLE_MEMBER_SERVER;
272 case ROLE_DOMAIN_CONTROLLER:
273 if (samdb_is_pdc(state->sam_ldb)) {
274 role = DS_ROLE_PRIMARY_DC;
276 role = DS_ROLE_BACKUP_DC;
281 switch (lp_server_role(global_loadparm)) {
282 case ROLE_STANDALONE:
283 domain = talloc_strdup(mem_ctx, lp_workgroup(global_loadparm));
284 W_ERROR_HAVE_NO_MEMORY(domain);
286 case ROLE_DOMAIN_MEMBER:
287 domain = talloc_strdup(mem_ctx, lp_workgroup(global_loadparm));
288 W_ERROR_HAVE_NO_MEMORY(domain);
289 /* TODO: what is with dns_domain and forest and guid? */
291 case ROLE_DOMAIN_CONTROLLER:
292 flags = DS_ROLE_PRIMARY_DS_RUNNING;
294 if (state->mixed_domain == 1) {
295 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
298 domain = state->domain_name;
299 dns_domain = state->domain_dns;
300 forest = state->forest_dns;
302 domain_guid = state->domain_guid;
303 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
307 info->basic.role = role;
308 info->basic.flags = flags;
309 info->basic.domain = domain;
310 info->basic.dns_domain = dns_domain;
311 info->basic.forest = forest;
312 info->basic.domain_guid = domain_guid;
317 case DS_ROLE_UPGRADE_STATUS:
319 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
320 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
325 case DS_ROLE_OP_STATUS:
327 info->opstatus.status = DS_ROLE_OP_IDLE;
333 return WERR_INVALID_PARAM;
336 return WERR_INVALID_PARAM;
341 fill in the AccountDomain info
343 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
344 struct lsa_DomainInfo *info)
346 info->name.string = state->domain_name;
347 info->sid = state->domain_sid;
353 fill in the DNS domain info
355 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
356 struct lsa_DnsDomainInfo *info)
358 info->name.string = state->domain_name;
359 info->sid = state->domain_sid;
360 info->dns_domain.string = state->domain_dns;
361 info->dns_forest.string = state->forest_dns;
362 info->domain_guid = state->domain_guid;
370 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
371 struct lsa_QueryInfoPolicy2 *r)
373 struct lsa_policy_state *state;
374 struct dcesrv_handle *h;
378 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
382 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
384 return NT_STATUS_NO_MEMORY;
387 ZERO_STRUCTP(r->out.info);
389 switch (r->in.level) {
390 case LSA_POLICY_INFO_DOMAIN:
391 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
392 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
394 case LSA_POLICY_INFO_DNS:
395 return dcesrv_lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
396 case LSA_POLICY_INFO_DB:
397 case LSA_POLICY_INFO_AUDIT_FULL_SET:
398 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
399 return NT_STATUS_INVALID_PARAMETER;
402 return NT_STATUS_INVALID_INFO_CLASS;
408 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
409 struct lsa_QueryInfoPolicy *r)
411 struct lsa_QueryInfoPolicy2 r2;
414 r2.in.handle = r->in.handle;
415 r2.in.level = r->in.level;
417 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
419 r->out.info = r2.out.info;
427 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
428 struct lsa_SetInfoPolicy *r)
430 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
437 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
438 struct lsa_ClearAuditLog *r)
440 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
447 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
448 struct lsa_CreateAccount *r)
450 struct lsa_account_state *astate;
452 struct lsa_policy_state *state;
453 struct dcesrv_handle *h, *ah;
455 ZERO_STRUCTP(r->out.acct_handle);
457 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
461 astate = talloc(dce_call->conn, struct lsa_account_state);
462 if (astate == NULL) {
463 return NT_STATUS_NO_MEMORY;
466 astate->account_sid = dom_sid_dup(astate, r->in.sid);
467 if (astate->account_sid == NULL) {
469 return NT_STATUS_NO_MEMORY;
472 astate->policy = talloc_reference(astate, state);
473 astate->access_mask = r->in.access_mask;
475 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
478 return NT_STATUS_NO_MEMORY;
481 ah->data = talloc_steal(ah, astate);
483 *r->out.acct_handle = ah->wire_handle;
492 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
493 struct lsa_EnumAccounts *r)
495 struct dcesrv_handle *h;
496 struct lsa_policy_state *state;
498 struct ldb_message **res;
499 const char * const attrs[] = { "objectSid", NULL};
502 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
506 /* NOTE: This call must only return accounts that have at least
509 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
510 "(&(objectSid=*)(privilege=*))");
512 return NT_STATUS_NO_SUCH_USER;
515 if (*r->in.resume_handle >= ret) {
516 return NT_STATUS_NO_MORE_ENTRIES;
519 count = ret - *r->in.resume_handle;
520 if (count > r->in.num_entries) {
521 count = r->in.num_entries;
525 return NT_STATUS_NO_MORE_ENTRIES;
528 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
529 if (r->out.sids->sids == NULL) {
530 return NT_STATUS_NO_MEMORY;
533 for (i=0;i<count;i++) {
534 r->out.sids->sids[i].sid =
535 samdb_result_dom_sid(r->out.sids->sids,
536 res[i + *r->in.resume_handle],
538 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
541 r->out.sids->num_sids = count;
542 *r->out.resume_handle = count + *r->in.resume_handle;
550 lsa_CreateTrustedDomainEx2
552 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
554 struct lsa_CreateTrustedDomainEx2 *r)
556 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
560 lsa_CreateTrustedDomainEx
562 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
564 struct lsa_CreateTrustedDomainEx *r)
566 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
570 lsa_CreateTrustedDomain
572 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
573 struct lsa_CreateTrustedDomain *r)
575 struct dcesrv_handle *policy_handle;
576 struct lsa_policy_state *policy_state;
577 struct lsa_trusted_domain_state *trusted_domain_state;
578 struct dcesrv_handle *handle;
579 struct ldb_message **msgs, *msg;
580 const char *attrs[] = {
586 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
587 ZERO_STRUCTP(r->out.trustdom_handle);
589 policy_state = policy_handle->data;
591 if (!r->in.info->name.string) {
592 return NT_STATUS_INVALID_PARAMETER;
594 name = r->in.info->name.string;
596 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
597 if (!trusted_domain_state) {
598 return NT_STATUS_NO_MEMORY;
600 trusted_domain_state->policy = policy_state;
602 msg = ldb_msg_new(mem_ctx);
604 return NT_STATUS_NO_MEMORY;
607 /* search for the trusted_domain record */
608 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
609 mem_ctx, policy_state->system_dn, &msgs, attrs,
610 "(&(cn=%s)(objectclass=trustedDomain))",
611 ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
613 return NT_STATUS_OBJECT_NAME_COLLISION;
616 if (ret < 0 || ret > 1) {
617 DEBUG(0,("Found %d records matching DN %s\n", ret,
618 ldb_dn_get_linearized(policy_state->system_dn)));
619 return NT_STATUS_INTERNAL_DB_CORRUPTION;
622 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
623 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
624 return NT_STATUS_NO_MEMORY;
627 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
629 if (r->in.info->sid) {
630 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
632 return NT_STATUS_NO_MEMORY;
635 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
638 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
640 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
642 /* create the trusted_domain */
643 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
644 if (ret != LDB_SUCCESS) {
645 DEBUG(0,("Failed to create trusted_domain record %s: %s\n",
646 ldb_dn_get_linearized(msg->dn), ldb_errstring(trusted_domain_state->policy->sam_ldb)));
647 return NT_STATUS_INTERNAL_DB_CORRUPTION;
650 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
652 return NT_STATUS_NO_MEMORY;
655 handle->data = talloc_steal(handle, trusted_domain_state);
657 trusted_domain_state->access_mask = r->in.access_mask;
658 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
660 *r->out.trustdom_handle = handle->wire_handle;
666 lsa_OpenTrustedDomain
668 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
669 struct lsa_OpenTrustedDomain *r)
671 struct dcesrv_handle *policy_handle;
673 struct lsa_policy_state *policy_state;
674 struct lsa_trusted_domain_state *trusted_domain_state;
675 struct dcesrv_handle *handle;
676 struct ldb_message **msgs;
677 const char *attrs[] = {
681 const char *sid_string;
684 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
685 ZERO_STRUCTP(r->out.trustdom_handle);
686 policy_state = policy_handle->data;
688 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
689 if (!trusted_domain_state) {
690 return NT_STATUS_NO_MEMORY;
692 trusted_domain_state->policy = policy_state;
694 sid_string = dom_sid_string(mem_ctx, r->in.sid);
696 return NT_STATUS_NO_MEMORY;
699 /* search for the trusted_domain record */
700 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
701 mem_ctx, policy_state->system_dn, &msgs, attrs,
702 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
705 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
709 DEBUG(0,("Found %d records matching DN %s\n", ret,
710 ldb_dn_get_linearized(policy_state->system_dn)));
711 return NT_STATUS_INTERNAL_DB_CORRUPTION;
714 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
716 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
718 return NT_STATUS_NO_MEMORY;
721 handle->data = talloc_steal(handle, trusted_domain_state);
723 trusted_domain_state->access_mask = r->in.access_mask;
724 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
726 *r->out.trustdom_handle = handle->wire_handle;
733 lsa_OpenTrustedDomainByName
735 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
737 struct lsa_OpenTrustedDomainByName *r)
739 struct dcesrv_handle *policy_handle;
741 struct lsa_policy_state *policy_state;
742 struct lsa_trusted_domain_state *trusted_domain_state;
743 struct dcesrv_handle *handle;
744 struct ldb_message **msgs;
745 const char *attrs[] = {
751 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
752 ZERO_STRUCTP(r->out.trustdom_handle);
753 policy_state = policy_handle->data;
755 if (!r->in.name.string) {
756 return NT_STATUS_INVALID_PARAMETER;
759 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
760 if (!trusted_domain_state) {
761 return NT_STATUS_NO_MEMORY;
763 trusted_domain_state->policy = policy_state;
765 /* search for the trusted_domain record */
766 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
767 mem_ctx, policy_state->system_dn, &msgs, attrs,
768 "(&(flatname=%s)(objectclass=trustedDomain))",
769 ldb_binary_encode_string(mem_ctx, r->in.name.string));
771 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
775 DEBUG(0,("Found %d records matching DN %s\n", ret,
776 ldb_dn_get_linearized(policy_state->system_dn)));
777 return NT_STATUS_INTERNAL_DB_CORRUPTION;
780 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
782 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
784 return NT_STATUS_NO_MEMORY;
787 handle->data = talloc_steal(handle, trusted_domain_state);
789 trusted_domain_state->access_mask = r->in.access_mask;
790 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
792 *r->out.trustdom_handle = handle->wire_handle;
800 lsa_SetTrustedDomainInfo
802 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
803 struct lsa_SetTrustedDomainInfo *r)
805 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
811 lsa_SetInfomrationTrustedDomain
813 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
815 struct lsa_SetInformationTrustedDomain *r)
817 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
822 lsa_DeleteTrustedDomain
824 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
825 struct lsa_DeleteTrustedDomain *r)
828 struct lsa_OpenTrustedDomain open;
829 struct lsa_Delete delete;
830 struct dcesrv_handle *h;
832 open.in.handle = r->in.handle;
833 open.in.sid = r->in.dom_sid;
834 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
835 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
836 if (!open.out.trustdom_handle) {
837 return NT_STATUS_NO_MEMORY;
839 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
840 if (!NT_STATUS_IS_OK(status)) {
844 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
845 talloc_steal(mem_ctx, h);
847 delete.in.handle = open.out.trustdom_handle;
848 status = dcesrv_lsa_Delete(dce_call, mem_ctx, &delete);
849 if (!NT_STATUS_IS_OK(status)) {
855 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
856 struct ldb_message *msg,
857 struct lsa_TrustDomainInfoInfoEx *info_ex)
859 info_ex->domain_name.string
860 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
861 info_ex->netbios_name.string
862 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
864 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
865 info_ex->trust_direction
866 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
868 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
869 info_ex->trust_attributes
870 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
875 lsa_QueryTrustedDomainInfo
877 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
878 struct lsa_QueryTrustedDomainInfo *r)
880 struct dcesrv_handle *h;
881 struct lsa_trusted_domain_state *trusted_domain_state;
882 struct ldb_message *msg;
884 struct ldb_message **res;
885 const char *attrs[] = {
888 "securityIdentifier",
895 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
897 trusted_domain_state = h->data;
899 /* pull all the user attributes */
900 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
901 trusted_domain_state->trusted_domain_dn, &res, attrs);
903 return NT_STATUS_INTERNAL_DB_CORRUPTION;
907 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
909 return NT_STATUS_NO_MEMORY;
911 switch (r->in.level) {
912 case LSA_TRUSTED_DOMAIN_INFO_NAME:
913 r->out.info->name.netbios_name.string
914 = samdb_result_string(msg, "flatname", NULL);
916 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
917 r->out.info->posix_offset.posix_offset
918 = samdb_result_uint(msg, "posixOffset", 0);
920 #if 0 /* Win2k3 doesn't implement this */
921 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
922 r->out.info->info_basic.netbios_name.string
923 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
924 r->out.info->info_basic.sid
925 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
928 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
929 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
931 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
932 ZERO_STRUCT(r->out.info->full_info);
933 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
935 case LSA_TRUSTED_DOMAIN_INFO_INFO_ALL:
936 ZERO_STRUCT(r->out.info->info_all);
937 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_all.info_ex);
939 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO:
940 case LSA_TRUSTED_DOMAIN_INFO_11:
941 /* oops, we don't want to return the info after all */
942 talloc_free(r->out.info);
944 return NT_STATUS_INVALID_PARAMETER;
946 /* oops, we don't want to return the info after all */
947 talloc_free(r->out.info);
949 return NT_STATUS_INVALID_INFO_CLASS;
957 lsa_QueryTrustedDomainInfoBySid
959 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
960 struct lsa_QueryTrustedDomainInfoBySid *r)
963 struct lsa_OpenTrustedDomain open;
964 struct lsa_QueryTrustedDomainInfo query;
965 struct dcesrv_handle *h;
966 open.in.handle = r->in.handle;
967 open.in.sid = r->in.dom_sid;
968 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
969 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
970 if (!open.out.trustdom_handle) {
971 return NT_STATUS_NO_MEMORY;
973 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
974 if (!NT_STATUS_IS_OK(status)) {
978 /* Ensure this handle goes away at the end of this call */
979 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
980 talloc_steal(mem_ctx, h);
982 query.in.trustdom_handle = open.out.trustdom_handle;
983 query.in.level = r->in.level;
984 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
985 if (!NT_STATUS_IS_OK(status)) {
989 r->out.info = query.out.info;
994 lsa_SetTrustedDomainInfoByName
996 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
998 struct lsa_SetTrustedDomainInfoByName *r)
1000 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1004 lsa_QueryTrustedDomainInfoByName
1006 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1007 TALLOC_CTX *mem_ctx,
1008 struct lsa_QueryTrustedDomainInfoByName *r)
1011 struct lsa_OpenTrustedDomainByName open;
1012 struct lsa_QueryTrustedDomainInfo query;
1013 struct dcesrv_handle *h;
1014 open.in.handle = r->in.handle;
1015 open.in.name = r->in.trusted_domain;
1016 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1017 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1018 if (!open.out.trustdom_handle) {
1019 return NT_STATUS_NO_MEMORY;
1021 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1022 if (!NT_STATUS_IS_OK(status)) {
1026 /* Ensure this handle goes away at the end of this call */
1027 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1028 talloc_steal(mem_ctx, h);
1030 query.in.trustdom_handle = open.out.trustdom_handle;
1031 query.in.level = r->in.level;
1032 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1033 if (!NT_STATUS_IS_OK(status)) {
1037 r->out.info = query.out.info;
1038 return NT_STATUS_OK;
1042 lsa_CloseTrustedDomainEx
1044 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1045 TALLOC_CTX *mem_ctx,
1046 struct lsa_CloseTrustedDomainEx *r)
1048 /* The result of a bad hair day from an IDL programmer? Not
1049 * implmented in Win2k3. You should always just lsa_Close
1051 return NT_STATUS_NOT_IMPLEMENTED;
1056 comparison function for sorting lsa_DomainInformation array
1058 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1060 return strcasecmp_m(e1->name.string, e2->name.string);
1066 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1067 struct lsa_EnumTrustDom *r)
1069 struct dcesrv_handle *policy_handle;
1070 struct lsa_DomainInfo *entries;
1071 struct lsa_policy_state *policy_state;
1072 struct ldb_message **domains;
1073 const char *attrs[] = {
1075 "securityIdentifier",
1082 *r->out.resume_handle = 0;
1084 r->out.domains->domains = NULL;
1085 r->out.domains->count = 0;
1087 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1089 policy_state = policy_handle->data;
1091 /* search for all users in this domain. This could possibly be cached and
1092 resumed based on resume_key */
1093 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1094 "objectclass=trustedDomain");
1096 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1098 if (count == 0 || r->in.max_size == 0) {
1099 return NT_STATUS_OK;
1102 /* convert to lsa_TrustInformation format */
1103 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1105 return NT_STATUS_NO_MEMORY;
1107 for (i=0;i<count;i++) {
1108 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1109 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1112 /* sort the results by name */
1113 qsort(entries, count, sizeof(*entries),
1114 (comparison_fn_t)compare_DomainInfo);
1116 if (*r->in.resume_handle >= count) {
1117 *r->out.resume_handle = -1;
1119 return NT_STATUS_NO_MORE_ENTRIES;
1122 /* return the rest, limit by max_size. Note that we
1123 use the w2k3 element size value of 60 */
1124 r->out.domains->count = count - *r->in.resume_handle;
1125 r->out.domains->count = MIN(r->out.domains->count,
1126 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1128 r->out.domains->domains = entries + *r->in.resume_handle;
1129 r->out.domains->count = r->out.domains->count;
1131 if (r->out.domains->count < count - *r->in.resume_handle) {
1132 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1133 return STATUS_MORE_ENTRIES;
1136 return NT_STATUS_OK;
1140 comparison function for sorting lsa_DomainInformation array
1142 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1144 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1148 lsa_EnumTrustedDomainsEx
1150 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1151 struct lsa_EnumTrustedDomainsEx *r)
1153 struct dcesrv_handle *policy_handle;
1154 struct lsa_TrustDomainInfoInfoEx *entries;
1155 struct lsa_policy_state *policy_state;
1156 struct ldb_message **domains;
1157 const char *attrs[] = {
1160 "securityIdentifier",
1170 *r->out.resume_handle = 0;
1172 r->out.domains->domains = NULL;
1173 r->out.domains->count = 0;
1175 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1177 policy_state = policy_handle->data;
1179 /* search for all users in this domain. This could possibly be cached and
1180 resumed based on resume_key */
1181 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1182 "objectclass=trustedDomain");
1184 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1186 if (count == 0 || r->in.max_size == 0) {
1187 return NT_STATUS_OK;
1190 /* convert to lsa_DomainInformation format */
1191 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1193 return NT_STATUS_NO_MEMORY;
1195 for (i=0;i<count;i++) {
1196 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1197 if (!NT_STATUS_IS_OK(nt_status)) {
1202 /* sort the results by name */
1203 qsort(entries, count, sizeof(*entries),
1204 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1206 if (*r->in.resume_handle >= count) {
1207 *r->out.resume_handle = -1;
1209 return NT_STATUS_NO_MORE_ENTRIES;
1212 /* return the rest, limit by max_size. Note that we
1213 use the w2k3 element size value of 60 */
1214 r->out.domains->count = count - *r->in.resume_handle;
1215 r->out.domains->count = MIN(r->out.domains->count,
1216 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1218 r->out.domains->domains = entries + *r->in.resume_handle;
1219 r->out.domains->count = r->out.domains->count;
1221 if (r->out.domains->count < count - *r->in.resume_handle) {
1222 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1223 return STATUS_MORE_ENTRIES;
1226 return NT_STATUS_OK;
1233 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1234 struct lsa_OpenAccount *r)
1236 struct dcesrv_handle *h, *ah;
1237 struct lsa_policy_state *state;
1238 struct lsa_account_state *astate;
1240 ZERO_STRUCTP(r->out.acct_handle);
1242 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1246 astate = talloc(dce_call->conn, struct lsa_account_state);
1247 if (astate == NULL) {
1248 return NT_STATUS_NO_MEMORY;
1251 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1252 if (astate->account_sid == NULL) {
1253 talloc_free(astate);
1254 return NT_STATUS_NO_MEMORY;
1257 astate->policy = talloc_reference(astate, state);
1258 astate->access_mask = r->in.access_mask;
1260 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1262 talloc_free(astate);
1263 return NT_STATUS_NO_MEMORY;
1266 ah->data = talloc_steal(ah, astate);
1268 *r->out.acct_handle = ah->wire_handle;
1270 return NT_STATUS_OK;
1275 lsa_EnumPrivsAccount
1277 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1278 TALLOC_CTX *mem_ctx,
1279 struct lsa_EnumPrivsAccount *r)
1281 struct dcesrv_handle *h;
1282 struct lsa_account_state *astate;
1284 struct ldb_message **res;
1285 const char * const attrs[] = { "privilege", NULL};
1286 struct ldb_message_element *el;
1289 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1293 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1294 r->out.privs->count = 0;
1295 r->out.privs->unknown = 0;
1296 r->out.privs->set = NULL;
1298 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1299 if (sidstr == NULL) {
1300 return NT_STATUS_NO_MEMORY;
1303 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1304 "objectSid=%s", sidstr);
1306 return NT_STATUS_OK;
1309 el = ldb_msg_find_element(res[0], "privilege");
1310 if (el == NULL || el->num_values == 0) {
1311 return NT_STATUS_OK;
1314 r->out.privs->set = talloc_array(r->out.privs,
1315 struct lsa_LUIDAttribute, el->num_values);
1316 if (r->out.privs->set == NULL) {
1317 return NT_STATUS_NO_MEMORY;
1320 for (i=0;i<el->num_values;i++) {
1321 int id = sec_privilege_id((const char *)el->values[i].data);
1323 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1325 r->out.privs->set[i].attribute = 0;
1326 r->out.privs->set[i].luid.low = id;
1327 r->out.privs->set[i].luid.high = 0;
1330 r->out.privs->count = el->num_values;
1332 return NT_STATUS_OK;
1336 lsa_EnumAccountRights
1338 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1339 TALLOC_CTX *mem_ctx,
1340 struct lsa_EnumAccountRights *r)
1342 struct dcesrv_handle *h;
1343 struct lsa_policy_state *state;
1345 struct ldb_message **res;
1346 const char * const attrs[] = { "privilege", NULL};
1348 struct ldb_message_element *el;
1350 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1354 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1355 if (sidstr == NULL) {
1356 return NT_STATUS_NO_MEMORY;
1359 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1360 "(&(objectSid=%s)(privilege=*))", sidstr);
1362 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1365 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1368 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1369 dom_sid_string(mem_ctx, r->in.sid),
1370 ldb_errstring(state->sam_ldb)));
1371 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1374 el = ldb_msg_find_element(res[0], "privilege");
1375 if (el == NULL || el->num_values == 0) {
1376 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1379 r->out.rights->count = el->num_values;
1380 r->out.rights->names = talloc_array(r->out.rights,
1381 struct lsa_StringLarge, r->out.rights->count);
1382 if (r->out.rights->names == NULL) {
1383 return NT_STATUS_NO_MEMORY;
1386 for (i=0;i<el->num_values;i++) {
1387 r->out.rights->names[i].string = (const char *)el->values[i].data;
1390 return NT_STATUS_OK;
1396 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1398 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1399 TALLOC_CTX *mem_ctx,
1400 struct lsa_policy_state *state,
1402 struct dom_sid *sid,
1403 const struct lsa_RightSet *rights)
1406 struct ldb_message *msg;
1407 struct ldb_message_element *el;
1409 struct lsa_EnumAccountRights r2;
1411 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1412 if (sidstr == NULL) {
1413 return NT_STATUS_NO_MEMORY;
1416 msg = ldb_msg_new(mem_ctx);
1418 return NT_STATUS_NO_MEMORY;
1421 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1422 NULL, "objectSid=%s", sidstr);
1423 if (msg->dn == NULL) {
1425 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1426 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1428 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1430 if (!NT_STATUS_IS_OK(status)) {
1433 return NT_STATUS_NO_SUCH_USER;
1436 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1437 return NT_STATUS_NO_MEMORY;
1440 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1443 r2.in.handle = &state->handle->wire_handle;
1445 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1447 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1448 if (!NT_STATUS_IS_OK(status)) {
1449 ZERO_STRUCTP(r2.out.rights);
1453 for (i=0;i<rights->count;i++) {
1454 if (sec_privilege_id(rights->names[i].string) == -1) {
1455 return NT_STATUS_NO_SUCH_PRIVILEGE;
1458 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1460 for (j=0;j<r2.out.rights->count;j++) {
1461 if (strcasecmp_m(r2.out.rights->names[j].string,
1462 rights->names[i].string) == 0) {
1466 if (j != r2.out.rights->count) continue;
1469 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1470 if (ret != LDB_SUCCESS) {
1471 return NT_STATUS_NO_MEMORY;
1475 el = ldb_msg_find_element(msg, "privilege");
1477 return NT_STATUS_OK;
1480 ret = samdb_modify(state->sam_ldb, mem_ctx, msg);
1482 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1483 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1485 DEBUG(3, ("Could not %s attributes from %s: %s",
1486 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1487 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1488 return NT_STATUS_UNEXPECTED_IO_ERROR;
1491 return NT_STATUS_OK;
1495 lsa_AddPrivilegesToAccount
1497 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1498 struct lsa_AddPrivilegesToAccount *r)
1500 struct lsa_RightSet rights;
1501 struct dcesrv_handle *h;
1502 struct lsa_account_state *astate;
1505 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1509 rights.count = r->in.privs->count;
1510 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1511 if (rights.names == NULL) {
1512 return NT_STATUS_NO_MEMORY;
1514 for (i=0;i<rights.count;i++) {
1515 int id = r->in.privs->set[i].luid.low;
1516 if (r->in.privs->set[i].luid.high) {
1517 return NT_STATUS_NO_SUCH_PRIVILEGE;
1519 rights.names[i].string = sec_privilege_name(id);
1520 if (rights.names[i].string == NULL) {
1521 return NT_STATUS_NO_SUCH_PRIVILEGE;
1525 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1526 LDB_FLAG_MOD_ADD, astate->account_sid,
1532 lsa_RemovePrivilegesFromAccount
1534 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1535 struct lsa_RemovePrivilegesFromAccount *r)
1537 struct lsa_RightSet *rights;
1538 struct dcesrv_handle *h;
1539 struct lsa_account_state *astate;
1542 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1546 rights = talloc(mem_ctx, struct lsa_RightSet);
1548 if (r->in.remove_all == 1 &&
1549 r->in.privs == NULL) {
1550 struct lsa_EnumAccountRights r2;
1553 r2.in.handle = &astate->policy->handle->wire_handle;
1554 r2.in.sid = astate->account_sid;
1555 r2.out.rights = rights;
1557 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1558 if (!NT_STATUS_IS_OK(status)) {
1562 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1563 LDB_FLAG_MOD_DELETE, astate->account_sid,
1567 if (r->in.remove_all != 0) {
1568 return NT_STATUS_INVALID_PARAMETER;
1571 rights->count = r->in.privs->count;
1572 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
1573 if (rights->names == NULL) {
1574 return NT_STATUS_NO_MEMORY;
1576 for (i=0;i<rights->count;i++) {
1577 int id = r->in.privs->set[i].luid.low;
1578 if (r->in.privs->set[i].luid.high) {
1579 return NT_STATUS_NO_SUCH_PRIVILEGE;
1581 rights->names[i].string = sec_privilege_name(id);
1582 if (rights->names[i].string == NULL) {
1583 return NT_STATUS_NO_SUCH_PRIVILEGE;
1587 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1588 LDB_FLAG_MOD_DELETE, astate->account_sid,
1594 lsa_GetQuotasForAccount
1596 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1597 struct lsa_GetQuotasForAccount *r)
1599 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1604 lsa_SetQuotasForAccount
1606 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1607 struct lsa_SetQuotasForAccount *r)
1609 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1614 lsa_GetSystemAccessAccount
1616 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1617 struct lsa_GetSystemAccessAccount *r)
1619 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1624 lsa_SetSystemAccessAccount
1626 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1627 struct lsa_SetSystemAccessAccount *r)
1629 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1636 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1637 struct lsa_CreateSecret *r)
1639 struct dcesrv_handle *policy_handle;
1640 struct lsa_policy_state *policy_state;
1641 struct lsa_secret_state *secret_state;
1642 struct dcesrv_handle *handle;
1643 struct ldb_message **msgs, *msg;
1645 const char *attrs[] = {
1653 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1654 ZERO_STRUCTP(r->out.sec_handle);
1656 policy_state = policy_handle->data;
1658 if (!r->in.name.string) {
1659 return NT_STATUS_INVALID_PARAMETER;
1662 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1663 if (!secret_state) {
1664 return NT_STATUS_NO_MEMORY;
1666 secret_state->policy = policy_state;
1668 msg = ldb_msg_new(mem_ctx);
1670 return NT_STATUS_NO_MEMORY;
1673 if (strncmp("G$", r->in.name.string, 2) == 0) {
1675 name = &r->in.name.string[2];
1676 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1677 secret_state->global = true;
1679 if (strlen(name) < 1) {
1680 return NT_STATUS_INVALID_PARAMETER;
1683 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
1684 /* search for the secret record */
1685 ret = gendb_search(secret_state->sam_ldb,
1686 mem_ctx, policy_state->system_dn, &msgs, attrs,
1687 "(&(cn=%s)(objectclass=secret))",
1690 return NT_STATUS_OBJECT_NAME_COLLISION;
1694 DEBUG(0,("Failure searching for CN=%s: %s\n",
1695 name2, ldb_errstring(secret_state->sam_ldb)));
1696 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1699 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1700 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
1701 return NT_STATUS_NO_MEMORY;
1704 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
1707 secret_state->global = false;
1709 name = r->in.name.string;
1710 if (strlen(name) < 1) {
1711 return NT_STATUS_INVALID_PARAMETER;
1714 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1715 /* search for the secret record */
1716 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1717 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1719 "(&(cn=%s)(objectclass=secret))",
1720 ldb_binary_encode_string(mem_ctx, name));
1722 return NT_STATUS_OBJECT_NAME_COLLISION;
1726 DEBUG(0,("Failure searching for CN=%s: %s\n",
1727 name, ldb_errstring(secret_state->sam_ldb)));
1728 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1731 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
1732 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
1735 /* pull in all the template attributes. Note this is always from the global samdb */
1736 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
1739 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
1741 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1744 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
1746 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1748 /* create the secret */
1749 ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
1751 DEBUG(0,("Failed to create secret record %s: %s\n",
1752 ldb_dn_get_linearized(msg->dn),
1753 ldb_errstring(secret_state->sam_ldb)));
1754 return NT_STATUS_ACCESS_DENIED;
1757 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1759 return NT_STATUS_NO_MEMORY;
1762 handle->data = talloc_steal(handle, secret_state);
1764 secret_state->access_mask = r->in.access_mask;
1765 secret_state->policy = talloc_reference(secret_state, policy_state);
1767 *r->out.sec_handle = handle->wire_handle;
1769 return NT_STATUS_OK;
1776 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1777 struct lsa_OpenSecret *r)
1779 struct dcesrv_handle *policy_handle;
1781 struct lsa_policy_state *policy_state;
1782 struct lsa_secret_state *secret_state;
1783 struct dcesrv_handle *handle;
1784 struct ldb_message **msgs;
1785 const char *attrs[] = {
1793 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1794 ZERO_STRUCTP(r->out.sec_handle);
1795 policy_state = policy_handle->data;
1797 if (!r->in.name.string) {
1798 return NT_STATUS_INVALID_PARAMETER;
1801 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1802 if (!secret_state) {
1803 return NT_STATUS_NO_MEMORY;
1805 secret_state->policy = policy_state;
1807 if (strncmp("G$", r->in.name.string, 2) == 0) {
1808 name = &r->in.name.string[2];
1809 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1810 secret_state->global = true;
1812 if (strlen(name) < 1) {
1813 return NT_STATUS_INVALID_PARAMETER;
1816 /* search for the secret record */
1817 ret = gendb_search(secret_state->sam_ldb,
1818 mem_ctx, policy_state->system_dn, &msgs, attrs,
1819 "(&(cn=%s Secret)(objectclass=secret))",
1820 ldb_binary_encode_string(mem_ctx, name));
1822 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1826 DEBUG(0,("Found %d records matching DN %s\n", ret,
1827 ldb_dn_get_linearized(policy_state->system_dn)));
1828 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1832 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1834 secret_state->global = false;
1835 name = r->in.name.string;
1836 if (strlen(name) < 1) {
1837 return NT_STATUS_INVALID_PARAMETER;
1840 /* search for the secret record */
1841 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1842 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1844 "(&(cn=%s)(objectclass=secret))",
1845 ldb_binary_encode_string(mem_ctx, name));
1847 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1851 DEBUG(0,("Found %d records matching CN=%s\n",
1852 ret, ldb_binary_encode_string(mem_ctx, name)));
1853 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1857 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1859 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1861 return NT_STATUS_NO_MEMORY;
1864 handle->data = talloc_steal(handle, secret_state);
1866 secret_state->access_mask = r->in.access_mask;
1867 secret_state->policy = talloc_reference(secret_state, policy_state);
1869 *r->out.sec_handle = handle->wire_handle;
1871 return NT_STATUS_OK;
1878 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1879 struct lsa_SetSecret *r)
1882 struct dcesrv_handle *h;
1883 struct lsa_secret_state *secret_state;
1884 struct ldb_message *msg;
1885 DATA_BLOB session_key;
1886 DATA_BLOB crypt_secret, secret;
1889 NTSTATUS status = NT_STATUS_OK;
1891 struct timeval now = timeval_current();
1892 NTTIME nt_now = timeval_to_nttime(&now);
1894 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
1896 secret_state = h->data;
1898 msg = ldb_msg_new(mem_ctx);
1900 return NT_STATUS_NO_MEMORY;
1903 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
1905 return NT_STATUS_NO_MEMORY;
1907 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
1908 if (!NT_STATUS_IS_OK(status)) {
1912 if (r->in.old_val) {
1914 crypt_secret.data = r->in.old_val->data;
1915 crypt_secret.length = r->in.old_val->size;
1917 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1918 if (!NT_STATUS_IS_OK(status)) {
1922 val.data = secret.data;
1923 val.length = secret.length;
1926 if (samdb_msg_add_value(secret_state->sam_ldb,
1927 mem_ctx, msg, "priorValue", &val) != 0) {
1928 return NT_STATUS_NO_MEMORY;
1931 /* set old value mtime */
1932 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1933 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
1934 return NT_STATUS_NO_MEMORY;
1937 if (!r->in.new_val) {
1938 /* This behaviour varies depending of if this is a local, or a global secret... */
1939 if (secret_state->global) {
1940 /* set old value mtime */
1941 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1942 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
1943 return NT_STATUS_NO_MEMORY;
1946 if (samdb_msg_add_delete(secret_state->sam_ldb,
1947 mem_ctx, msg, "currentValue")) {
1948 return NT_STATUS_NO_MEMORY;
1950 if (samdb_msg_add_delete(secret_state->sam_ldb,
1951 mem_ctx, msg, "lastSetTime")) {
1952 return NT_STATUS_NO_MEMORY;
1958 if (r->in.new_val) {
1960 crypt_secret.data = r->in.new_val->data;
1961 crypt_secret.length = r->in.new_val->size;
1963 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1964 if (!NT_STATUS_IS_OK(status)) {
1968 val.data = secret.data;
1969 val.length = secret.length;
1972 if (samdb_msg_add_value(secret_state->sam_ldb,
1973 mem_ctx, msg, "currentValue", &val) != 0) {
1974 return NT_STATUS_NO_MEMORY;
1977 /* set new value mtime */
1978 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1979 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
1980 return NT_STATUS_NO_MEMORY;
1983 /* If the old value is not set, then migrate the
1984 * current value to the old value */
1985 if (!r->in.old_val) {
1986 const struct ldb_val *new_val;
1987 NTTIME last_set_time;
1988 struct ldb_message **res;
1989 const char *attrs[] = {
1995 /* search for the secret record */
1996 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
1997 secret_state->secret_dn, &res, attrs);
1999 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2003 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2004 ldb_dn_get_linearized(secret_state->secret_dn)));
2005 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2008 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2009 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2013 if (samdb_msg_add_value(secret_state->sam_ldb,
2014 mem_ctx, msg, "priorValue",
2016 return NT_STATUS_NO_MEMORY;
2020 /* set new value mtime */
2021 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2022 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2023 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2024 return NT_STATUS_NO_MEMORY;
2030 /* modify the samdb record */
2031 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2033 /* we really need samdb.c to return NTSTATUS */
2034 return NT_STATUS_UNSUCCESSFUL;
2037 return NT_STATUS_OK;
2044 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2045 struct lsa_QuerySecret *r)
2047 struct dcesrv_handle *h;
2048 struct lsa_secret_state *secret_state;
2049 struct ldb_message *msg;
2050 DATA_BLOB session_key;
2051 DATA_BLOB crypt_secret, secret;
2053 struct ldb_message **res;
2054 const char *attrs[] = {
2064 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2066 secret_state = h->data;
2068 /* pull all the user attributes */
2069 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2070 secret_state->secret_dn, &res, attrs);
2072 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2076 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2077 if (!NT_STATUS_IS_OK(nt_status)) {
2081 if (r->in.old_val) {
2082 const struct ldb_val *prior_val;
2083 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2084 if (!r->out.old_val) {
2085 return NT_STATUS_NO_MEMORY;
2087 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2089 if (prior_val && prior_val->length) {
2090 secret.data = prior_val->data;
2091 secret.length = prior_val->length;
2094 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2095 if (!crypt_secret.length) {
2096 return NT_STATUS_NO_MEMORY;
2098 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2099 if (!r->out.old_val->buf) {
2100 return NT_STATUS_NO_MEMORY;
2102 r->out.old_val->buf->size = crypt_secret.length;
2103 r->out.old_val->buf->length = crypt_secret.length;
2104 r->out.old_val->buf->data = crypt_secret.data;
2108 if (r->in.old_mtime) {
2109 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2110 if (!r->out.old_mtime) {
2111 return NT_STATUS_NO_MEMORY;
2113 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2116 if (r->in.new_val) {
2117 const struct ldb_val *new_val;
2118 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2119 if (!r->out.new_val) {
2120 return NT_STATUS_NO_MEMORY;
2123 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2125 if (new_val && new_val->length) {
2126 secret.data = new_val->data;
2127 secret.length = new_val->length;
2130 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2131 if (!crypt_secret.length) {
2132 return NT_STATUS_NO_MEMORY;
2134 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2135 if (!r->out.new_val->buf) {
2136 return NT_STATUS_NO_MEMORY;
2138 r->out.new_val->buf->length = crypt_secret.length;
2139 r->out.new_val->buf->size = crypt_secret.length;
2140 r->out.new_val->buf->data = crypt_secret.data;
2144 if (r->in.new_mtime) {
2145 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2146 if (!r->out.new_mtime) {
2147 return NT_STATUS_NO_MEMORY;
2149 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2152 return NT_STATUS_OK;
2159 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2160 TALLOC_CTX *mem_ctx,
2161 struct lsa_LookupPrivValue *r)
2163 struct dcesrv_handle *h;
2164 struct lsa_policy_state *state;
2167 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2171 id = sec_privilege_id(r->in.name->string);
2173 return NT_STATUS_NO_SUCH_PRIVILEGE;
2176 r->out.luid->low = id;
2177 r->out.luid->high = 0;
2179 return NT_STATUS_OK;
2186 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2187 TALLOC_CTX *mem_ctx,
2188 struct lsa_LookupPrivName *r)
2190 struct dcesrv_handle *h;
2191 struct lsa_policy_state *state;
2192 const char *privname;
2194 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2198 if (r->in.luid->high != 0) {
2199 return NT_STATUS_NO_SUCH_PRIVILEGE;
2202 privname = sec_privilege_name(r->in.luid->low);
2203 if (privname == NULL) {
2204 return NT_STATUS_NO_SUCH_PRIVILEGE;
2207 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2208 if (r->out.name == NULL) {
2209 return NT_STATUS_NO_MEMORY;
2211 r->out.name->string = privname;
2213 return NT_STATUS_OK;
2218 lsa_LookupPrivDisplayName
2220 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2221 TALLOC_CTX *mem_ctx,
2222 struct lsa_LookupPrivDisplayName *r)
2224 struct dcesrv_handle *h;
2225 struct lsa_policy_state *state;
2228 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2232 id = sec_privilege_id(r->in.name->string);
2234 return NT_STATUS_NO_SUCH_PRIVILEGE;
2237 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2238 if (r->out.disp_name == NULL) {
2239 return NT_STATUS_NO_MEMORY;
2242 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2243 if (r->out.disp_name->string == NULL) {
2244 return NT_STATUS_INTERNAL_ERROR;
2247 return NT_STATUS_OK;
2254 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2255 struct lsa_DeleteObject *r)
2257 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2262 lsa_EnumAccountsWithUserRight
2264 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2265 TALLOC_CTX *mem_ctx,
2266 struct lsa_EnumAccountsWithUserRight *r)
2268 struct dcesrv_handle *h;
2269 struct lsa_policy_state *state;
2271 struct ldb_message **res;
2272 const char * const attrs[] = { "objectSid", NULL};
2273 const char *privname;
2275 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2279 if (r->in.name == NULL) {
2280 return NT_STATUS_NO_SUCH_PRIVILEGE;
2283 privname = r->in.name->string;
2284 if (sec_privilege_id(privname) == -1) {
2285 return NT_STATUS_NO_SUCH_PRIVILEGE;
2288 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2289 "privilege=%s", privname);
2291 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2294 return NT_STATUS_NO_MORE_ENTRIES;
2297 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2298 if (r->out.sids->sids == NULL) {
2299 return NT_STATUS_NO_MEMORY;
2301 for (i=0;i<ret;i++) {
2302 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2303 res[i], "objectSid");
2304 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2306 r->out.sids->num_sids = ret;
2308 return NT_STATUS_OK;
2313 lsa_AddAccountRights
2315 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2316 TALLOC_CTX *mem_ctx,
2317 struct lsa_AddAccountRights *r)
2319 struct dcesrv_handle *h;
2320 struct lsa_policy_state *state;
2322 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2326 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2328 r->in.sid, r->in.rights);
2333 lsa_RemoveAccountRights
2335 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2336 TALLOC_CTX *mem_ctx,
2337 struct lsa_RemoveAccountRights *r)
2339 struct dcesrv_handle *h;
2340 struct lsa_policy_state *state;
2342 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2346 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2347 LDB_FLAG_MOD_DELETE,
2348 r->in.sid, r->in.rights);
2353 lsa_StorePrivateData
2355 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2356 struct lsa_StorePrivateData *r)
2358 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2363 lsa_RetrievePrivateData
2365 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2366 struct lsa_RetrievePrivateData *r)
2368 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2375 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2376 struct lsa_GetUserName *r)
2378 NTSTATUS status = NT_STATUS_OK;
2379 const char *account_name;
2380 const char *authority_name;
2381 struct lsa_String *_account_name;
2382 struct lsa_StringPointer *_authority_name = NULL;
2384 /* this is what w2k3 does */
2385 r->out.account_name = r->in.account_name;
2386 r->out.authority_name = r->in.authority_name;
2388 if (r->in.account_name && r->in.account_name->string) {
2389 return NT_STATUS_INVALID_PARAMETER;
2392 if (r->in.authority_name &&
2393 r->in.authority_name->string &&
2394 r->in.authority_name->string->string) {
2395 return NT_STATUS_INVALID_PARAMETER;
2398 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2399 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2401 _account_name = talloc(mem_ctx, struct lsa_String);
2402 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2403 _account_name->string = account_name;
2405 if (r->in.authority_name) {
2406 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2407 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2408 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2409 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2410 _authority_name->string->string = authority_name;
2413 r->out.account_name = _account_name;
2414 r->out.authority_name = _authority_name;
2422 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2423 TALLOC_CTX *mem_ctx,
2424 struct lsa_SetInfoPolicy2 *r)
2426 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2430 lsa_QueryDomainInformationPolicy
2432 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2433 TALLOC_CTX *mem_ctx,
2434 struct lsa_QueryDomainInformationPolicy *r)
2436 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2440 lsa_SetDomInfoPolicy
2442 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2443 TALLOC_CTX *mem_ctx,
2444 struct lsa_SetDomainInformationPolicy *r)
2446 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2452 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
2453 TALLOC_CTX *mem_ctx,
2454 struct lsa_TestCall *r)
2456 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2462 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2463 struct lsa_CREDRWRITE *r)
2465 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2472 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2473 struct lsa_CREDRREAD *r)
2475 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2482 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2483 struct lsa_CREDRENUMERATE *r)
2485 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2490 lsa_CREDRWRITEDOMAINCREDENTIALS
2492 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2493 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2495 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2500 lsa_CREDRREADDOMAINCREDENTIALS
2502 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2503 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2505 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2512 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2513 struct lsa_CREDRDELETE *r)
2515 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2520 lsa_CREDRGETTARGETINFO
2522 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2523 struct lsa_CREDRGETTARGETINFO *r)
2525 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2530 lsa_CREDRPROFILELOADED
2532 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2533 struct lsa_CREDRPROFILELOADED *r)
2535 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2540 lsa_CREDRGETSESSIONTYPES
2542 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2543 struct lsa_CREDRGETSESSIONTYPES *r)
2545 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2550 lsa_LSARREGISTERAUDITEVENT
2552 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2553 struct lsa_LSARREGISTERAUDITEVENT *r)
2555 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2560 lsa_LSARGENAUDITEVENT
2562 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2563 struct lsa_LSARGENAUDITEVENT *r)
2565 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2570 lsa_LSARUNREGISTERAUDITEVENT
2572 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2573 struct lsa_LSARUNREGISTERAUDITEVENT *r)
2575 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2580 lsa_lsaRQueryForestTrustInformation
2582 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2583 struct lsa_lsaRQueryForestTrustInformation *r)
2585 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2590 lsa_LSARSETFORESTTRUSTINFORMATION
2592 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2593 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2595 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2602 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2603 struct lsa_CREDRRENAME *r)
2605 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2611 lsa_LSAROPENPOLICYSCE
2613 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2614 struct lsa_LSAROPENPOLICYSCE *r)
2616 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2621 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
2623 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2624 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2626 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2631 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
2633 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2634 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2636 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2641 lsa_LSARADTREPORTSECURITYEVENT
2643 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2644 struct lsa_LSARADTREPORTSECURITYEVENT *r)
2646 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2650 /* include the generated boilerplate */
2651 #include "librpc/gen_ndr/ndr_lsa_s.c"
2655 /*****************************************
2656 NOTE! The remaining calls below were
2657 removed in w2k3, so the DCESRV_FAULT()
2658 replies are the correct implementation. Do
2659 not try and fill these in with anything else
2660 ******************************************/
2663 dssetup_DsRoleDnsNameToFlatName
2665 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2666 struct dssetup_DsRoleDnsNameToFlatName *r)
2668 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2673 dssetup_DsRoleDcAsDc
2675 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2676 struct dssetup_DsRoleDcAsDc *r)
2678 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2683 dssetup_DsRoleDcAsReplica
2685 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2686 struct dssetup_DsRoleDcAsReplica *r)
2688 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2693 dssetup_DsRoleDemoteDc
2695 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2696 struct dssetup_DsRoleDemoteDc *r)
2698 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2703 dssetup_DsRoleGetDcOperationProgress
2705 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2706 struct dssetup_DsRoleGetDcOperationProgress *r)
2708 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2713 dssetup_DsRoleGetDcOperationResults
2715 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2716 struct dssetup_DsRoleGetDcOperationResults *r)
2718 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2723 dssetup_DsRoleCancel
2725 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2726 struct dssetup_DsRoleCancel *r)
2728 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2733 dssetup_DsRoleServerSaveStateForUpgrade
2735 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2736 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
2738 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2743 dssetup_DsRoleUpgradeDownlevelServer
2745 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2746 struct dssetup_DsRoleUpgradeDownlevelServer *r)
2748 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2753 dssetup_DsRoleAbortDownlevelServerUpgrade
2755 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2756 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
2758 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2762 /* include the generated boilerplate */
2763 #include "librpc/gen_ndr/ndr_dssetup_s.c"
2765 NTSTATUS dcerpc_server_lsa_init(void)
2769 ret = dcerpc_server_dssetup_init();
2770 if (!NT_STATUS_IS_OK(ret)) {
2773 ret = dcerpc_server_lsarpc_init();
2774 if (!NT_STATUS_IS_OK(ret)) {