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"
27 this type allows us to distinguish handle types
31 state associated with a lsa_OpenAccount() operation
33 struct lsa_account_state {
34 struct lsa_policy_state *policy;
36 struct dom_sid *account_sid;
41 state associated with a lsa_OpenSecret() operation
43 struct lsa_secret_state {
44 struct lsa_policy_state *policy;
46 struct ldb_dn *secret_dn;
47 struct ldb_context *sam_ldb;
52 state associated with a lsa_OpenTrustedDomain() operation
54 struct lsa_trusted_domain_state {
55 struct lsa_policy_state *policy;
57 struct ldb_dn *trusted_domain_dn;
60 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
62 struct lsa_EnumAccountRights *r);
64 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
66 struct lsa_policy_state *state,
69 const struct lsa_RightSet *rights);
74 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
77 struct dcesrv_handle *h;
79 *r->out.handle = *r->in.handle;
81 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
85 ZERO_STRUCTP(r->out.handle);
94 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
97 struct dcesrv_handle *h;
100 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
101 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
102 struct lsa_secret_state *secret_state = h->data;
103 ret = ldb_delete(secret_state->sam_ldb,
104 secret_state->secret_dn);
107 return NT_STATUS_INVALID_HANDLE;
111 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
112 struct lsa_trusted_domain_state *trusted_domain_state = h->data;
113 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
114 trusted_domain_state->trusted_domain_dn);
117 return NT_STATUS_INVALID_HANDLE;
121 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
122 struct lsa_RightSet *rights;
123 struct lsa_account_state *astate;
124 struct lsa_EnumAccountRights r2;
127 rights = talloc(mem_ctx, struct lsa_RightSet);
129 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
133 r2.in.handle = &astate->policy->handle->wire_handle;
134 r2.in.sid = astate->account_sid;
135 r2.out.rights = rights;
137 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
138 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
142 if (!NT_STATUS_IS_OK(status)) {
146 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
147 LDB_FLAG_MOD_DELETE, astate->account_sid,
149 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
153 if (!NT_STATUS_IS_OK(status)) {
158 return NT_STATUS_INVALID_HANDLE;
165 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
166 struct lsa_EnumPrivs *r)
168 struct dcesrv_handle *h;
169 struct lsa_policy_state *state;
171 const char *privname;
173 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
177 i = *r->in.resume_handle;
180 while ((privname = sec_privilege_name(i)) &&
181 r->out.privs->count < r->in.max_count) {
182 struct lsa_PrivEntry *e;
184 r->out.privs->privs = talloc_realloc(r->out.privs,
186 struct lsa_PrivEntry,
187 r->out.privs->count+1);
188 if (r->out.privs->privs == NULL) {
189 return NT_STATUS_NO_MEMORY;
191 e = &r->out.privs->privs[r->out.privs->count];
194 e->name.string = privname;
195 r->out.privs->count++;
199 *r->out.resume_handle = i;
208 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
209 struct lsa_QuerySecurity *r)
211 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
218 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
219 struct lsa_SetSecObj *r)
221 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
228 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
229 struct lsa_ChangePassword *r)
231 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
235 dssetup_DsRoleGetPrimaryDomainInformation
237 This is not an LSA call, but is the only call left on the DSSETUP
238 pipe (after the pipe was truncated), and needs lsa_get_policy_state
240 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
242 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
244 union dssetup_DsRoleInfo *info;
246 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
247 W_ERROR_HAVE_NO_MEMORY(info);
249 switch (r->in.level) {
250 case DS_ROLE_BASIC_INFORMATION:
252 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
254 const char *domain = NULL;
255 const char *dns_domain = NULL;
256 const char *forest = NULL;
257 struct GUID domain_guid;
258 struct lsa_policy_state *state;
260 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
261 if (!NT_STATUS_IS_OK(status)) {
262 return ntstatus_to_werror(status);
265 ZERO_STRUCT(domain_guid);
267 switch (lp_server_role(global_loadparm)) {
268 case ROLE_STANDALONE:
269 role = DS_ROLE_STANDALONE_SERVER;
271 case ROLE_DOMAIN_MEMBER:
272 role = DS_ROLE_MEMBER_SERVER;
274 case ROLE_DOMAIN_CONTROLLER:
275 if (samdb_is_pdc(state->sam_ldb)) {
276 role = DS_ROLE_PRIMARY_DC;
278 role = DS_ROLE_BACKUP_DC;
283 switch (lp_server_role(global_loadparm)) {
284 case ROLE_STANDALONE:
285 domain = talloc_strdup(mem_ctx, lp_workgroup(global_loadparm));
286 W_ERROR_HAVE_NO_MEMORY(domain);
288 case ROLE_DOMAIN_MEMBER:
289 domain = talloc_strdup(mem_ctx, lp_workgroup(global_loadparm));
290 W_ERROR_HAVE_NO_MEMORY(domain);
291 /* TODO: what is with dns_domain and forest and guid? */
293 case ROLE_DOMAIN_CONTROLLER:
294 flags = DS_ROLE_PRIMARY_DS_RUNNING;
296 if (state->mixed_domain == 1) {
297 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
300 domain = state->domain_name;
301 dns_domain = state->domain_dns;
302 forest = state->forest_dns;
304 domain_guid = state->domain_guid;
305 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
309 info->basic.role = role;
310 info->basic.flags = flags;
311 info->basic.domain = domain;
312 info->basic.dns_domain = dns_domain;
313 info->basic.forest = forest;
314 info->basic.domain_guid = domain_guid;
319 case DS_ROLE_UPGRADE_STATUS:
321 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
322 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
327 case DS_ROLE_OP_STATUS:
329 info->opstatus.status = DS_ROLE_OP_IDLE;
335 return WERR_INVALID_PARAM;
338 return WERR_INVALID_PARAM;
343 fill in the AccountDomain info
345 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
346 struct lsa_DomainInfo *info)
348 info->name.string = state->domain_name;
349 info->sid = state->domain_sid;
355 fill in the DNS domain info
357 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
358 struct lsa_DnsDomainInfo *info)
360 info->name.string = state->domain_name;
361 info->sid = state->domain_sid;
362 info->dns_domain.string = state->domain_dns;
363 info->dns_forest.string = state->forest_dns;
364 info->domain_guid = state->domain_guid;
372 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
373 struct lsa_QueryInfoPolicy2 *r)
375 struct lsa_policy_state *state;
376 struct dcesrv_handle *h;
380 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
384 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
386 return NT_STATUS_NO_MEMORY;
389 ZERO_STRUCTP(r->out.info);
391 switch (r->in.level) {
392 case LSA_POLICY_INFO_DOMAIN:
393 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
394 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
396 case LSA_POLICY_INFO_DNS:
397 return dcesrv_lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
398 case LSA_POLICY_INFO_DB:
399 case LSA_POLICY_INFO_AUDIT_FULL_SET:
400 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
401 return NT_STATUS_INVALID_PARAMETER;
404 return NT_STATUS_INVALID_INFO_CLASS;
410 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
411 struct lsa_QueryInfoPolicy *r)
413 struct lsa_QueryInfoPolicy2 r2;
416 r2.in.handle = r->in.handle;
417 r2.in.level = r->in.level;
419 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
421 r->out.info = r2.out.info;
429 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
430 struct lsa_SetInfoPolicy *r)
432 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
439 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
440 struct lsa_ClearAuditLog *r)
442 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
449 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
450 struct lsa_CreateAccount *r)
452 struct lsa_account_state *astate;
454 struct lsa_policy_state *state;
455 struct dcesrv_handle *h, *ah;
457 ZERO_STRUCTP(r->out.acct_handle);
459 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
463 astate = talloc(dce_call->conn, struct lsa_account_state);
464 if (astate == NULL) {
465 return NT_STATUS_NO_MEMORY;
468 astate->account_sid = dom_sid_dup(astate, r->in.sid);
469 if (astate->account_sid == NULL) {
471 return NT_STATUS_NO_MEMORY;
474 astate->policy = talloc_reference(astate, state);
475 astate->access_mask = r->in.access_mask;
477 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
480 return NT_STATUS_NO_MEMORY;
483 ah->data = talloc_steal(ah, astate);
485 *r->out.acct_handle = ah->wire_handle;
494 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
495 struct lsa_EnumAccounts *r)
497 struct dcesrv_handle *h;
498 struct lsa_policy_state *state;
500 struct ldb_message **res;
501 const char * const attrs[] = { "objectSid", NULL};
504 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
508 /* NOTE: This call must only return accounts that have at least
511 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
512 "(&(objectSid=*)(privilege=*))");
514 return NT_STATUS_NO_SUCH_USER;
517 if (*r->in.resume_handle >= ret) {
518 return NT_STATUS_NO_MORE_ENTRIES;
521 count = ret - *r->in.resume_handle;
522 if (count > r->in.num_entries) {
523 count = r->in.num_entries;
527 return NT_STATUS_NO_MORE_ENTRIES;
530 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
531 if (r->out.sids->sids == NULL) {
532 return NT_STATUS_NO_MEMORY;
535 for (i=0;i<count;i++) {
536 r->out.sids->sids[i].sid =
537 samdb_result_dom_sid(r->out.sids->sids,
538 res[i + *r->in.resume_handle],
540 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
543 r->out.sids->num_sids = count;
544 *r->out.resume_handle = count + *r->in.resume_handle;
552 lsa_CreateTrustedDomainEx2
554 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
556 struct lsa_CreateTrustedDomainEx2 *r)
558 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
562 lsa_CreateTrustedDomainEx
564 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
566 struct lsa_CreateTrustedDomainEx *r)
568 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
572 lsa_CreateTrustedDomain
574 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
575 struct lsa_CreateTrustedDomain *r)
577 struct dcesrv_handle *policy_handle;
578 struct lsa_policy_state *policy_state;
579 struct lsa_trusted_domain_state *trusted_domain_state;
580 struct dcesrv_handle *handle;
581 struct ldb_message **msgs, *msg;
582 const char *attrs[] = {
588 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
589 ZERO_STRUCTP(r->out.trustdom_handle);
591 policy_state = policy_handle->data;
593 if (!r->in.info->name.string) {
594 return NT_STATUS_INVALID_PARAMETER;
596 name = r->in.info->name.string;
598 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
599 if (!trusted_domain_state) {
600 return NT_STATUS_NO_MEMORY;
602 trusted_domain_state->policy = policy_state;
604 msg = ldb_msg_new(mem_ctx);
606 return NT_STATUS_NO_MEMORY;
609 /* search for the trusted_domain record */
610 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
611 mem_ctx, policy_state->system_dn, &msgs, attrs,
612 "(&(cn=%s)(objectclass=trustedDomain))",
613 ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
615 return NT_STATUS_OBJECT_NAME_COLLISION;
618 if (ret < 0 || ret > 1) {
619 DEBUG(0,("Found %d records matching DN %s\n", ret,
620 ldb_dn_get_linearized(policy_state->system_dn)));
621 return NT_STATUS_INTERNAL_DB_CORRUPTION;
624 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
625 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
626 return NT_STATUS_NO_MEMORY;
629 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
631 if (r->in.info->sid) {
632 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
634 return NT_STATUS_NO_MEMORY;
637 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
640 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
642 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
644 /* create the trusted_domain */
645 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
646 if (ret != LDB_SUCCESS) {
647 DEBUG(0,("Failed to create trusted_domain record %s: %s\n",
648 ldb_dn_get_linearized(msg->dn), ldb_errstring(trusted_domain_state->policy->sam_ldb)));
649 return NT_STATUS_INTERNAL_DB_CORRUPTION;
652 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
654 return NT_STATUS_NO_MEMORY;
657 handle->data = talloc_steal(handle, trusted_domain_state);
659 trusted_domain_state->access_mask = r->in.access_mask;
660 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
662 *r->out.trustdom_handle = handle->wire_handle;
668 lsa_OpenTrustedDomain
670 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
671 struct lsa_OpenTrustedDomain *r)
673 struct dcesrv_handle *policy_handle;
675 struct lsa_policy_state *policy_state;
676 struct lsa_trusted_domain_state *trusted_domain_state;
677 struct dcesrv_handle *handle;
678 struct ldb_message **msgs;
679 const char *attrs[] = {
683 const char *sid_string;
686 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
687 ZERO_STRUCTP(r->out.trustdom_handle);
688 policy_state = policy_handle->data;
690 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
691 if (!trusted_domain_state) {
692 return NT_STATUS_NO_MEMORY;
694 trusted_domain_state->policy = policy_state;
696 sid_string = dom_sid_string(mem_ctx, r->in.sid);
698 return NT_STATUS_NO_MEMORY;
701 /* search for the trusted_domain record */
702 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
703 mem_ctx, policy_state->system_dn, &msgs, attrs,
704 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
707 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
711 DEBUG(0,("Found %d records matching DN %s\n", ret,
712 ldb_dn_get_linearized(policy_state->system_dn)));
713 return NT_STATUS_INTERNAL_DB_CORRUPTION;
716 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
718 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
720 return NT_STATUS_NO_MEMORY;
723 handle->data = talloc_steal(handle, trusted_domain_state);
725 trusted_domain_state->access_mask = r->in.access_mask;
726 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
728 *r->out.trustdom_handle = handle->wire_handle;
735 lsa_OpenTrustedDomainByName
737 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
739 struct lsa_OpenTrustedDomainByName *r)
741 struct dcesrv_handle *policy_handle;
743 struct lsa_policy_state *policy_state;
744 struct lsa_trusted_domain_state *trusted_domain_state;
745 struct dcesrv_handle *handle;
746 struct ldb_message **msgs;
747 const char *attrs[] = {
753 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
754 ZERO_STRUCTP(r->out.trustdom_handle);
755 policy_state = policy_handle->data;
757 if (!r->in.name.string) {
758 return NT_STATUS_INVALID_PARAMETER;
761 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
762 if (!trusted_domain_state) {
763 return NT_STATUS_NO_MEMORY;
765 trusted_domain_state->policy = policy_state;
767 /* search for the trusted_domain record */
768 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
769 mem_ctx, policy_state->system_dn, &msgs, attrs,
770 "(&(flatname=%s)(objectclass=trustedDomain))",
771 ldb_binary_encode_string(mem_ctx, r->in.name.string));
773 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
777 DEBUG(0,("Found %d records matching DN %s\n", ret,
778 ldb_dn_get_linearized(policy_state->system_dn)));
779 return NT_STATUS_INTERNAL_DB_CORRUPTION;
782 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
784 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
786 return NT_STATUS_NO_MEMORY;
789 handle->data = talloc_steal(handle, trusted_domain_state);
791 trusted_domain_state->access_mask = r->in.access_mask;
792 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
794 *r->out.trustdom_handle = handle->wire_handle;
802 lsa_SetTrustedDomainInfo
804 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
805 struct lsa_SetTrustedDomainInfo *r)
807 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
813 lsa_SetInfomrationTrustedDomain
815 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
817 struct lsa_SetInformationTrustedDomain *r)
819 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
824 lsa_DeleteTrustedDomain
826 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
827 struct lsa_DeleteTrustedDomain *r)
830 struct lsa_OpenTrustedDomain open;
831 struct lsa_Delete delete;
832 struct dcesrv_handle *h;
834 open.in.handle = r->in.handle;
835 open.in.sid = r->in.dom_sid;
836 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
837 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
838 if (!open.out.trustdom_handle) {
839 return NT_STATUS_NO_MEMORY;
841 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
842 if (!NT_STATUS_IS_OK(status)) {
846 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
847 talloc_steal(mem_ctx, h);
849 delete.in.handle = open.out.trustdom_handle;
850 status = dcesrv_lsa_Delete(dce_call, mem_ctx, &delete);
851 if (!NT_STATUS_IS_OK(status)) {
857 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
858 struct ldb_message *msg,
859 struct lsa_TrustDomainInfoInfoEx *info_ex)
861 info_ex->domain_name.string
862 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
863 info_ex->netbios_name.string
864 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
866 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
867 info_ex->trust_direction
868 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
870 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
871 info_ex->trust_attributes
872 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
877 lsa_QueryTrustedDomainInfo
879 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
880 struct lsa_QueryTrustedDomainInfo *r)
882 struct dcesrv_handle *h;
883 struct lsa_trusted_domain_state *trusted_domain_state;
884 struct ldb_message *msg;
886 struct ldb_message **res;
887 const char *attrs[] = {
890 "securityIdentifier",
897 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
899 trusted_domain_state = h->data;
901 /* pull all the user attributes */
902 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
903 trusted_domain_state->trusted_domain_dn, &res, attrs);
905 return NT_STATUS_INTERNAL_DB_CORRUPTION;
909 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
911 return NT_STATUS_NO_MEMORY;
913 switch (r->in.level) {
914 case LSA_TRUSTED_DOMAIN_INFO_NAME:
915 r->out.info->name.netbios_name.string
916 = samdb_result_string(msg, "flatname", NULL);
918 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
919 r->out.info->posix_offset.posix_offset
920 = samdb_result_uint(msg, "posixOffset", 0);
922 #if 0 /* Win2k3 doesn't implement this */
923 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
924 r->out.info->info_basic.netbios_name.string
925 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
926 r->out.info->info_basic.sid
927 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
930 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
931 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
933 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
934 ZERO_STRUCT(r->out.info->full_info);
935 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
937 case LSA_TRUSTED_DOMAIN_INFO_INFO_ALL:
938 ZERO_STRUCT(r->out.info->info_all);
939 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_all.info_ex);
941 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO:
942 case LSA_TRUSTED_DOMAIN_INFO_11:
943 /* oops, we don't want to return the info after all */
944 talloc_free(r->out.info);
946 return NT_STATUS_INVALID_PARAMETER;
948 /* oops, we don't want to return the info after all */
949 talloc_free(r->out.info);
951 return NT_STATUS_INVALID_INFO_CLASS;
959 lsa_QueryTrustedDomainInfoBySid
961 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
962 struct lsa_QueryTrustedDomainInfoBySid *r)
965 struct lsa_OpenTrustedDomain open;
966 struct lsa_QueryTrustedDomainInfo query;
967 struct dcesrv_handle *h;
968 open.in.handle = r->in.handle;
969 open.in.sid = r->in.dom_sid;
970 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
971 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
972 if (!open.out.trustdom_handle) {
973 return NT_STATUS_NO_MEMORY;
975 status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
976 if (!NT_STATUS_IS_OK(status)) {
980 /* Ensure this handle goes away at the end of this call */
981 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
982 talloc_steal(mem_ctx, h);
984 query.in.trustdom_handle = open.out.trustdom_handle;
985 query.in.level = r->in.level;
986 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
987 if (!NT_STATUS_IS_OK(status)) {
991 r->out.info = query.out.info;
996 lsa_SetTrustedDomainInfoByName
998 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1000 struct lsa_SetTrustedDomainInfoByName *r)
1002 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1006 lsa_QueryTrustedDomainInfoByName
1008 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1009 TALLOC_CTX *mem_ctx,
1010 struct lsa_QueryTrustedDomainInfoByName *r)
1013 struct lsa_OpenTrustedDomainByName open;
1014 struct lsa_QueryTrustedDomainInfo query;
1015 struct dcesrv_handle *h;
1016 open.in.handle = r->in.handle;
1017 open.in.name = r->in.trusted_domain;
1018 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1019 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1020 if (!open.out.trustdom_handle) {
1021 return NT_STATUS_NO_MEMORY;
1023 status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1024 if (!NT_STATUS_IS_OK(status)) {
1028 /* Ensure this handle goes away at the end of this call */
1029 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1030 talloc_steal(mem_ctx, h);
1032 query.in.trustdom_handle = open.out.trustdom_handle;
1033 query.in.level = r->in.level;
1034 status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1035 if (!NT_STATUS_IS_OK(status)) {
1039 r->out.info = query.out.info;
1040 return NT_STATUS_OK;
1044 lsa_CloseTrustedDomainEx
1046 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1047 TALLOC_CTX *mem_ctx,
1048 struct lsa_CloseTrustedDomainEx *r)
1050 /* The result of a bad hair day from an IDL programmer? Not
1051 * implmented in Win2k3. You should always just lsa_Close
1053 return NT_STATUS_NOT_IMPLEMENTED;
1058 comparison function for sorting lsa_DomainInformation array
1060 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1062 return strcasecmp_m(e1->name.string, e2->name.string);
1068 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1069 struct lsa_EnumTrustDom *r)
1071 struct dcesrv_handle *policy_handle;
1072 struct lsa_DomainInfo *entries;
1073 struct lsa_policy_state *policy_state;
1074 struct ldb_message **domains;
1075 const char *attrs[] = {
1077 "securityIdentifier",
1084 *r->out.resume_handle = 0;
1086 r->out.domains->domains = NULL;
1087 r->out.domains->count = 0;
1089 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1091 policy_state = policy_handle->data;
1093 /* search for all users in this domain. This could possibly be cached and
1094 resumed based on resume_key */
1095 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1096 "objectclass=trustedDomain");
1098 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1100 if (count == 0 || r->in.max_size == 0) {
1101 return NT_STATUS_OK;
1104 /* convert to lsa_TrustInformation format */
1105 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1107 return NT_STATUS_NO_MEMORY;
1109 for (i=0;i<count;i++) {
1110 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1111 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1114 /* sort the results by name */
1115 qsort(entries, count, sizeof(*entries),
1116 (comparison_fn_t)compare_DomainInfo);
1118 if (*r->in.resume_handle >= count) {
1119 *r->out.resume_handle = -1;
1121 return NT_STATUS_NO_MORE_ENTRIES;
1124 /* return the rest, limit by max_size. Note that we
1125 use the w2k3 element size value of 60 */
1126 r->out.domains->count = count - *r->in.resume_handle;
1127 r->out.domains->count = MIN(r->out.domains->count,
1128 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1130 r->out.domains->domains = entries + *r->in.resume_handle;
1131 r->out.domains->count = r->out.domains->count;
1133 if (r->out.domains->count < count - *r->in.resume_handle) {
1134 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1135 return STATUS_MORE_ENTRIES;
1138 return NT_STATUS_OK;
1142 comparison function for sorting lsa_DomainInformation array
1144 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1146 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1150 lsa_EnumTrustedDomainsEx
1152 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1153 struct lsa_EnumTrustedDomainsEx *r)
1155 struct dcesrv_handle *policy_handle;
1156 struct lsa_TrustDomainInfoInfoEx *entries;
1157 struct lsa_policy_state *policy_state;
1158 struct ldb_message **domains;
1159 const char *attrs[] = {
1162 "securityIdentifier",
1172 *r->out.resume_handle = 0;
1174 r->out.domains->domains = NULL;
1175 r->out.domains->count = 0;
1177 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1179 policy_state = policy_handle->data;
1181 /* search for all users in this domain. This could possibly be cached and
1182 resumed based on resume_key */
1183 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1184 "objectclass=trustedDomain");
1186 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1188 if (count == 0 || r->in.max_size == 0) {
1189 return NT_STATUS_OK;
1192 /* convert to lsa_DomainInformation format */
1193 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1195 return NT_STATUS_NO_MEMORY;
1197 for (i=0;i<count;i++) {
1198 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1199 if (!NT_STATUS_IS_OK(nt_status)) {
1204 /* sort the results by name */
1205 qsort(entries, count, sizeof(*entries),
1206 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1208 if (*r->in.resume_handle >= count) {
1209 *r->out.resume_handle = -1;
1211 return NT_STATUS_NO_MORE_ENTRIES;
1214 /* return the rest, limit by max_size. Note that we
1215 use the w2k3 element size value of 60 */
1216 r->out.domains->count = count - *r->in.resume_handle;
1217 r->out.domains->count = MIN(r->out.domains->count,
1218 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1220 r->out.domains->domains = entries + *r->in.resume_handle;
1221 r->out.domains->count = r->out.domains->count;
1223 if (r->out.domains->count < count - *r->in.resume_handle) {
1224 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1225 return STATUS_MORE_ENTRIES;
1228 return NT_STATUS_OK;
1235 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1236 struct lsa_OpenAccount *r)
1238 struct dcesrv_handle *h, *ah;
1239 struct lsa_policy_state *state;
1240 struct lsa_account_state *astate;
1242 ZERO_STRUCTP(r->out.acct_handle);
1244 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1248 astate = talloc(dce_call->conn, struct lsa_account_state);
1249 if (astate == NULL) {
1250 return NT_STATUS_NO_MEMORY;
1253 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1254 if (astate->account_sid == NULL) {
1255 talloc_free(astate);
1256 return NT_STATUS_NO_MEMORY;
1259 astate->policy = talloc_reference(astate, state);
1260 astate->access_mask = r->in.access_mask;
1262 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1264 talloc_free(astate);
1265 return NT_STATUS_NO_MEMORY;
1268 ah->data = talloc_steal(ah, astate);
1270 *r->out.acct_handle = ah->wire_handle;
1272 return NT_STATUS_OK;
1277 lsa_EnumPrivsAccount
1279 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1280 TALLOC_CTX *mem_ctx,
1281 struct lsa_EnumPrivsAccount *r)
1283 struct dcesrv_handle *h;
1284 struct lsa_account_state *astate;
1286 struct ldb_message **res;
1287 const char * const attrs[] = { "privilege", NULL};
1288 struct ldb_message_element *el;
1291 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1295 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1296 r->out.privs->count = 0;
1297 r->out.privs->unknown = 0;
1298 r->out.privs->set = NULL;
1300 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1301 if (sidstr == NULL) {
1302 return NT_STATUS_NO_MEMORY;
1305 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1306 "objectSid=%s", sidstr);
1308 return NT_STATUS_OK;
1311 el = ldb_msg_find_element(res[0], "privilege");
1312 if (el == NULL || el->num_values == 0) {
1313 return NT_STATUS_OK;
1316 r->out.privs->set = talloc_array(r->out.privs,
1317 struct lsa_LUIDAttribute, el->num_values);
1318 if (r->out.privs->set == NULL) {
1319 return NT_STATUS_NO_MEMORY;
1322 for (i=0;i<el->num_values;i++) {
1323 int id = sec_privilege_id((const char *)el->values[i].data);
1325 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1327 r->out.privs->set[i].attribute = 0;
1328 r->out.privs->set[i].luid.low = id;
1329 r->out.privs->set[i].luid.high = 0;
1332 r->out.privs->count = el->num_values;
1334 return NT_STATUS_OK;
1338 lsa_EnumAccountRights
1340 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1341 TALLOC_CTX *mem_ctx,
1342 struct lsa_EnumAccountRights *r)
1344 struct dcesrv_handle *h;
1345 struct lsa_policy_state *state;
1347 struct ldb_message **res;
1348 const char * const attrs[] = { "privilege", NULL};
1350 struct ldb_message_element *el;
1352 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1356 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1357 if (sidstr == NULL) {
1358 return NT_STATUS_NO_MEMORY;
1361 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1362 "(&(objectSid=%s)(privilege=*))", sidstr);
1364 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1367 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1370 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1371 dom_sid_string(mem_ctx, r->in.sid),
1372 ldb_errstring(state->sam_ldb)));
1373 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1376 el = ldb_msg_find_element(res[0], "privilege");
1377 if (el == NULL || el->num_values == 0) {
1378 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1381 r->out.rights->count = el->num_values;
1382 r->out.rights->names = talloc_array(r->out.rights,
1383 struct lsa_StringLarge, r->out.rights->count);
1384 if (r->out.rights->names == NULL) {
1385 return NT_STATUS_NO_MEMORY;
1388 for (i=0;i<el->num_values;i++) {
1389 r->out.rights->names[i].string = (const char *)el->values[i].data;
1392 return NT_STATUS_OK;
1398 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1400 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1401 TALLOC_CTX *mem_ctx,
1402 struct lsa_policy_state *state,
1404 struct dom_sid *sid,
1405 const struct lsa_RightSet *rights)
1408 struct ldb_message *msg;
1409 struct ldb_message_element *el;
1411 struct lsa_EnumAccountRights r2;
1413 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1414 if (sidstr == NULL) {
1415 return NT_STATUS_NO_MEMORY;
1418 msg = ldb_msg_new(mem_ctx);
1420 return NT_STATUS_NO_MEMORY;
1423 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1424 NULL, "objectSid=%s", sidstr);
1425 if (msg->dn == NULL) {
1427 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1428 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1430 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1432 if (!NT_STATUS_IS_OK(status)) {
1435 return NT_STATUS_NO_SUCH_USER;
1438 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1439 return NT_STATUS_NO_MEMORY;
1442 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1445 r2.in.handle = &state->handle->wire_handle;
1447 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1449 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1450 if (!NT_STATUS_IS_OK(status)) {
1451 ZERO_STRUCTP(r2.out.rights);
1455 for (i=0;i<rights->count;i++) {
1456 if (sec_privilege_id(rights->names[i].string) == -1) {
1457 return NT_STATUS_NO_SUCH_PRIVILEGE;
1460 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1462 for (j=0;j<r2.out.rights->count;j++) {
1463 if (strcasecmp_m(r2.out.rights->names[j].string,
1464 rights->names[i].string) == 0) {
1468 if (j != r2.out.rights->count) continue;
1471 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1472 if (ret != LDB_SUCCESS) {
1473 return NT_STATUS_NO_MEMORY;
1477 el = ldb_msg_find_element(msg, "privilege");
1479 return NT_STATUS_OK;
1482 ret = ldb_modify(state->sam_ldb, msg);
1484 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1485 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1487 DEBUG(3, ("Could not %s attributes from %s: %s",
1488 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1489 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1490 return NT_STATUS_UNEXPECTED_IO_ERROR;
1493 return NT_STATUS_OK;
1497 lsa_AddPrivilegesToAccount
1499 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1500 struct lsa_AddPrivilegesToAccount *r)
1502 struct lsa_RightSet rights;
1503 struct dcesrv_handle *h;
1504 struct lsa_account_state *astate;
1507 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1511 rights.count = r->in.privs->count;
1512 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1513 if (rights.names == NULL) {
1514 return NT_STATUS_NO_MEMORY;
1516 for (i=0;i<rights.count;i++) {
1517 int id = r->in.privs->set[i].luid.low;
1518 if (r->in.privs->set[i].luid.high) {
1519 return NT_STATUS_NO_SUCH_PRIVILEGE;
1521 rights.names[i].string = sec_privilege_name(id);
1522 if (rights.names[i].string == NULL) {
1523 return NT_STATUS_NO_SUCH_PRIVILEGE;
1527 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1528 LDB_FLAG_MOD_ADD, astate->account_sid,
1534 lsa_RemovePrivilegesFromAccount
1536 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1537 struct lsa_RemovePrivilegesFromAccount *r)
1539 struct lsa_RightSet *rights;
1540 struct dcesrv_handle *h;
1541 struct lsa_account_state *astate;
1544 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1548 rights = talloc(mem_ctx, struct lsa_RightSet);
1550 if (r->in.remove_all == 1 &&
1551 r->in.privs == NULL) {
1552 struct lsa_EnumAccountRights r2;
1555 r2.in.handle = &astate->policy->handle->wire_handle;
1556 r2.in.sid = astate->account_sid;
1557 r2.out.rights = rights;
1559 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1560 if (!NT_STATUS_IS_OK(status)) {
1564 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1565 LDB_FLAG_MOD_DELETE, astate->account_sid,
1569 if (r->in.remove_all != 0) {
1570 return NT_STATUS_INVALID_PARAMETER;
1573 rights->count = r->in.privs->count;
1574 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
1575 if (rights->names == NULL) {
1576 return NT_STATUS_NO_MEMORY;
1578 for (i=0;i<rights->count;i++) {
1579 int id = r->in.privs->set[i].luid.low;
1580 if (r->in.privs->set[i].luid.high) {
1581 return NT_STATUS_NO_SUCH_PRIVILEGE;
1583 rights->names[i].string = sec_privilege_name(id);
1584 if (rights->names[i].string == NULL) {
1585 return NT_STATUS_NO_SUCH_PRIVILEGE;
1589 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1590 LDB_FLAG_MOD_DELETE, astate->account_sid,
1596 lsa_GetQuotasForAccount
1598 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1599 struct lsa_GetQuotasForAccount *r)
1601 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1606 lsa_SetQuotasForAccount
1608 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1609 struct lsa_SetQuotasForAccount *r)
1611 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1616 lsa_GetSystemAccessAccount
1618 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1619 struct lsa_GetSystemAccessAccount *r)
1621 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1626 lsa_SetSystemAccessAccount
1628 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1629 struct lsa_SetSystemAccessAccount *r)
1631 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1638 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1639 struct lsa_CreateSecret *r)
1641 struct dcesrv_handle *policy_handle;
1642 struct lsa_policy_state *policy_state;
1643 struct lsa_secret_state *secret_state;
1644 struct dcesrv_handle *handle;
1645 struct ldb_message **msgs, *msg;
1647 const char *attrs[] = {
1655 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1656 ZERO_STRUCTP(r->out.sec_handle);
1658 policy_state = policy_handle->data;
1660 if (!r->in.name.string) {
1661 return NT_STATUS_INVALID_PARAMETER;
1664 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1665 if (!secret_state) {
1666 return NT_STATUS_NO_MEMORY;
1668 secret_state->policy = policy_state;
1670 msg = ldb_msg_new(mem_ctx);
1672 return NT_STATUS_NO_MEMORY;
1675 if (strncmp("G$", r->in.name.string, 2) == 0) {
1677 name = &r->in.name.string[2];
1678 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1679 secret_state->global = true;
1681 if (strlen(name) < 1) {
1682 return NT_STATUS_INVALID_PARAMETER;
1685 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
1686 /* search for the secret record */
1687 ret = gendb_search(secret_state->sam_ldb,
1688 mem_ctx, policy_state->system_dn, &msgs, attrs,
1689 "(&(cn=%s)(objectclass=secret))",
1692 return NT_STATUS_OBJECT_NAME_COLLISION;
1696 DEBUG(0,("Failure searching for CN=%s: %s\n",
1697 name2, ldb_errstring(secret_state->sam_ldb)));
1698 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1701 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1702 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
1703 return NT_STATUS_NO_MEMORY;
1706 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
1709 secret_state->global = false;
1711 name = r->in.name.string;
1712 if (strlen(name) < 1) {
1713 return NT_STATUS_INVALID_PARAMETER;
1716 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx,
1718 /* search for the secret record */
1719 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1720 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1722 "(&(cn=%s)(objectclass=secret))",
1723 ldb_binary_encode_string(mem_ctx, name));
1725 return NT_STATUS_OBJECT_NAME_COLLISION;
1729 DEBUG(0,("Failure searching for CN=%s: %s\n",
1730 name, ldb_errstring(secret_state->sam_ldb)));
1731 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1734 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
1735 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
1738 /* pull in all the template attributes. Note this is always from the global samdb */
1739 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
1742 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
1744 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1747 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
1749 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1751 /* create the secret */
1752 ret = ldb_add(secret_state->sam_ldb, msg);
1754 DEBUG(0,("Failed to create secret record %s: %s\n",
1755 ldb_dn_get_linearized(msg->dn),
1756 ldb_errstring(secret_state->sam_ldb)));
1757 return NT_STATUS_ACCESS_DENIED;
1760 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1762 return NT_STATUS_NO_MEMORY;
1765 handle->data = talloc_steal(handle, secret_state);
1767 secret_state->access_mask = r->in.access_mask;
1768 secret_state->policy = talloc_reference(secret_state, policy_state);
1770 *r->out.sec_handle = handle->wire_handle;
1772 return NT_STATUS_OK;
1779 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1780 struct lsa_OpenSecret *r)
1782 struct dcesrv_handle *policy_handle;
1784 struct lsa_policy_state *policy_state;
1785 struct lsa_secret_state *secret_state;
1786 struct dcesrv_handle *handle;
1787 struct ldb_message **msgs;
1788 const char *attrs[] = {
1796 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1797 ZERO_STRUCTP(r->out.sec_handle);
1798 policy_state = policy_handle->data;
1800 if (!r->in.name.string) {
1801 return NT_STATUS_INVALID_PARAMETER;
1804 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1805 if (!secret_state) {
1806 return NT_STATUS_NO_MEMORY;
1808 secret_state->policy = policy_state;
1810 if (strncmp("G$", r->in.name.string, 2) == 0) {
1811 name = &r->in.name.string[2];
1812 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1813 secret_state->global = true;
1815 if (strlen(name) < 1) {
1816 return NT_STATUS_INVALID_PARAMETER;
1819 /* search for the secret record */
1820 ret = gendb_search(secret_state->sam_ldb,
1821 mem_ctx, policy_state->system_dn, &msgs, attrs,
1822 "(&(cn=%s Secret)(objectclass=secret))",
1823 ldb_binary_encode_string(mem_ctx, name));
1825 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1829 DEBUG(0,("Found %d records matching DN %s\n", ret,
1830 ldb_dn_get_linearized(policy_state->system_dn)));
1831 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1835 secret_state->sam_ldb = talloc_reference(secret_state,
1836 secrets_db_connect(mem_ctx, global_loadparm));
1838 secret_state->global = false;
1839 name = r->in.name.string;
1840 if (strlen(name) < 1) {
1841 return NT_STATUS_INVALID_PARAMETER;
1844 /* search for the secret record */
1845 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1846 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1848 "(&(cn=%s)(objectclass=secret))",
1849 ldb_binary_encode_string(mem_ctx, name));
1851 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1855 DEBUG(0,("Found %d records matching CN=%s\n",
1856 ret, ldb_binary_encode_string(mem_ctx, name)));
1857 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1861 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1863 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1865 return NT_STATUS_NO_MEMORY;
1868 handle->data = talloc_steal(handle, secret_state);
1870 secret_state->access_mask = r->in.access_mask;
1871 secret_state->policy = talloc_reference(secret_state, policy_state);
1873 *r->out.sec_handle = handle->wire_handle;
1875 return NT_STATUS_OK;
1882 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1883 struct lsa_SetSecret *r)
1886 struct dcesrv_handle *h;
1887 struct lsa_secret_state *secret_state;
1888 struct ldb_message *msg;
1889 DATA_BLOB session_key;
1890 DATA_BLOB crypt_secret, secret;
1893 NTSTATUS status = NT_STATUS_OK;
1895 struct timeval now = timeval_current();
1896 NTTIME nt_now = timeval_to_nttime(&now);
1898 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
1900 secret_state = h->data;
1902 msg = ldb_msg_new(mem_ctx);
1904 return NT_STATUS_NO_MEMORY;
1907 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
1909 return NT_STATUS_NO_MEMORY;
1911 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
1912 if (!NT_STATUS_IS_OK(status)) {
1916 if (r->in.old_val) {
1918 crypt_secret.data = r->in.old_val->data;
1919 crypt_secret.length = r->in.old_val->size;
1921 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1922 if (!NT_STATUS_IS_OK(status)) {
1926 val.data = secret.data;
1927 val.length = secret.length;
1930 if (samdb_msg_add_value(secret_state->sam_ldb,
1931 mem_ctx, msg, "priorValue", &val) != 0) {
1932 return NT_STATUS_NO_MEMORY;
1935 /* set old value mtime */
1936 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1937 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
1938 return NT_STATUS_NO_MEMORY;
1941 if (!r->in.new_val) {
1942 /* This behaviour varies depending of if this is a local, or a global secret... */
1943 if (secret_state->global) {
1944 /* set old value mtime */
1945 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1946 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
1947 return NT_STATUS_NO_MEMORY;
1950 if (samdb_msg_add_delete(secret_state->sam_ldb,
1951 mem_ctx, msg, "currentValue")) {
1952 return NT_STATUS_NO_MEMORY;
1954 if (samdb_msg_add_delete(secret_state->sam_ldb,
1955 mem_ctx, msg, "lastSetTime")) {
1956 return NT_STATUS_NO_MEMORY;
1962 if (r->in.new_val) {
1964 crypt_secret.data = r->in.new_val->data;
1965 crypt_secret.length = r->in.new_val->size;
1967 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1968 if (!NT_STATUS_IS_OK(status)) {
1972 val.data = secret.data;
1973 val.length = secret.length;
1976 if (samdb_msg_add_value(secret_state->sam_ldb,
1977 mem_ctx, msg, "currentValue", &val) != 0) {
1978 return NT_STATUS_NO_MEMORY;
1981 /* set new value mtime */
1982 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1983 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
1984 return NT_STATUS_NO_MEMORY;
1987 /* If the old value is not set, then migrate the
1988 * current value to the old value */
1989 if (!r->in.old_val) {
1990 const struct ldb_val *new_val;
1991 NTTIME last_set_time;
1992 struct ldb_message **res;
1993 const char *attrs[] = {
1999 /* search for the secret record */
2000 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2001 secret_state->secret_dn, &res, attrs);
2003 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2007 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2008 ldb_dn_get_linearized(secret_state->secret_dn)));
2009 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2012 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2013 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2017 if (samdb_msg_add_value(secret_state->sam_ldb,
2018 mem_ctx, msg, "priorValue",
2020 return NT_STATUS_NO_MEMORY;
2024 /* set new value mtime */
2025 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2026 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2027 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2028 return NT_STATUS_NO_MEMORY;
2034 /* modify the samdb record */
2035 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2037 /* we really need samdb.c to return NTSTATUS */
2038 return NT_STATUS_UNSUCCESSFUL;
2041 return NT_STATUS_OK;
2048 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2049 struct lsa_QuerySecret *r)
2051 struct dcesrv_handle *h;
2052 struct lsa_secret_state *secret_state;
2053 struct ldb_message *msg;
2054 DATA_BLOB session_key;
2055 DATA_BLOB crypt_secret, secret;
2057 struct ldb_message **res;
2058 const char *attrs[] = {
2068 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2070 secret_state = h->data;
2072 /* pull all the user attributes */
2073 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2074 secret_state->secret_dn, &res, attrs);
2076 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2080 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2081 if (!NT_STATUS_IS_OK(nt_status)) {
2085 if (r->in.old_val) {
2086 const struct ldb_val *prior_val;
2087 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2088 if (!r->out.old_val) {
2089 return NT_STATUS_NO_MEMORY;
2091 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2093 if (prior_val && prior_val->length) {
2094 secret.data = prior_val->data;
2095 secret.length = prior_val->length;
2098 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2099 if (!crypt_secret.length) {
2100 return NT_STATUS_NO_MEMORY;
2102 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2103 if (!r->out.old_val->buf) {
2104 return NT_STATUS_NO_MEMORY;
2106 r->out.old_val->buf->size = crypt_secret.length;
2107 r->out.old_val->buf->length = crypt_secret.length;
2108 r->out.old_val->buf->data = crypt_secret.data;
2112 if (r->in.old_mtime) {
2113 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2114 if (!r->out.old_mtime) {
2115 return NT_STATUS_NO_MEMORY;
2117 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2120 if (r->in.new_val) {
2121 const struct ldb_val *new_val;
2122 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2123 if (!r->out.new_val) {
2124 return NT_STATUS_NO_MEMORY;
2127 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2129 if (new_val && new_val->length) {
2130 secret.data = new_val->data;
2131 secret.length = new_val->length;
2134 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2135 if (!crypt_secret.length) {
2136 return NT_STATUS_NO_MEMORY;
2138 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2139 if (!r->out.new_val->buf) {
2140 return NT_STATUS_NO_MEMORY;
2142 r->out.new_val->buf->length = crypt_secret.length;
2143 r->out.new_val->buf->size = crypt_secret.length;
2144 r->out.new_val->buf->data = crypt_secret.data;
2148 if (r->in.new_mtime) {
2149 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2150 if (!r->out.new_mtime) {
2151 return NT_STATUS_NO_MEMORY;
2153 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2156 return NT_STATUS_OK;
2163 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2164 TALLOC_CTX *mem_ctx,
2165 struct lsa_LookupPrivValue *r)
2167 struct dcesrv_handle *h;
2168 struct lsa_policy_state *state;
2171 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2175 id = sec_privilege_id(r->in.name->string);
2177 return NT_STATUS_NO_SUCH_PRIVILEGE;
2180 r->out.luid->low = id;
2181 r->out.luid->high = 0;
2183 return NT_STATUS_OK;
2190 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2191 TALLOC_CTX *mem_ctx,
2192 struct lsa_LookupPrivName *r)
2194 struct dcesrv_handle *h;
2195 struct lsa_policy_state *state;
2196 const char *privname;
2198 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2202 if (r->in.luid->high != 0) {
2203 return NT_STATUS_NO_SUCH_PRIVILEGE;
2206 privname = sec_privilege_name(r->in.luid->low);
2207 if (privname == NULL) {
2208 return NT_STATUS_NO_SUCH_PRIVILEGE;
2211 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2212 if (r->out.name == NULL) {
2213 return NT_STATUS_NO_MEMORY;
2215 r->out.name->string = privname;
2217 return NT_STATUS_OK;
2222 lsa_LookupPrivDisplayName
2224 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2225 TALLOC_CTX *mem_ctx,
2226 struct lsa_LookupPrivDisplayName *r)
2228 struct dcesrv_handle *h;
2229 struct lsa_policy_state *state;
2232 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2236 id = sec_privilege_id(r->in.name->string);
2238 return NT_STATUS_NO_SUCH_PRIVILEGE;
2241 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2242 if (r->out.disp_name == NULL) {
2243 return NT_STATUS_NO_MEMORY;
2246 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2247 if (r->out.disp_name->string == NULL) {
2248 return NT_STATUS_INTERNAL_ERROR;
2251 return NT_STATUS_OK;
2258 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2259 struct lsa_DeleteObject *r)
2261 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2266 lsa_EnumAccountsWithUserRight
2268 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2269 TALLOC_CTX *mem_ctx,
2270 struct lsa_EnumAccountsWithUserRight *r)
2272 struct dcesrv_handle *h;
2273 struct lsa_policy_state *state;
2275 struct ldb_message **res;
2276 const char * const attrs[] = { "objectSid", NULL};
2277 const char *privname;
2279 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2283 if (r->in.name == NULL) {
2284 return NT_STATUS_NO_SUCH_PRIVILEGE;
2287 privname = r->in.name->string;
2288 if (sec_privilege_id(privname) == -1) {
2289 return NT_STATUS_NO_SUCH_PRIVILEGE;
2292 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2293 "privilege=%s", privname);
2295 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2298 return NT_STATUS_NO_MORE_ENTRIES;
2301 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2302 if (r->out.sids->sids == NULL) {
2303 return NT_STATUS_NO_MEMORY;
2305 for (i=0;i<ret;i++) {
2306 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2307 res[i], "objectSid");
2308 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2310 r->out.sids->num_sids = ret;
2312 return NT_STATUS_OK;
2317 lsa_AddAccountRights
2319 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2320 TALLOC_CTX *mem_ctx,
2321 struct lsa_AddAccountRights *r)
2323 struct dcesrv_handle *h;
2324 struct lsa_policy_state *state;
2326 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2330 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2332 r->in.sid, r->in.rights);
2337 lsa_RemoveAccountRights
2339 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2340 TALLOC_CTX *mem_ctx,
2341 struct lsa_RemoveAccountRights *r)
2343 struct dcesrv_handle *h;
2344 struct lsa_policy_state *state;
2346 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2350 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2351 LDB_FLAG_MOD_DELETE,
2352 r->in.sid, r->in.rights);
2357 lsa_StorePrivateData
2359 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2360 struct lsa_StorePrivateData *r)
2362 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2367 lsa_RetrievePrivateData
2369 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2370 struct lsa_RetrievePrivateData *r)
2372 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2379 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2380 struct lsa_GetUserName *r)
2382 NTSTATUS status = NT_STATUS_OK;
2383 const char *account_name;
2384 const char *authority_name;
2385 struct lsa_String *_account_name;
2386 struct lsa_StringPointer *_authority_name = NULL;
2388 /* this is what w2k3 does */
2389 r->out.account_name = r->in.account_name;
2390 r->out.authority_name = r->in.authority_name;
2392 if (r->in.account_name && r->in.account_name->string) {
2393 return NT_STATUS_INVALID_PARAMETER;
2396 if (r->in.authority_name &&
2397 r->in.authority_name->string &&
2398 r->in.authority_name->string->string) {
2399 return NT_STATUS_INVALID_PARAMETER;
2402 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2403 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2405 _account_name = talloc(mem_ctx, struct lsa_String);
2406 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2407 _account_name->string = account_name;
2409 if (r->in.authority_name) {
2410 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2411 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2412 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2413 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2414 _authority_name->string->string = authority_name;
2417 r->out.account_name = _account_name;
2418 r->out.authority_name = _authority_name;
2426 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2427 TALLOC_CTX *mem_ctx,
2428 struct lsa_SetInfoPolicy2 *r)
2430 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2434 lsa_QueryDomainInformationPolicy
2436 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2437 TALLOC_CTX *mem_ctx,
2438 struct lsa_QueryDomainInformationPolicy *r)
2440 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2444 lsa_SetDomInfoPolicy
2446 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2447 TALLOC_CTX *mem_ctx,
2448 struct lsa_SetDomainInformationPolicy *r)
2450 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2456 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
2457 TALLOC_CTX *mem_ctx,
2458 struct lsa_TestCall *r)
2460 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2466 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2467 struct lsa_CREDRWRITE *r)
2469 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2476 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2477 struct lsa_CREDRREAD *r)
2479 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2486 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2487 struct lsa_CREDRENUMERATE *r)
2489 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2494 lsa_CREDRWRITEDOMAINCREDENTIALS
2496 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2497 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2499 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2504 lsa_CREDRREADDOMAINCREDENTIALS
2506 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2507 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2509 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2516 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2517 struct lsa_CREDRDELETE *r)
2519 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2524 lsa_CREDRGETTARGETINFO
2526 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2527 struct lsa_CREDRGETTARGETINFO *r)
2529 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2534 lsa_CREDRPROFILELOADED
2536 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2537 struct lsa_CREDRPROFILELOADED *r)
2539 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2544 lsa_CREDRGETSESSIONTYPES
2546 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2547 struct lsa_CREDRGETSESSIONTYPES *r)
2549 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2554 lsa_LSARREGISTERAUDITEVENT
2556 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2557 struct lsa_LSARREGISTERAUDITEVENT *r)
2559 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2564 lsa_LSARGENAUDITEVENT
2566 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2567 struct lsa_LSARGENAUDITEVENT *r)
2569 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2574 lsa_LSARUNREGISTERAUDITEVENT
2576 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2577 struct lsa_LSARUNREGISTERAUDITEVENT *r)
2579 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2584 lsa_lsaRQueryForestTrustInformation
2586 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2587 struct lsa_lsaRQueryForestTrustInformation *r)
2589 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2594 lsa_LSARSETFORESTTRUSTINFORMATION
2596 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2597 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2599 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2606 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2607 struct lsa_CREDRRENAME *r)
2609 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2615 lsa_LSAROPENPOLICYSCE
2617 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2618 struct lsa_LSAROPENPOLICYSCE *r)
2620 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2625 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
2627 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2628 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2630 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2635 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
2637 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2638 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2640 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2645 lsa_LSARADTREPORTSECURITYEVENT
2647 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2648 struct lsa_LSARADTREPORTSECURITYEVENT *r)
2650 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2654 /* include the generated boilerplate */
2655 #include "librpc/gen_ndr/ndr_lsa_s.c"
2659 /*****************************************
2660 NOTE! The remaining calls below were
2661 removed in w2k3, so the DCESRV_FAULT()
2662 replies are the correct implementation. Do
2663 not try and fill these in with anything else
2664 ******************************************/
2667 dssetup_DsRoleDnsNameToFlatName
2669 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2670 struct dssetup_DsRoleDnsNameToFlatName *r)
2672 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2677 dssetup_DsRoleDcAsDc
2679 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2680 struct dssetup_DsRoleDcAsDc *r)
2682 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2687 dssetup_DsRoleDcAsReplica
2689 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2690 struct dssetup_DsRoleDcAsReplica *r)
2692 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2697 dssetup_DsRoleDemoteDc
2699 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2700 struct dssetup_DsRoleDemoteDc *r)
2702 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2707 dssetup_DsRoleGetDcOperationProgress
2709 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2710 struct dssetup_DsRoleGetDcOperationProgress *r)
2712 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2717 dssetup_DsRoleGetDcOperationResults
2719 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2720 struct dssetup_DsRoleGetDcOperationResults *r)
2722 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2727 dssetup_DsRoleCancel
2729 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2730 struct dssetup_DsRoleCancel *r)
2732 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2737 dssetup_DsRoleServerSaveStateForUpgrade
2739 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2740 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
2742 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2747 dssetup_DsRoleUpgradeDownlevelServer
2749 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2750 struct dssetup_DsRoleUpgradeDownlevelServer *r)
2752 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2757 dssetup_DsRoleAbortDownlevelServerUpgrade
2759 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2760 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
2762 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2766 /* include the generated boilerplate */
2767 #include "librpc/gen_ndr/ndr_dssetup_s.c"
2769 NTSTATUS dcerpc_server_lsa_init(void)
2773 ret = dcerpc_server_dssetup_init();
2774 if (!NT_STATUS_IS_OK(ret)) {
2777 ret = dcerpc_server_lsarpc_init();
2778 if (!NT_STATUS_IS_OK(ret)) {