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));
1717 /* search for the secret record */
1718 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1719 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1721 "(&(cn=%s)(objectclass=secret))",
1722 ldb_binary_encode_string(mem_ctx, name));
1724 return NT_STATUS_OBJECT_NAME_COLLISION;
1728 DEBUG(0,("Failure searching for CN=%s: %s\n",
1729 name, ldb_errstring(secret_state->sam_ldb)));
1730 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1733 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
1734 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
1737 /* pull in all the template attributes. Note this is always from the global samdb */
1738 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
1741 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
1743 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1746 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
1748 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1750 /* create the secret */
1751 ret = ldb_add(secret_state->sam_ldb, msg);
1753 DEBUG(0,("Failed to create secret record %s: %s\n",
1754 ldb_dn_get_linearized(msg->dn),
1755 ldb_errstring(secret_state->sam_ldb)));
1756 return NT_STATUS_ACCESS_DENIED;
1759 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1761 return NT_STATUS_NO_MEMORY;
1764 handle->data = talloc_steal(handle, secret_state);
1766 secret_state->access_mask = r->in.access_mask;
1767 secret_state->policy = talloc_reference(secret_state, policy_state);
1769 *r->out.sec_handle = handle->wire_handle;
1771 return NT_STATUS_OK;
1778 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1779 struct lsa_OpenSecret *r)
1781 struct dcesrv_handle *policy_handle;
1783 struct lsa_policy_state *policy_state;
1784 struct lsa_secret_state *secret_state;
1785 struct dcesrv_handle *handle;
1786 struct ldb_message **msgs;
1787 const char *attrs[] = {
1795 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1796 ZERO_STRUCTP(r->out.sec_handle);
1797 policy_state = policy_handle->data;
1799 if (!r->in.name.string) {
1800 return NT_STATUS_INVALID_PARAMETER;
1803 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1804 if (!secret_state) {
1805 return NT_STATUS_NO_MEMORY;
1807 secret_state->policy = policy_state;
1809 if (strncmp("G$", r->in.name.string, 2) == 0) {
1810 name = &r->in.name.string[2];
1811 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1812 secret_state->global = true;
1814 if (strlen(name) < 1) {
1815 return NT_STATUS_INVALID_PARAMETER;
1818 /* search for the secret record */
1819 ret = gendb_search(secret_state->sam_ldb,
1820 mem_ctx, policy_state->system_dn, &msgs, attrs,
1821 "(&(cn=%s Secret)(objectclass=secret))",
1822 ldb_binary_encode_string(mem_ctx, name));
1824 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1828 DEBUG(0,("Found %d records matching DN %s\n", ret,
1829 ldb_dn_get_linearized(policy_state->system_dn)));
1830 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1834 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1836 secret_state->global = false;
1837 name = r->in.name.string;
1838 if (strlen(name) < 1) {
1839 return NT_STATUS_INVALID_PARAMETER;
1842 /* search for the secret record */
1843 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1844 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1846 "(&(cn=%s)(objectclass=secret))",
1847 ldb_binary_encode_string(mem_ctx, name));
1849 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1853 DEBUG(0,("Found %d records matching CN=%s\n",
1854 ret, ldb_binary_encode_string(mem_ctx, name)));
1855 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1859 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1861 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1863 return NT_STATUS_NO_MEMORY;
1866 handle->data = talloc_steal(handle, secret_state);
1868 secret_state->access_mask = r->in.access_mask;
1869 secret_state->policy = talloc_reference(secret_state, policy_state);
1871 *r->out.sec_handle = handle->wire_handle;
1873 return NT_STATUS_OK;
1880 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1881 struct lsa_SetSecret *r)
1884 struct dcesrv_handle *h;
1885 struct lsa_secret_state *secret_state;
1886 struct ldb_message *msg;
1887 DATA_BLOB session_key;
1888 DATA_BLOB crypt_secret, secret;
1891 NTSTATUS status = NT_STATUS_OK;
1893 struct timeval now = timeval_current();
1894 NTTIME nt_now = timeval_to_nttime(&now);
1896 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
1898 secret_state = h->data;
1900 msg = ldb_msg_new(mem_ctx);
1902 return NT_STATUS_NO_MEMORY;
1905 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
1907 return NT_STATUS_NO_MEMORY;
1909 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
1910 if (!NT_STATUS_IS_OK(status)) {
1914 if (r->in.old_val) {
1916 crypt_secret.data = r->in.old_val->data;
1917 crypt_secret.length = r->in.old_val->size;
1919 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1920 if (!NT_STATUS_IS_OK(status)) {
1924 val.data = secret.data;
1925 val.length = secret.length;
1928 if (samdb_msg_add_value(secret_state->sam_ldb,
1929 mem_ctx, msg, "priorValue", &val) != 0) {
1930 return NT_STATUS_NO_MEMORY;
1933 /* set old value mtime */
1934 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1935 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
1936 return NT_STATUS_NO_MEMORY;
1939 if (!r->in.new_val) {
1940 /* This behaviour varies depending of if this is a local, or a global secret... */
1941 if (secret_state->global) {
1942 /* set old value mtime */
1943 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1944 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
1945 return NT_STATUS_NO_MEMORY;
1948 if (samdb_msg_add_delete(secret_state->sam_ldb,
1949 mem_ctx, msg, "currentValue")) {
1950 return NT_STATUS_NO_MEMORY;
1952 if (samdb_msg_add_delete(secret_state->sam_ldb,
1953 mem_ctx, msg, "lastSetTime")) {
1954 return NT_STATUS_NO_MEMORY;
1960 if (r->in.new_val) {
1962 crypt_secret.data = r->in.new_val->data;
1963 crypt_secret.length = r->in.new_val->size;
1965 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1966 if (!NT_STATUS_IS_OK(status)) {
1970 val.data = secret.data;
1971 val.length = secret.length;
1974 if (samdb_msg_add_value(secret_state->sam_ldb,
1975 mem_ctx, msg, "currentValue", &val) != 0) {
1976 return NT_STATUS_NO_MEMORY;
1979 /* set new value mtime */
1980 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1981 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
1982 return NT_STATUS_NO_MEMORY;
1985 /* If the old value is not set, then migrate the
1986 * current value to the old value */
1987 if (!r->in.old_val) {
1988 const struct ldb_val *new_val;
1989 NTTIME last_set_time;
1990 struct ldb_message **res;
1991 const char *attrs[] = {
1997 /* search for the secret record */
1998 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
1999 secret_state->secret_dn, &res, attrs);
2001 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2005 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2006 ldb_dn_get_linearized(secret_state->secret_dn)));
2007 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2010 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2011 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2015 if (samdb_msg_add_value(secret_state->sam_ldb,
2016 mem_ctx, msg, "priorValue",
2018 return NT_STATUS_NO_MEMORY;
2022 /* set new value mtime */
2023 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2024 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2025 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2026 return NT_STATUS_NO_MEMORY;
2032 /* modify the samdb record */
2033 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2035 /* we really need samdb.c to return NTSTATUS */
2036 return NT_STATUS_UNSUCCESSFUL;
2039 return NT_STATUS_OK;
2046 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2047 struct lsa_QuerySecret *r)
2049 struct dcesrv_handle *h;
2050 struct lsa_secret_state *secret_state;
2051 struct ldb_message *msg;
2052 DATA_BLOB session_key;
2053 DATA_BLOB crypt_secret, secret;
2055 struct ldb_message **res;
2056 const char *attrs[] = {
2066 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2068 secret_state = h->data;
2070 /* pull all the user attributes */
2071 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2072 secret_state->secret_dn, &res, attrs);
2074 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2078 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2079 if (!NT_STATUS_IS_OK(nt_status)) {
2083 if (r->in.old_val) {
2084 const struct ldb_val *prior_val;
2085 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2086 if (!r->out.old_val) {
2087 return NT_STATUS_NO_MEMORY;
2089 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2091 if (prior_val && prior_val->length) {
2092 secret.data = prior_val->data;
2093 secret.length = prior_val->length;
2096 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2097 if (!crypt_secret.length) {
2098 return NT_STATUS_NO_MEMORY;
2100 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2101 if (!r->out.old_val->buf) {
2102 return NT_STATUS_NO_MEMORY;
2104 r->out.old_val->buf->size = crypt_secret.length;
2105 r->out.old_val->buf->length = crypt_secret.length;
2106 r->out.old_val->buf->data = crypt_secret.data;
2110 if (r->in.old_mtime) {
2111 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2112 if (!r->out.old_mtime) {
2113 return NT_STATUS_NO_MEMORY;
2115 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2118 if (r->in.new_val) {
2119 const struct ldb_val *new_val;
2120 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2121 if (!r->out.new_val) {
2122 return NT_STATUS_NO_MEMORY;
2125 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2127 if (new_val && new_val->length) {
2128 secret.data = new_val->data;
2129 secret.length = new_val->length;
2132 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2133 if (!crypt_secret.length) {
2134 return NT_STATUS_NO_MEMORY;
2136 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2137 if (!r->out.new_val->buf) {
2138 return NT_STATUS_NO_MEMORY;
2140 r->out.new_val->buf->length = crypt_secret.length;
2141 r->out.new_val->buf->size = crypt_secret.length;
2142 r->out.new_val->buf->data = crypt_secret.data;
2146 if (r->in.new_mtime) {
2147 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2148 if (!r->out.new_mtime) {
2149 return NT_STATUS_NO_MEMORY;
2151 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2154 return NT_STATUS_OK;
2161 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2162 TALLOC_CTX *mem_ctx,
2163 struct lsa_LookupPrivValue *r)
2165 struct dcesrv_handle *h;
2166 struct lsa_policy_state *state;
2169 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2173 id = sec_privilege_id(r->in.name->string);
2175 return NT_STATUS_NO_SUCH_PRIVILEGE;
2178 r->out.luid->low = id;
2179 r->out.luid->high = 0;
2181 return NT_STATUS_OK;
2188 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2189 TALLOC_CTX *mem_ctx,
2190 struct lsa_LookupPrivName *r)
2192 struct dcesrv_handle *h;
2193 struct lsa_policy_state *state;
2194 const char *privname;
2196 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2200 if (r->in.luid->high != 0) {
2201 return NT_STATUS_NO_SUCH_PRIVILEGE;
2204 privname = sec_privilege_name(r->in.luid->low);
2205 if (privname == NULL) {
2206 return NT_STATUS_NO_SUCH_PRIVILEGE;
2209 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2210 if (r->out.name == NULL) {
2211 return NT_STATUS_NO_MEMORY;
2213 r->out.name->string = privname;
2215 return NT_STATUS_OK;
2220 lsa_LookupPrivDisplayName
2222 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2223 TALLOC_CTX *mem_ctx,
2224 struct lsa_LookupPrivDisplayName *r)
2226 struct dcesrv_handle *h;
2227 struct lsa_policy_state *state;
2230 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2234 id = sec_privilege_id(r->in.name->string);
2236 return NT_STATUS_NO_SUCH_PRIVILEGE;
2239 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2240 if (r->out.disp_name == NULL) {
2241 return NT_STATUS_NO_MEMORY;
2244 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2245 if (r->out.disp_name->string == NULL) {
2246 return NT_STATUS_INTERNAL_ERROR;
2249 return NT_STATUS_OK;
2256 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2257 struct lsa_DeleteObject *r)
2259 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2264 lsa_EnumAccountsWithUserRight
2266 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2267 TALLOC_CTX *mem_ctx,
2268 struct lsa_EnumAccountsWithUserRight *r)
2270 struct dcesrv_handle *h;
2271 struct lsa_policy_state *state;
2273 struct ldb_message **res;
2274 const char * const attrs[] = { "objectSid", NULL};
2275 const char *privname;
2277 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2281 if (r->in.name == NULL) {
2282 return NT_STATUS_NO_SUCH_PRIVILEGE;
2285 privname = r->in.name->string;
2286 if (sec_privilege_id(privname) == -1) {
2287 return NT_STATUS_NO_SUCH_PRIVILEGE;
2290 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2291 "privilege=%s", privname);
2293 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2296 return NT_STATUS_NO_MORE_ENTRIES;
2299 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2300 if (r->out.sids->sids == NULL) {
2301 return NT_STATUS_NO_MEMORY;
2303 for (i=0;i<ret;i++) {
2304 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2305 res[i], "objectSid");
2306 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2308 r->out.sids->num_sids = ret;
2310 return NT_STATUS_OK;
2315 lsa_AddAccountRights
2317 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2318 TALLOC_CTX *mem_ctx,
2319 struct lsa_AddAccountRights *r)
2321 struct dcesrv_handle *h;
2322 struct lsa_policy_state *state;
2324 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2328 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2330 r->in.sid, r->in.rights);
2335 lsa_RemoveAccountRights
2337 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2338 TALLOC_CTX *mem_ctx,
2339 struct lsa_RemoveAccountRights *r)
2341 struct dcesrv_handle *h;
2342 struct lsa_policy_state *state;
2344 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2348 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2349 LDB_FLAG_MOD_DELETE,
2350 r->in.sid, r->in.rights);
2355 lsa_StorePrivateData
2357 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2358 struct lsa_StorePrivateData *r)
2360 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2365 lsa_RetrievePrivateData
2367 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2368 struct lsa_RetrievePrivateData *r)
2370 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2377 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2378 struct lsa_GetUserName *r)
2380 NTSTATUS status = NT_STATUS_OK;
2381 const char *account_name;
2382 const char *authority_name;
2383 struct lsa_String *_account_name;
2384 struct lsa_StringPointer *_authority_name = NULL;
2386 /* this is what w2k3 does */
2387 r->out.account_name = r->in.account_name;
2388 r->out.authority_name = r->in.authority_name;
2390 if (r->in.account_name && r->in.account_name->string) {
2391 return NT_STATUS_INVALID_PARAMETER;
2394 if (r->in.authority_name &&
2395 r->in.authority_name->string &&
2396 r->in.authority_name->string->string) {
2397 return NT_STATUS_INVALID_PARAMETER;
2400 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2401 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2403 _account_name = talloc(mem_ctx, struct lsa_String);
2404 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2405 _account_name->string = account_name;
2407 if (r->in.authority_name) {
2408 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2409 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2410 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2411 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2412 _authority_name->string->string = authority_name;
2415 r->out.account_name = _account_name;
2416 r->out.authority_name = _authority_name;
2424 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2425 TALLOC_CTX *mem_ctx,
2426 struct lsa_SetInfoPolicy2 *r)
2428 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2432 lsa_QueryDomainInformationPolicy
2434 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2435 TALLOC_CTX *mem_ctx,
2436 struct lsa_QueryDomainInformationPolicy *r)
2438 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2442 lsa_SetDomInfoPolicy
2444 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2445 TALLOC_CTX *mem_ctx,
2446 struct lsa_SetDomainInformationPolicy *r)
2448 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2454 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
2455 TALLOC_CTX *mem_ctx,
2456 struct lsa_TestCall *r)
2458 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2464 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2465 struct lsa_CREDRWRITE *r)
2467 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2474 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2475 struct lsa_CREDRREAD *r)
2477 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2484 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2485 struct lsa_CREDRENUMERATE *r)
2487 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2492 lsa_CREDRWRITEDOMAINCREDENTIALS
2494 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2495 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2497 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2502 lsa_CREDRREADDOMAINCREDENTIALS
2504 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2505 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2507 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2514 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2515 struct lsa_CREDRDELETE *r)
2517 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2522 lsa_CREDRGETTARGETINFO
2524 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2525 struct lsa_CREDRGETTARGETINFO *r)
2527 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2532 lsa_CREDRPROFILELOADED
2534 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2535 struct lsa_CREDRPROFILELOADED *r)
2537 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2542 lsa_CREDRGETSESSIONTYPES
2544 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2545 struct lsa_CREDRGETSESSIONTYPES *r)
2547 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2552 lsa_LSARREGISTERAUDITEVENT
2554 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2555 struct lsa_LSARREGISTERAUDITEVENT *r)
2557 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2562 lsa_LSARGENAUDITEVENT
2564 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2565 struct lsa_LSARGENAUDITEVENT *r)
2567 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2572 lsa_LSARUNREGISTERAUDITEVENT
2574 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2575 struct lsa_LSARUNREGISTERAUDITEVENT *r)
2577 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2582 lsa_lsaRQueryForestTrustInformation
2584 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2585 struct lsa_lsaRQueryForestTrustInformation *r)
2587 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2592 lsa_LSARSETFORESTTRUSTINFORMATION
2594 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2595 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2597 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2604 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2605 struct lsa_CREDRRENAME *r)
2607 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2613 lsa_LSAROPENPOLICYSCE
2615 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2616 struct lsa_LSAROPENPOLICYSCE *r)
2618 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2623 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
2625 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2626 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2628 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2633 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
2635 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2636 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2638 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2643 lsa_LSARADTREPORTSECURITYEVENT
2645 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2646 struct lsa_LSARADTREPORTSECURITYEVENT *r)
2648 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2652 /* include the generated boilerplate */
2653 #include "librpc/gen_ndr/ndr_lsa_s.c"
2657 /*****************************************
2658 NOTE! The remaining calls below were
2659 removed in w2k3, so the DCESRV_FAULT()
2660 replies are the correct implementation. Do
2661 not try and fill these in with anything else
2662 ******************************************/
2665 dssetup_DsRoleDnsNameToFlatName
2667 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2668 struct dssetup_DsRoleDnsNameToFlatName *r)
2670 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2675 dssetup_DsRoleDcAsDc
2677 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2678 struct dssetup_DsRoleDcAsDc *r)
2680 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2685 dssetup_DsRoleDcAsReplica
2687 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2688 struct dssetup_DsRoleDcAsReplica *r)
2690 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2695 dssetup_DsRoleDemoteDc
2697 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2698 struct dssetup_DsRoleDemoteDc *r)
2700 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2705 dssetup_DsRoleGetDcOperationProgress
2707 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2708 struct dssetup_DsRoleGetDcOperationProgress *r)
2710 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2715 dssetup_DsRoleGetDcOperationResults
2717 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2718 struct dssetup_DsRoleGetDcOperationResults *r)
2720 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2725 dssetup_DsRoleCancel
2727 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2728 struct dssetup_DsRoleCancel *r)
2730 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2735 dssetup_DsRoleServerSaveStateForUpgrade
2737 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2738 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
2740 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2745 dssetup_DsRoleUpgradeDownlevelServer
2747 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2748 struct dssetup_DsRoleUpgradeDownlevelServer *r)
2750 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2755 dssetup_DsRoleAbortDownlevelServerUpgrade
2757 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2758 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
2760 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2764 /* include the generated boilerplate */
2765 #include "librpc/gen_ndr/ndr_dssetup_s.c"
2767 NTSTATUS dcerpc_server_lsa_init(void)
2771 ret = dcerpc_server_dssetup_init();
2772 if (!NT_STATUS_IS_OK(ret)) {
2775 ret = dcerpc_server_lsarpc_init();
2776 if (!NT_STATUS_IS_OK(ret)) {