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-2005
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 2 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, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "librpc/gen_ndr/ndr_lsa.h"
26 #include "librpc/gen_ndr/ndr_samr.h"
27 #include "rpc_server/dcerpc_server.h"
28 #include "rpc_server/common/common.h"
29 #include "lib/ldb/include/ldb.h"
30 #include "auth/auth.h"
31 #include "system/time.h"
34 this type allows us to distinguish handle types
40 LSA_HANDLE_TRUSTED_DOMAIN
44 state associated with a lsa_OpenPolicy() operation
46 struct lsa_policy_state {
47 struct dcesrv_handle *handle;
48 struct ldb_wrap *sam_ctx;
49 struct sidmap_context *sidmap;
51 const char *domain_dn;
52 const char *builtin_dn;
53 const char *system_dn;
54 const char *domain_name;
55 struct dom_sid *domain_sid;
56 struct dom_sid *builtin_sid;
61 state associated with a lsa_OpenAccount() operation
63 struct lsa_account_state {
64 struct lsa_policy_state *policy;
66 struct dom_sid *account_sid;
67 const char *account_sid_str;
68 const char *account_dn;
73 state associated with a lsa_OpenSecret() operation
75 struct lsa_secret_state {
76 struct lsa_policy_state *policy;
78 const char *secret_dn;
79 struct ldb_wrap *sam_ctx;
84 state associated with a lsa_OpenTrustedDomain() operation
86 struct lsa_trusted_domain_state {
87 struct lsa_policy_state *policy;
89 const char *trusted_domain_dn;
95 static NTSTATUS lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
98 struct dcesrv_handle *h;
100 *r->out.handle = *r->in.handle;
102 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
106 ZERO_STRUCTP(r->out.handle);
115 static NTSTATUS lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
116 struct lsa_Delete *r)
118 struct dcesrv_handle *h;
121 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
122 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
123 struct lsa_secret_state *secret_state = h->data;
124 ret = samdb_delete(secret_state->sam_ctx, mem_ctx, secret_state->secret_dn);
127 return NT_STATUS_INVALID_HANDLE;
131 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
132 struct lsa_trusted_domain_state *trusted_domain_state = h->data;
133 ret = samdb_delete(trusted_domain_state->policy->sam_ctx, mem_ctx,
134 trusted_domain_state->trusted_domain_dn);
137 return NT_STATUS_INVALID_HANDLE;
143 return NT_STATUS_INVALID_HANDLE;
150 static NTSTATUS lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
151 struct lsa_EnumPrivs *r)
153 struct dcesrv_handle *h;
154 struct lsa_policy_state *state;
156 const char *privname;
158 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
162 i = *r->in.resume_handle;
165 while ((privname = sec_privilege_name(i)) &&
166 r->out.privs->count < r->in.max_count) {
167 struct lsa_PrivEntry *e;
169 r->out.privs->privs = talloc_realloc_p(r->out.privs,
171 struct lsa_PrivEntry,
172 r->out.privs->count+1);
173 if (r->out.privs->privs == NULL) {
174 return NT_STATUS_NO_MEMORY;
176 e = &r->out.privs->privs[r->out.privs->count];
179 e->name.string = privname;
180 r->out.privs->count++;
184 *r->out.resume_handle = i;
193 static NTSTATUS lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
194 struct lsa_QuerySecurity *r)
196 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
203 static NTSTATUS lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
204 struct lsa_SetSecObj *r)
206 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
213 static NTSTATUS lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
214 struct lsa_ChangePassword *r)
216 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
219 static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
220 struct lsa_policy_state **_state)
222 struct lsa_policy_state *state;
225 state = talloc_p(mem_ctx, struct lsa_policy_state);
227 return NT_STATUS_NO_MEMORY;
230 /* make sure the sam database is accessible */
231 state->sam_ctx = samdb_connect(state);
232 if (state->sam_ctx == NULL) {
233 return NT_STATUS_INVALID_SYSTEM_SERVICE;
236 state->sidmap = sidmap_open(state);
237 if (state->sidmap == NULL) {
238 return NT_STATUS_INVALID_SYSTEM_SERVICE;
241 /* work out the domain_dn - useful for so many calls its worth
243 state->domain_dn = talloc_reference(state,
244 samdb_search_string(state->sam_ctx, mem_ctx, NULL,
245 "dn", "(&(objectClass=domain)(!(objectclass=builtinDomain)))"));
246 if (!state->domain_dn) {
247 return NT_STATUS_NO_SUCH_DOMAIN;
250 /* work out the builtin_dn - useful for so many calls its worth
252 state->builtin_dn = talloc_reference(state,
253 samdb_search_string(state->sam_ctx, mem_ctx, NULL,
254 "dn", "objectClass=builtinDomain"));
255 if (!state->builtin_dn) {
256 return NT_STATUS_NO_SUCH_DOMAIN;
259 /* work out the system_dn - useful for so many calls its worth
261 state->system_dn = talloc_reference(state,
262 samdb_search_string(state->sam_ctx, mem_ctx, state->domain_dn,
263 "dn", "(&(objectClass=container)(cn=System))"));
264 if (!state->system_dn) {
265 return NT_STATUS_NO_SUCH_DOMAIN;
268 sid_str = samdb_search_string(state->sam_ctx, mem_ctx, NULL,
269 "objectSid", "dn=%s", state->domain_dn);
271 return NT_STATUS_NO_SUCH_DOMAIN;
274 state->domain_sid = dom_sid_parse_talloc(state, sid_str);
275 if (!state->domain_sid) {
276 return NT_STATUS_NO_SUCH_DOMAIN;
279 state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
280 if (!state->builtin_sid) {
281 return NT_STATUS_NO_SUCH_DOMAIN;
284 state->domain_name = talloc_reference(state,
285 samdb_search_string(state->sam_ctx, mem_ctx, NULL,
286 "name", "dn=%s", state->domain_dn));
287 if (!state->domain_name) {
288 return NT_STATUS_NO_SUCH_DOMAIN;
299 static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
300 struct lsa_OpenPolicy2 *r)
303 struct lsa_policy_state *state;
304 struct dcesrv_handle *handle;
306 ZERO_STRUCTP(r->out.handle);
308 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
309 if (!NT_STATUS_IS_OK(status)) {
313 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
315 return NT_STATUS_NO_MEMORY;
318 handle->data = talloc_steal(handle, state);
320 state->access_mask = r->in.access_mask;
321 state->handle = handle;
322 *r->out.handle = handle->wire_handle;
324 /* note that we have completely ignored the attr element of
325 the OpenPolicy. As far as I can tell, this is what w2k3
333 a wrapper around lsa_OpenPolicy2
335 static NTSTATUS lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
336 struct lsa_OpenPolicy *r)
338 struct lsa_OpenPolicy2 r2;
340 r2.in.system_name = NULL;
341 r2.in.attr = r->in.attr;
342 r2.in.access_mask = r->in.access_mask;
343 r2.out.handle = r->out.handle;
345 return lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
352 fill in the AccountDomain info
354 static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
355 struct lsa_DomainInfo *info)
357 const char * const attrs[] = { "objectSid", "name", NULL};
359 struct ldb_message **res;
361 ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs,
362 "dn=%s", state->domain_dn);
364 return NT_STATUS_INTERNAL_DB_CORRUPTION;
367 info->name.string = samdb_result_string(res[0], "name", NULL);
368 info->sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
374 fill in the DNS domain info
376 static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
377 struct lsa_DnsDomainInfo *info)
379 const char * const attrs[] = { "name", "dnsDomain", "objectGUID", "objectSid", NULL };
381 struct ldb_message **res;
383 ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs,
384 "dn=%s", state->domain_dn);
386 return NT_STATUS_INTERNAL_DB_CORRUPTION;
389 info->name.string = samdb_result_string(res[0], "name", NULL);
390 info->dns_domain.string = samdb_result_string(res[0], "dnsDomain", NULL);
391 info->dns_forest.string = samdb_result_string(res[0], "dnsDomain", NULL);
392 info->domain_guid = samdb_result_guid(res[0], "objectGUID");
393 info->sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
401 static NTSTATUS lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
402 struct lsa_QueryInfoPolicy2 *r)
404 struct lsa_policy_state *state;
405 struct dcesrv_handle *h;
409 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
413 r->out.info = talloc_p(mem_ctx, union lsa_PolicyInformation);
415 return NT_STATUS_NO_MEMORY;
418 ZERO_STRUCTP(r->out.info);
420 switch (r->in.level) {
421 case LSA_POLICY_INFO_DOMAIN:
422 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
423 return lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
425 case LSA_POLICY_INFO_DNS:
426 return lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
429 return NT_STATUS_INVALID_INFO_CLASS;
435 static NTSTATUS lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
436 struct lsa_QueryInfoPolicy *r)
438 struct lsa_QueryInfoPolicy2 r2;
441 r2.in.handle = r->in.handle;
442 r2.in.level = r->in.level;
444 status = lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
446 r->out.info = r2.out.info;
454 static NTSTATUS lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
455 struct lsa_SetInfoPolicy *r)
457 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
464 static NTSTATUS lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
465 struct lsa_ClearAuditLog *r)
467 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
474 static NTSTATUS lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
475 struct lsa_CreateAccount *r)
477 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
484 static NTSTATUS lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
485 struct lsa_EnumAccounts *r)
487 struct dcesrv_handle *h;
488 struct lsa_policy_state *state;
490 struct ldb_message **res;
491 const char * const attrs[] = { "objectSid", NULL};
494 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
498 ret = samdb_search(state->sam_ctx, mem_ctx, state->builtin_dn, &res, attrs,
501 return NT_STATUS_NO_SUCH_USER;
504 if (*r->in.resume_handle >= ret) {
505 return NT_STATUS_NO_MORE_ENTRIES;
508 count = ret - *r->in.resume_handle;
509 if (count > r->in.num_entries) {
510 count = r->in.num_entries;
514 return NT_STATUS_NO_MORE_ENTRIES;
517 r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_SidPtr, count);
518 if (r->out.sids->sids == NULL) {
519 return NT_STATUS_NO_MEMORY;
522 for (i=0;i<count;i++) {
525 sidstr = samdb_result_string(res[i + *r->in.resume_handle], "objectSid", NULL);
526 if (sidstr == NULL) {
527 return NT_STATUS_NO_MEMORY;
529 r->out.sids->sids[i].sid = dom_sid_parse_talloc(r->out.sids->sids, sidstr);
530 if (r->out.sids->sids[i].sid == NULL) {
531 return NT_STATUS_NO_MEMORY;
535 r->out.sids->num_sids = count;
536 *r->out.resume_handle = count + *r->in.resume_handle;
544 lsa_CreateTrustedDomainEx2
546 static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
548 struct lsa_CreateTrustedDomainEx2 *r)
550 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
554 lsa_CreateTrustedDomainEx
556 static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
558 struct lsa_CreateTrustedDomainEx *r)
560 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
564 lsa_CreateTrustedDomain
566 static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
567 struct lsa_CreateTrustedDomain *r)
569 struct dcesrv_handle *policy_handle;
570 struct lsa_policy_state *policy_state;
571 struct lsa_trusted_domain_state *trusted_domain_state;
572 struct dcesrv_handle *handle;
573 struct ldb_message **msgs, *msg;
574 const char *attrs[] = {
580 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
581 ZERO_STRUCTP(r->out.trustdom_handle);
583 policy_state = policy_handle->data;
585 if (!r->in.info->name.string) {
586 return NT_STATUS_INVALID_PARAMETER;
588 name = r->in.info->name.string;
590 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
591 if (!trusted_domain_state) {
592 return NT_STATUS_NO_MEMORY;
594 trusted_domain_state->policy = policy_state;
596 msg = ldb_msg_new(mem_ctx);
598 return NT_STATUS_NO_MEMORY;
601 /* search for the trusted_domain record */
602 ret = samdb_search(trusted_domain_state->policy->sam_ctx,
603 mem_ctx, policy_state->system_dn, &msgs, attrs,
604 "(&(cn=%s)(objectclass=trustedDomain))",
605 r->in.info->name.string);
607 return NT_STATUS_OBJECT_NAME_COLLISION;
610 if (ret < 0 || ret > 1) {
611 DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
612 return NT_STATUS_INTERNAL_DB_CORRUPTION;
615 msg->dn = talloc_asprintf(mem_ctx, "cn=%s,%s", r->in.info->name.string,
616 policy_state->system_dn);
618 return NT_STATUS_NO_MEMORY;
621 samdb_msg_add_string(trusted_domain_state->policy->sam_ctx, mem_ctx, msg, "cn", name);
622 samdb_msg_add_string(trusted_domain_state->policy->sam_ctx, mem_ctx, msg, "flatname", name);
624 if (r->in.info->sid) {
625 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
627 return NT_STATUS_NO_MEMORY;
630 samdb_msg_add_string(trusted_domain_state->policy->sam_ctx, mem_ctx, msg, "securityIdentifier", sid_string);
633 /* pull in all the template attributes. Note this is always from the global samdb */
634 ret = samdb_copy_template(trusted_domain_state->policy->sam_ctx, mem_ctx, msg,
635 "(&(name=TemplateTrustedDomain)(objectclass=trustedDomainTemplate))");
637 DEBUG(0,("Failed to load TemplateTrustedDomain from samdb\n"));
638 return NT_STATUS_INTERNAL_DB_CORRUPTION;
641 samdb_msg_add_string(trusted_domain_state->policy->sam_ctx, mem_ctx, msg, "objectClass", "trustedDomain");
643 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
645 /* create the trusted_domain */
646 ret = samdb_add(trusted_domain_state->policy->sam_ctx, mem_ctx, msg);
648 DEBUG(0,("Failed to create trusted_domain record %s\n", msg->dn));
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 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 = samdb_search(trusted_domain_state->policy->sam_ctx,
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, policy_state->system_dn));
712 return NT_STATUS_INTERNAL_DB_CORRUPTION;
715 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
717 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
719 return NT_STATUS_NO_MEMORY;
722 handle->data = talloc_steal(handle, trusted_domain_state);
724 trusted_domain_state->access_mask = r->in.access_mask;
725 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
727 *r->out.trustdom_handle = handle->wire_handle;
734 lsa_OpenTrustedDomainByName
736 static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
738 struct lsa_OpenTrustedDomainByName *r)
740 struct dcesrv_handle *policy_handle;
742 struct lsa_policy_state *policy_state;
743 struct lsa_trusted_domain_state *trusted_domain_state;
744 struct dcesrv_handle *handle;
745 struct ldb_message **msgs;
746 const char *attrs[] = {
752 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
753 ZERO_STRUCTP(r->out.trustdom_handle);
754 policy_state = policy_handle->data;
756 if (!r->in.name.string) {
757 return NT_STATUS_INVALID_PARAMETER;
760 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
761 if (!trusted_domain_state) {
762 return NT_STATUS_NO_MEMORY;
764 trusted_domain_state->policy = policy_state;
766 /* search for the trusted_domain record */
767 ret = samdb_search(trusted_domain_state->policy->sam_ctx,
768 mem_ctx, policy_state->system_dn, &msgs, attrs,
769 "(&(flatname=%s)(objectclass=trustedDomain))",
772 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
776 DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
777 return NT_STATUS_INTERNAL_DB_CORRUPTION;
780 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
782 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
784 return NT_STATUS_NO_MEMORY;
787 handle->data = talloc_steal(handle, trusted_domain_state);
789 trusted_domain_state->access_mask = r->in.access_mask;
790 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
792 *r->out.trustdom_handle = handle->wire_handle;
799 lsa_QueryTrustedDomainInfoBySid
801 static NTSTATUS lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
802 struct lsa_QueryTrustedDomainInfoBySid *r)
804 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
809 lsa_SetTrustDomainInfo
811 static NTSTATUS lsa_SetTrustDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
812 struct lsa_SetTrustDomainInfo *r)
814 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
819 lsa_DeleteTrustDomain
821 static NTSTATUS lsa_DeleteTrustDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
822 struct lsa_DeleteTrustDomain *r)
824 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
829 lsa_QueryTrustedDomainInfo
831 static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
832 struct lsa_QueryTrustedDomainInfo *r)
834 struct dcesrv_handle *h;
835 struct lsa_trusted_domain_state *trusted_domain_state;
836 struct ldb_message *msg;
838 struct ldb_message **res;
839 const char *attrs[] = {
843 "securityIdentifier",
847 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
849 trusted_domain_state = h->data;
851 /* pull all the user attributes */
852 ret = samdb_search(trusted_domain_state->policy->sam_ctx, mem_ctx, NULL, &res, attrs,
853 "dn=%s", trusted_domain_state->trusted_domain_dn);
855 return NT_STATUS_INTERNAL_DB_CORRUPTION;
859 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
861 return NT_STATUS_NO_MEMORY;
863 switch (r->in.level) {
864 case LSA_TRUSTED_DOMAIN_INFO_NAME:
865 r->out.info->name.netbios_name.string
866 = samdb_result_string(msg, "flatname", NULL);
868 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
869 r->out.info->posix_offset.posix_offset
870 = samdb_result_uint(msg, "posixOffset", 0);
873 /* oops, we don't want to return the info after all */
874 talloc_free(r->out.info);
876 return NT_STATUS_INVALID_INFO_CLASS;
884 lsa_SetInformationTrustedDomain
886 static NTSTATUS lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
887 struct lsa_SetInformationTrustedDomain *r)
889 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
894 lsa_QueryTrustedDomainInfoByName
896 static NTSTATUS lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
898 struct lsa_QueryTrustedDomainInfoByName *r)
900 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
904 lsa_SetTrustedDomainInfoByName
906 static NTSTATUS lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
908 struct lsa_SetTrustedDomainInfoByName *r)
910 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
914 lsa_EnumTrustedDomainsEx
916 static NTSTATUS lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call,
918 struct lsa_EnumTrustedDomainsEx *r)
920 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
924 lsa_CloseTrustedDomainEx
926 static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
928 struct lsa_CloseTrustedDomainEx *r)
930 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
935 comparison function for sorting lsa_DomainInformation array
937 static int compare_DomainInformation(struct lsa_DomainInformation *e1, struct lsa_DomainInformation *e2)
939 return strcasecmp(e1->name.string, e2->name.string);
945 static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
946 struct lsa_EnumTrustDom *r)
948 struct dcesrv_handle *policy_handle;
949 struct lsa_DomainInformation *entries;
950 struct lsa_policy_state *policy_state;
951 struct ldb_message **domains;
952 const char *attrs[] = {
954 "securityIdentifier",
961 *r->out.resume_handle = 0;
963 r->out.domains->domains = NULL;
964 r->out.domains->count = 0;
966 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
968 policy_state = policy_handle->data;
970 /* search for all users in this domain. This could possibly be cached and
971 resumed based on resume_key */
972 count = samdb_search(policy_state->sam_ctx, mem_ctx, policy_state->system_dn, &domains, attrs,
973 "objectclass=trustedDomain");
975 return NT_STATUS_INTERNAL_DB_CORRUPTION;
977 if (count == 0 || r->in.max_size == 0) {
981 /* convert to lsa_DomainInformation format */
982 entries = talloc_array_p(mem_ctx, struct lsa_DomainInformation, count);
984 return NT_STATUS_NO_MEMORY;
986 for (i=0;i<count;i++) {
987 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
988 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
991 /* sort the results by name */
992 qsort(entries, count, sizeof(struct lsa_DomainInformation),
993 (comparison_fn_t)compare_DomainInformation);
995 if (*r->in.resume_handle >= count) {
996 *r->out.resume_handle = -1;
998 return NT_STATUS_NO_MORE_ENTRIES;
1001 /* return the rest, limit by max_size. Note that we
1002 use the w2k3 element size value of 60 */
1003 r->out.domains->count = count - *r->in.resume_handle;
1004 r->out.domains->count = MIN(r->out.domains->count,
1005 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1007 r->out.domains->domains = entries + *r->in.resume_handle;
1008 r->out.domains->count = r->out.domains->count;
1010 if (r->out.domains->count < count - *r->in.resume_handle) {
1011 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1012 return STATUS_MORE_ENTRIES;
1015 return NT_STATUS_OK;
1020 return the authority name and authority sid, given a sid
1022 static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
1023 TALLOC_CTX *mem_ctx, struct dom_sid *sid,
1024 const char **authority_name,
1025 struct dom_sid **authority_sid)
1027 if (dom_sid_in_domain(state->domain_sid, sid)) {
1028 *authority_name = state->domain_name;
1029 *authority_sid = state->domain_sid;
1030 return NT_STATUS_OK;
1033 if (dom_sid_in_domain(state->builtin_sid, sid)) {
1034 *authority_name = "BUILTIN";
1035 *authority_sid = state->builtin_sid;
1036 return NT_STATUS_OK;
1039 *authority_sid = dom_sid_dup(mem_ctx, sid);
1040 if (*authority_sid == NULL) {
1041 return NT_STATUS_NO_MEMORY;
1043 (*authority_sid)->num_auths = 0;
1044 *authority_name = dom_sid_string(mem_ctx, *authority_sid);
1045 if (*authority_name == NULL) {
1046 return NT_STATUS_NO_MEMORY;
1049 return NT_STATUS_OK;
1053 add to the lsa_RefDomainList for LookupSids and LookupNames
1055 static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1056 struct dom_sid *sid,
1057 struct lsa_RefDomainList *domains,
1058 uint32_t *sid_index)
1061 const char *authority_name;
1062 struct dom_sid *authority_sid;
1065 /* work out the authority name */
1066 status = lsa_authority_name(state, mem_ctx, sid,
1067 &authority_name, &authority_sid);
1068 if (!NT_STATUS_IS_OK(status)) {
1072 /* see if we've already done this authority name */
1073 for (i=0;i<domains->count;i++) {
1074 if (strcmp(authority_name, domains->domains[i].name.string) == 0) {
1076 return NT_STATUS_OK;
1080 domains->domains = talloc_realloc_p(domains,
1082 struct lsa_TrustInformation,
1084 if (domains->domains == NULL) {
1085 return NT_STATUS_NO_MEMORY;
1087 domains->domains[i].name.string = authority_name;
1088 domains->domains[i].sid = authority_sid;
1092 return NT_STATUS_OK;
1096 lookup a name for 1 SID
1098 static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1099 struct dom_sid *sid, const char *sid_str,
1100 const char **name, uint32_t *atype)
1103 struct ldb_message **res;
1104 const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "name", NULL};
1107 ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs,
1108 "objectSid=%s", sid_str);
1110 *name = ldb_msg_find_string(res[0], "sAMAccountName", NULL);
1112 *name = ldb_msg_find_string(res[0], "name", NULL);
1114 *name = talloc_strdup(mem_ctx, sid_str);
1115 NTSTATUS_TALLOC_CHECK(*name);
1119 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
1121 return NT_STATUS_OK;
1124 status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype);
1133 static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
1134 TALLOC_CTX *mem_ctx,
1135 struct lsa_LookupSids3 *r)
1137 struct lsa_policy_state *state;
1139 NTSTATUS status = NT_STATUS_OK;
1141 r->out.domains = NULL;
1143 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
1144 if (!NT_STATUS_IS_OK(status)) {
1148 r->out.domains = talloc_zero_p(mem_ctx, struct lsa_RefDomainList);
1149 if (r->out.domains == NULL) {
1150 return NT_STATUS_NO_MEMORY;
1153 r->out.names = talloc_zero_p(mem_ctx, struct lsa_TransNameArray2);
1154 if (r->out.names == NULL) {
1155 return NT_STATUS_NO_MEMORY;
1160 r->out.names->names = talloc_array_p(r->out.names, struct lsa_TranslatedName2,
1161 r->in.sids->num_sids);
1162 if (r->out.names->names == NULL) {
1163 return NT_STATUS_NO_MEMORY;
1166 for (i=0;i<r->in.sids->num_sids;i++) {
1167 struct dom_sid *sid = r->in.sids->sids[i].sid;
1168 char *sid_str = dom_sid_string(mem_ctx, sid);
1170 uint32_t atype, rtype, sid_index;
1173 r->out.names->count++;
1176 r->out.names->names[i].sid_type = SID_NAME_UNKNOWN;
1177 r->out.names->names[i].name.string = sid_str;
1178 r->out.names->names[i].sid_index = 0xFFFFFFFF;
1179 r->out.names->names[i].unknown = 0;
1181 if (sid_str == NULL) {
1182 r->out.names->names[i].name.string = "(SIDERROR)";
1183 status = STATUS_SOME_UNMAPPED;
1187 /* work out the authority name */
1188 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
1189 if (!NT_STATUS_IS_OK(status2)) {
1193 status2 = lsa_lookup_sid(state, mem_ctx, sid, sid_str,
1195 if (!NT_STATUS_IS_OK(status2)) {
1196 status = STATUS_SOME_UNMAPPED;
1200 rtype = samdb_atype_map(atype);
1201 if (rtype == SID_NAME_UNKNOWN) {
1202 status = STATUS_SOME_UNMAPPED;
1206 r->out.names->names[i].sid_type = rtype;
1207 r->out.names->names[i].name.string = name;
1208 r->out.names->names[i].sid_index = sid_index;
1209 r->out.names->names[i].unknown = 0;
1219 static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
1220 TALLOC_CTX *mem_ctx,
1221 struct lsa_LookupSids2 *r)
1223 struct lsa_LookupSids3 r3;
1226 r3.in.sids = r->in.sids;
1227 r3.in.names = r->in.names;
1228 r3.in.level = r->in.level;
1229 r3.in.count = r->in.count;
1230 r3.in.unknown1 = r->in.unknown1;
1231 r3.in.unknown2 = r->in.unknown2;
1232 r3.out.count = r->out.count;
1233 r3.out.names = r->out.names;
1235 status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
1236 if (dce_call->fault_code != 0) {
1240 r->out.domains = r3.out.domains;
1241 r->out.names = r3.out.names;
1242 r->out.count = r3.out.count;
1251 static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1252 struct lsa_LookupSids *r)
1254 struct lsa_LookupSids3 r3;
1258 r3.in.sids = r->in.sids;
1260 r3.in.level = r->in.level;
1261 r3.in.count = r->in.count;
1264 r3.out.count = r->out.count;
1266 status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
1267 if (dce_call->fault_code != 0) {
1271 r->out.domains = r3.out.domains;
1272 r->out.names = talloc_p(mem_ctx, struct lsa_TransNameArray);
1273 if (r->out.names == NULL) {
1274 return NT_STATUS_NO_MEMORY;
1276 r->out.names->count = r3.out.names->count;
1277 r->out.names->names = talloc_array_p(r->out.names, struct lsa_TranslatedName,
1278 r->out.names->count);
1279 if (r->out.names->names == NULL) {
1280 return NT_STATUS_NO_MEMORY;
1282 for (i=0;i<r->out.names->count;i++) {
1283 r->out.names->names[i].sid_type = r3.out.names->names[i].sid_type;
1284 r->out.names->names[i].name.string = r3.out.names->names[i].name.string;
1285 r->out.names->names[i].sid_index = r3.out.names->names[i].sid_index;
1295 static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1296 struct lsa_OpenAccount *r)
1298 struct dcesrv_handle *h, *ah;
1299 struct lsa_policy_state *state;
1300 struct lsa_account_state *astate;
1302 ZERO_STRUCTP(r->out.acct_handle);
1304 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1308 astate = talloc_p(dce_call->conn, struct lsa_account_state);
1309 if (astate == NULL) {
1310 return NT_STATUS_NO_MEMORY;
1313 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1314 if (astate->account_sid == NULL) {
1315 talloc_free(astate);
1316 return NT_STATUS_NO_MEMORY;
1319 astate->account_sid_str = dom_sid_string(astate, astate->account_sid);
1320 if (astate->account_sid_str == NULL) {
1321 talloc_free(astate);
1322 return NT_STATUS_NO_MEMORY;
1325 /* check it really exists */
1326 astate->account_dn = samdb_search_string(state->sam_ctx, astate,
1328 "(&(objectSid=%s)(objectClass=group))",
1329 astate->account_sid_str);
1330 if (astate->account_dn == NULL) {
1331 talloc_free(astate);
1332 return NT_STATUS_NO_SUCH_USER;
1335 astate->policy = talloc_reference(astate, state);
1336 astate->access_mask = r->in.access_mask;
1338 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1340 talloc_free(astate);
1341 return NT_STATUS_NO_MEMORY;
1344 ah->data = talloc_steal(ah, astate);
1346 *r->out.acct_handle = ah->wire_handle;
1348 return NT_STATUS_OK;
1353 lsa_EnumPrivsAccount
1355 static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1356 TALLOC_CTX *mem_ctx,
1357 struct lsa_EnumPrivsAccount *r)
1359 struct dcesrv_handle *h;
1360 struct lsa_account_state *astate;
1362 struct ldb_message **res;
1363 const char * const attrs[] = { "privilege", NULL};
1364 struct ldb_message_element *el;
1366 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1370 r->out.privs = talloc_p(mem_ctx, struct lsa_PrivilegeSet);
1371 r->out.privs->count = 0;
1372 r->out.privs->unknown = 0;
1373 r->out.privs->set = NULL;
1375 ret = samdb_search(astate->policy->sam_ctx, mem_ctx, NULL, &res, attrs,
1376 "dn=%s", astate->account_dn);
1378 return NT_STATUS_OK;
1381 el = ldb_msg_find_element(res[0], "privilege");
1382 if (el == NULL || el->num_values == 0) {
1383 return NT_STATUS_OK;
1386 r->out.privs->set = talloc_array_p(r->out.privs,
1387 struct lsa_LUIDAttribute, el->num_values);
1388 if (r->out.privs->set == NULL) {
1389 return NT_STATUS_NO_MEMORY;
1392 for (i=0;i<el->num_values;i++) {
1393 int id = sec_privilege_id(el->values[i].data);
1395 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1397 r->out.privs->set[i].attribute = 0;
1398 r->out.privs->set[i].luid.low = id;
1399 r->out.privs->set[i].luid.high = 0;
1402 r->out.privs->count = el->num_values;
1404 return NT_STATUS_OK;
1408 lsa_EnumAccountRights
1410 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1411 TALLOC_CTX *mem_ctx,
1412 struct lsa_EnumAccountRights *r)
1414 struct dcesrv_handle *h;
1415 struct lsa_policy_state *state;
1417 struct ldb_message **res;
1418 const char * const attrs[] = { "privilege", NULL};
1420 struct ldb_message_element *el;
1422 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1426 sidstr = dom_sid_string(mem_ctx, r->in.sid);
1427 if (sidstr == NULL) {
1428 return NT_STATUS_NO_MEMORY;
1431 ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs,
1432 "objectSid=%s", sidstr);
1434 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1437 el = ldb_msg_find_element(res[0], "privilege");
1438 if (el == NULL || el->num_values == 0) {
1439 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1442 r->out.rights->count = el->num_values;
1443 r->out.rights->names = talloc_array_p(r->out.rights,
1444 struct lsa_String, r->out.rights->count);
1445 if (r->out.rights->names == NULL) {
1446 return NT_STATUS_NO_MEMORY;
1449 for (i=0;i<el->num_values;i++) {
1450 r->out.rights->names[i].string = el->values[i].data;
1453 return NT_STATUS_OK;
1459 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1461 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1462 TALLOC_CTX *mem_ctx,
1463 struct lsa_policy_state *state,
1465 struct dom_sid *sid,
1466 const struct lsa_RightSet *rights)
1469 struct ldb_message *msg;
1470 struct ldb_message_element el;
1473 struct lsa_EnumAccountRights r2;
1475 sidstr = dom_sid_string(mem_ctx, sid);
1476 if (sidstr == NULL) {
1477 return NT_STATUS_NO_MEMORY;
1480 msg = ldb_msg_new(mem_ctx);
1482 return NT_STATUS_NO_MEMORY;
1485 dn = samdb_search_string(state->sam_ctx, mem_ctx, NULL, "dn",
1486 "objectSid=%s", sidstr);
1488 return NT_STATUS_NO_SUCH_USER;
1491 msg->dn = talloc_strdup(mem_ctx, dn);
1492 if (msg->dn == NULL) {
1493 return NT_STATUS_NO_MEMORY;
1496 if (ldb_msg_add_empty(state->sam_ctx->ldb, msg, "privilege", ldb_flag)) {
1497 return NT_STATUS_NO_MEMORY;
1500 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1503 r2.in.handle = &state->handle->wire_handle;
1505 r2.out.rights = talloc_p(mem_ctx, struct lsa_RightSet);
1507 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1508 if (!NT_STATUS_IS_OK(status)) {
1509 ZERO_STRUCTP(r2.out.rights);
1514 el.values = talloc_array_p(mem_ctx, struct ldb_val, rights->count);
1515 if (el.values == NULL) {
1516 return NT_STATUS_NO_MEMORY;
1518 for (i=0;i<rights->count;i++) {
1519 if (sec_privilege_id(rights->names[i].string) == -1) {
1520 return NT_STATUS_NO_SUCH_PRIVILEGE;
1523 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1525 for (j=0;j<r2.out.rights->count;j++) {
1526 if (StrCaseCmp(r2.out.rights->names[j].string,
1527 rights->names[i].string) == 0) {
1531 if (j != r2.out.rights->count) continue;
1535 el.values[el.num_values].length = strlen(rights->names[i].string);
1536 el.values[el.num_values].data = talloc_strdup(mem_ctx, rights->names[i].string);
1537 if (el.values[el.num_values].data == NULL) {
1538 return NT_STATUS_NO_MEMORY;
1543 if (el.num_values == 0) {
1544 return NT_STATUS_OK;
1547 ret = samdb_modify(state->sam_ctx, mem_ctx, msg);
1549 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1550 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1552 return NT_STATUS_UNEXPECTED_IO_ERROR;
1555 return NT_STATUS_OK;
1559 lsa_AddPrivilegesToAccount
1561 static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1562 struct lsa_AddPrivilegesToAccount *r)
1564 struct lsa_RightSet rights;
1565 struct dcesrv_handle *h;
1566 struct lsa_account_state *astate;
1569 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1573 rights.count = r->in.privs->count;
1574 rights.names = talloc_array_p(mem_ctx, struct lsa_String, 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 lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1590 LDB_FLAG_MOD_ADD, astate->account_sid,
1596 lsa_RemovePrivilegesFromAccount
1598 static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1599 struct lsa_RemovePrivilegesFromAccount *r)
1601 struct lsa_RightSet *rights;
1602 struct dcesrv_handle *h;
1603 struct lsa_account_state *astate;
1606 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1610 rights = talloc_p(mem_ctx, struct lsa_RightSet);
1612 if (r->in.remove_all == 1 &&
1613 r->in.privs == NULL) {
1614 struct lsa_EnumAccountRights r2;
1617 r2.in.handle = &astate->policy->handle->wire_handle;
1618 r2.in.sid = astate->account_sid;
1619 r2.out.rights = rights;
1621 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1622 if (!NT_STATUS_IS_OK(status)) {
1626 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1627 LDB_FLAG_MOD_DELETE, astate->account_sid,
1631 if (r->in.remove_all != 0) {
1632 return NT_STATUS_INVALID_PARAMETER;
1635 rights->count = r->in.privs->count;
1636 rights->names = talloc_array_p(mem_ctx, struct lsa_String, rights->count);
1637 if (rights->names == NULL) {
1638 return NT_STATUS_NO_MEMORY;
1640 for (i=0;i<rights->count;i++) {
1641 int id = r->in.privs->set[i].luid.low;
1642 if (r->in.privs->set[i].luid.high) {
1643 return NT_STATUS_NO_SUCH_PRIVILEGE;
1645 rights->names[i].string = sec_privilege_name(id);
1646 if (rights->names[i].string == NULL) {
1647 return NT_STATUS_NO_SUCH_PRIVILEGE;
1651 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1652 LDB_FLAG_MOD_DELETE, astate->account_sid,
1658 lsa_GetQuotasForAccount
1660 static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1661 struct lsa_GetQuotasForAccount *r)
1663 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1668 lsa_SetQuotasForAccount
1670 static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1671 struct lsa_SetQuotasForAccount *r)
1673 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1678 lsa_GetSystemAccessAccount
1680 static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1681 struct lsa_GetSystemAccessAccount *r)
1683 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1688 lsa_SetSystemAccessAccount
1690 static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1691 struct lsa_SetSystemAccessAccount *r)
1693 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1700 static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1701 struct lsa_CreateSecret *r)
1703 struct dcesrv_handle *policy_handle;
1704 struct lsa_policy_state *policy_state;
1705 struct lsa_secret_state *secret_state;
1706 struct dcesrv_handle *handle;
1707 struct ldb_message **msgs, *msg;
1708 const char *attrs[] = {
1716 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1717 ZERO_STRUCTP(r->out.sec_handle);
1719 policy_state = policy_handle->data;
1721 if (!r->in.name.string) {
1722 return NT_STATUS_INVALID_PARAMETER;
1725 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1726 if (!secret_state) {
1727 return NT_STATUS_NO_MEMORY;
1729 secret_state->policy = policy_state;
1731 msg = ldb_msg_new(mem_ctx);
1733 return NT_STATUS_NO_MEMORY;
1736 if (strncmp("G$", r->in.name.string, 2) == 0) {
1738 name = &r->in.name.string[2];
1739 secret_state->sam_ctx = talloc_reference(secret_state, policy_state->sam_ctx);
1740 secret_state->global = True;
1742 if (strlen(name) < 1) {
1743 return NT_STATUS_INVALID_PARAMETER;
1746 name2 = talloc_asprintf(mem_ctx, "%s Secret", name);
1747 /* search for the secret record */
1748 ret = samdb_search(secret_state->sam_ctx,
1749 mem_ctx, policy_state->system_dn, &msgs, attrs,
1750 "(&(cn=%s)(objectclass=secret))",
1753 return NT_STATUS_OBJECT_NAME_COLLISION;
1756 if (ret < 0 || ret > 1) {
1757 DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
1758 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1761 msg->dn = talloc_asprintf(mem_ctx, "cn=%s,%s", name2, policy_state->system_dn);
1762 if (!name2 || !msg->dn) {
1763 return NT_STATUS_NO_MEMORY;
1766 samdb_msg_add_string(secret_state->sam_ctx, mem_ctx, msg, "cn", name2);
1769 secret_state->global = False;
1771 name = r->in.name.string;
1772 if (strlen(name) < 1) {
1773 return NT_STATUS_INVALID_PARAMETER;
1776 secret_state->sam_ctx = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1777 /* search for the secret record */
1778 ret = samdb_search(secret_state->sam_ctx,
1779 mem_ctx, "cn=LSA Secrets", &msgs, attrs,
1780 "(&(cn=%s)(objectclass=secret))",
1783 return NT_STATUS_OBJECT_NAME_COLLISION;
1786 if (ret < 0 || ret > 1) {
1787 DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
1788 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1791 msg->dn = talloc_asprintf(mem_ctx, "cn=%s,cn=LSA Secrets", name);
1792 samdb_msg_add_string(secret_state->sam_ctx, mem_ctx, msg, "cn", name);
1795 /* pull in all the template attributes. Note this is always from the global samdb */
1796 ret = samdb_copy_template(secret_state->policy->sam_ctx, mem_ctx, msg,
1797 "(&(name=TemplateSecret)(objectclass=secretTemplate))");
1799 DEBUG(0,("Failed to load TemplateSecret from samdb\n"));
1800 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1803 samdb_msg_add_string(secret_state->sam_ctx, mem_ctx, msg, "objectClass", "secret");
1805 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1807 /* create the secret */
1808 ret = samdb_add(secret_state->sam_ctx, mem_ctx, msg);
1810 DEBUG(0,("Failed to create secret record %s\n", msg->dn));
1811 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1814 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1816 return NT_STATUS_NO_MEMORY;
1819 handle->data = talloc_steal(handle, secret_state);
1821 secret_state->access_mask = r->in.access_mask;
1822 secret_state->policy = talloc_reference(secret_state, policy_state);
1824 *r->out.sec_handle = handle->wire_handle;
1826 return NT_STATUS_OK;
1833 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1834 struct lsa_OpenSecret *r)
1836 struct dcesrv_handle *policy_handle;
1838 struct lsa_policy_state *policy_state;
1839 struct lsa_secret_state *secret_state;
1840 struct dcesrv_handle *handle;
1841 struct ldb_message **msgs;
1842 const char *attrs[] = {
1850 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1851 ZERO_STRUCTP(r->out.sec_handle);
1852 policy_state = policy_handle->data;
1854 if (!r->in.name.string) {
1855 return NT_STATUS_INVALID_PARAMETER;
1858 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1859 if (!secret_state) {
1860 return NT_STATUS_NO_MEMORY;
1862 secret_state->policy = policy_state;
1864 if (strncmp("G$", r->in.name.string, 2) == 0) {
1865 name = &r->in.name.string[2];
1866 secret_state->sam_ctx = talloc_reference(secret_state, policy_state->sam_ctx);
1867 secret_state->global = True;
1869 if (strlen(name) < 1) {
1870 return NT_STATUS_INVALID_PARAMETER;
1873 /* search for the secret record */
1874 ret = samdb_search(secret_state->sam_ctx,
1875 mem_ctx, policy_state->system_dn, &msgs, attrs,
1876 "(&(cn=%s Secret)(objectclass=secret))",
1879 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1883 DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
1884 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1888 secret_state->sam_ctx = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1890 secret_state->global = False;
1891 name = r->in.name.string;
1892 if (strlen(name) < 1) {
1893 return NT_STATUS_INVALID_PARAMETER;
1896 /* search for the secret record */
1897 ret = samdb_search(secret_state->sam_ctx,
1898 mem_ctx, "cn=LSA Secrets", &msgs, attrs,
1899 "(&(cn=%s)(objectclass=secret))",
1902 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1906 DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
1907 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1911 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1913 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1915 return NT_STATUS_NO_MEMORY;
1918 handle->data = talloc_steal(handle, secret_state);
1920 secret_state->access_mask = r->in.access_mask;
1921 secret_state->policy = talloc_reference(secret_state, policy_state);
1923 *r->out.sec_handle = handle->wire_handle;
1925 return NT_STATUS_OK;
1932 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1933 struct lsa_SetSecret *r)
1936 struct dcesrv_handle *h;
1937 struct lsa_secret_state *secret_state;
1938 struct ldb_message *msg;
1939 DATA_BLOB session_key;
1940 DATA_BLOB crypt_secret, secret;
1943 NTSTATUS status = NT_STATUS_OK;
1945 struct timeval now = timeval_current();
1946 NTTIME nt_now = timeval_to_nttime(&now);
1948 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
1950 secret_state = h->data;
1952 msg = ldb_msg_new(mem_ctx);
1954 return NT_STATUS_NO_MEMORY;
1957 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
1959 return NT_STATUS_NO_MEMORY;
1961 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
1962 if (!NT_STATUS_IS_OK(status)) {
1966 if (r->in.old_val) {
1968 crypt_secret.data = r->in.old_val->data;
1969 crypt_secret.length = r->in.old_val->size;
1971 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1972 if (!NT_STATUS_IS_OK(status)) {
1976 val.data = secret.data;
1977 val.length = secret.length;
1980 if (samdb_msg_add_value(secret_state->sam_ctx,
1981 mem_ctx, msg, "priorSecret", &val) != 0) {
1982 return NT_STATUS_NO_MEMORY;
1985 /* set old value mtime */
1986 if (samdb_msg_add_uint64(secret_state->sam_ctx,
1987 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
1988 return NT_STATUS_NO_MEMORY;
1991 if (!r->in.new_val) {
1992 /* This behaviour varies depending of if this is a local, or a global secret... */
1993 if (secret_state->global) {
1994 /* set old value mtime */
1995 if (samdb_msg_add_uint64(secret_state->sam_ctx,
1996 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
1997 return NT_STATUS_NO_MEMORY;
2000 if (samdb_msg_add_delete(secret_state->sam_ctx,
2001 mem_ctx, msg, "secret")) {
2002 return NT_STATUS_NO_MEMORY;
2004 if (samdb_msg_add_delete(secret_state->sam_ctx,
2005 mem_ctx, msg, "lastSetTime")) {
2006 return NT_STATUS_NO_MEMORY;
2012 if (r->in.new_val) {
2014 crypt_secret.data = r->in.new_val->data;
2015 crypt_secret.length = r->in.new_val->size;
2017 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2018 if (!NT_STATUS_IS_OK(status)) {
2022 val.data = secret.data;
2023 val.length = secret.length;
2026 if (samdb_msg_add_value(secret_state->sam_ctx,
2027 mem_ctx, msg, "secret", &val) != 0) {
2028 return NT_STATUS_NO_MEMORY;
2031 /* set new value mtime */
2032 if (samdb_msg_add_uint64(secret_state->sam_ctx,
2033 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2034 return NT_STATUS_NO_MEMORY;
2037 /* If the old value is not set, then migrate the
2038 * current value to the old value */
2039 if (!r->in.old_val) {
2040 const struct ldb_val *new_val;
2041 NTTIME last_set_time;
2042 struct ldb_message **res;
2043 const char *attrs[] = {
2049 /* search for the secret record */
2050 ret = samdb_search(secret_state->sam_ctx,
2051 mem_ctx, NULL, &res, attrs,
2052 "(dn=%s)", secret_state->secret_dn);
2054 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2058 DEBUG(0,("Found %d records matching dn=%s\n", ret, secret_state->secret_dn));
2059 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2062 new_val = ldb_msg_find_ldb_val(res[0], "secret");
2063 last_set_time = ldb_msg_find_uint64(res[0], "lastSetTime", 0);
2067 if (samdb_msg_add_value(secret_state->sam_ctx,
2068 mem_ctx, msg, "priorSecret",
2070 return NT_STATUS_NO_MEMORY;
2074 /* set new value mtime */
2075 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2076 if (samdb_msg_add_uint64(secret_state->sam_ctx,
2077 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2078 return NT_STATUS_NO_MEMORY;
2084 /* modify the samdb record */
2085 ret = samdb_replace(secret_state->sam_ctx, mem_ctx, msg);
2087 /* we really need samdb.c to return NTSTATUS */
2088 return NT_STATUS_UNSUCCESSFUL;
2091 return NT_STATUS_OK;
2098 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2099 struct lsa_QuerySecret *r)
2101 struct dcesrv_handle *h;
2102 struct lsa_secret_state *secret_state;
2103 struct ldb_message *msg;
2104 DATA_BLOB session_key;
2105 DATA_BLOB crypt_secret, secret;
2107 struct ldb_message **res;
2108 const char *attrs[] = {
2118 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2120 secret_state = h->data;
2122 /* pull all the user attributes */
2123 ret = samdb_search(secret_state->sam_ctx, mem_ctx, NULL, &res, attrs,
2124 "dn=%s", secret_state->secret_dn);
2126 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2130 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2131 if (!NT_STATUS_IS_OK(nt_status)) {
2135 if (r->in.old_val) {
2136 const struct ldb_val *prior_val;
2137 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2138 if (!r->out.old_val) {
2139 return NT_STATUS_NO_MEMORY;
2142 prior_val = ldb_msg_find_ldb_val(res[0], "priorSecret");
2144 if (prior_val && prior_val->length) {
2145 secret.data = prior_val->data;
2146 secret.length = prior_val->length;
2148 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2149 if (!crypt_secret.length) {
2150 return NT_STATUS_NO_MEMORY;
2152 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2153 if (!r->out.old_val->buf) {
2154 return NT_STATUS_NO_MEMORY;
2156 r->out.old_val->buf->size = crypt_secret.length;
2157 r->out.old_val->buf->length = crypt_secret.length;
2158 r->out.old_val->buf->data = crypt_secret.data;
2162 if (r->in.old_mtime) {
2163 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2164 if (!r->out.old_mtime) {
2165 return NT_STATUS_NO_MEMORY;
2167 *r->out.old_mtime = ldb_msg_find_uint64(res[0], "priorSetTime", 0);
2170 if (r->in.new_val) {
2171 const struct ldb_val *new_val;
2172 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2173 if (!r->out.new_val) {
2174 return NT_STATUS_NO_MEMORY;
2178 new_val = ldb_msg_find_ldb_val(res[0], "secret");
2180 if (new_val && new_val->length) {
2181 secret.data = new_val->data;
2182 secret.length = new_val->length;
2184 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2185 if (!crypt_secret.length) {
2186 return NT_STATUS_NO_MEMORY;
2188 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2189 if (!r->out.new_val->buf) {
2190 return NT_STATUS_NO_MEMORY;
2192 r->out.new_val->buf->length = crypt_secret.length;
2193 r->out.new_val->buf->size = crypt_secret.length;
2194 r->out.new_val->buf->data = crypt_secret.data;
2198 if (r->in.new_mtime) {
2199 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2200 if (!r->out.new_mtime) {
2201 return NT_STATUS_NO_MEMORY;
2203 *r->out.new_mtime = ldb_msg_find_uint64(res[0], "lastSetTime", 0);
2206 return NT_STATUS_OK;
2213 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2214 TALLOC_CTX *mem_ctx,
2215 struct lsa_LookupPrivValue *r)
2217 struct dcesrv_handle *h;
2218 struct lsa_policy_state *state;
2221 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2225 id = sec_privilege_id(r->in.name->string);
2227 return NT_STATUS_NO_SUCH_PRIVILEGE;
2230 r->out.luid->low = id;
2231 r->out.luid->high = 0;
2233 return NT_STATUS_OK;
2240 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2241 TALLOC_CTX *mem_ctx,
2242 struct lsa_LookupPrivName *r)
2244 struct dcesrv_handle *h;
2245 struct lsa_policy_state *state;
2246 const char *privname;
2248 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2252 if (r->in.luid->high != 0) {
2253 return NT_STATUS_NO_SUCH_PRIVILEGE;
2256 privname = sec_privilege_name(r->in.luid->low);
2257 if (privname == NULL) {
2258 return NT_STATUS_NO_SUCH_PRIVILEGE;
2261 r->out.name = talloc_p(mem_ctx, struct lsa_String);
2262 if (r->out.name == NULL) {
2263 return NT_STATUS_NO_MEMORY;
2265 r->out.name->string = privname;
2267 return NT_STATUS_OK;
2272 lsa_LookupPrivDisplayName
2274 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2275 TALLOC_CTX *mem_ctx,
2276 struct lsa_LookupPrivDisplayName *r)
2278 struct dcesrv_handle *h;
2279 struct lsa_policy_state *state;
2282 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2286 id = sec_privilege_id(r->in.name->string);
2288 return NT_STATUS_NO_SUCH_PRIVILEGE;
2291 r->out.disp_name = talloc_p(mem_ctx, struct lsa_String);
2292 if (r->out.disp_name == NULL) {
2293 return NT_STATUS_NO_MEMORY;
2296 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2297 if (r->out.disp_name->string == NULL) {
2298 return NT_STATUS_INTERNAL_ERROR;
2301 return NT_STATUS_OK;
2308 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2309 struct lsa_DeleteObject *r)
2311 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2316 lsa_EnumAccountsWithUserRight
2318 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2319 TALLOC_CTX *mem_ctx,
2320 struct lsa_EnumAccountsWithUserRight *r)
2322 struct dcesrv_handle *h;
2323 struct lsa_policy_state *state;
2325 struct ldb_message **res;
2326 const char * const attrs[] = { "objectSid", NULL};
2327 const char *privname;
2329 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2333 if (r->in.name == NULL) {
2334 return NT_STATUS_NO_SUCH_PRIVILEGE;
2337 privname = r->in.name->string;
2338 if (sec_privilege_id(privname) == -1) {
2339 return NT_STATUS_NO_SUCH_PRIVILEGE;
2342 ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs,
2343 "privilege=%s", privname);
2345 return NT_STATUS_NO_SUCH_USER;
2348 r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_SidPtr, ret);
2349 if (r->out.sids->sids == NULL) {
2350 return NT_STATUS_NO_MEMORY;
2352 for (i=0;i<ret;i++) {
2354 sidstr = samdb_result_string(res[i], "objectSid", NULL);
2355 if (sidstr == NULL) {
2356 return NT_STATUS_NO_MEMORY;
2358 r->out.sids->sids[i].sid = dom_sid_parse_talloc(r->out.sids->sids,
2360 if (r->out.sids->sids[i].sid == NULL) {
2361 return NT_STATUS_NO_MEMORY;
2364 r->out.sids->num_sids = ret;
2366 return NT_STATUS_OK;
2371 lsa_AddAccountRights
2373 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2374 TALLOC_CTX *mem_ctx,
2375 struct lsa_AddAccountRights *r)
2377 struct dcesrv_handle *h;
2378 struct lsa_policy_state *state;
2380 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2384 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2386 r->in.sid, r->in.rights);
2391 lsa_RemoveAccountRights
2393 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2394 TALLOC_CTX *mem_ctx,
2395 struct lsa_RemoveAccountRights *r)
2397 struct dcesrv_handle *h;
2398 struct lsa_policy_state *state;
2400 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2404 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2405 LDB_FLAG_MOD_DELETE,
2406 r->in.sid, r->in.rights);
2411 lsa_StorePrivateData
2413 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2414 struct lsa_StorePrivateData *r)
2416 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2421 lsa_RetrievePrivateData
2423 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2424 struct lsa_RetrievePrivateData *r)
2426 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2433 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2434 struct lsa_GetUserName *r)
2436 NTSTATUS status = NT_STATUS_OK;
2437 const char *account_name;
2438 const char *authority_name;
2439 struct lsa_String *_account_name;
2440 struct lsa_StringPointer *_authority_name = NULL;
2442 /* this is what w2k3 does */
2443 r->out.account_name = r->in.account_name;
2444 r->out.authority_name = r->in.authority_name;
2446 if (r->in.account_name && r->in.account_name->string) {
2447 return NT_STATUS_INVALID_PARAMETER;
2450 if (r->in.authority_name &&
2451 r->in.authority_name->string &&
2452 r->in.authority_name->string->string) {
2453 return NT_STATUS_INVALID_PARAMETER;
2456 /* TODO: this check should go and we should rely on the calling code that this is valid */
2457 if (!dce_call->conn->auth_state.session_info ||
2458 !dce_call->conn->auth_state.session_info->server_info ||
2459 !dce_call->conn->auth_state.session_info->server_info->account_name ||
2460 !dce_call->conn->auth_state.session_info->server_info->domain_name) {
2461 return NT_STATUS_INTERNAL_ERROR;
2464 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2465 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2467 _account_name = talloc_p(mem_ctx, struct lsa_String);
2468 NTSTATUS_TALLOC_CHECK(_account_name);
2469 _account_name->string = account_name;
2471 if (r->in.authority_name) {
2472 _authority_name = talloc_p(mem_ctx, struct lsa_StringPointer);
2473 NTSTATUS_TALLOC_CHECK(_authority_name);
2474 _authority_name->string = talloc_p(mem_ctx, struct lsa_String);
2475 NTSTATUS_TALLOC_CHECK(_authority_name->string);
2476 _authority_name->string->string = authority_name;
2479 r->out.account_name = _account_name;
2480 r->out.authority_name = _authority_name;
2488 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2489 TALLOC_CTX *mem_ctx,
2490 struct lsa_SetInfoPolicy2 *r)
2492 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2496 lsa_QueryDomainInformationPolicy
2498 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2499 TALLOC_CTX *mem_ctx,
2500 struct lsa_QueryDomainInformationPolicy *r)
2502 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2506 lsa_SetDomInfoPolicy
2508 static NTSTATUS lsa_SetDomInfoPolicy(struct dcesrv_call_state *dce_call,
2509 TALLOC_CTX *mem_ctx,
2510 struct lsa_SetDomInfoPolicy *r)
2512 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2518 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
2519 TALLOC_CTX *mem_ctx,
2520 struct lsa_TestCall *r)
2522 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2526 lookup a SID for 1 name
2528 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
2529 const char *name, struct dom_sid **sid, uint32_t *atype)
2532 struct ldb_message **res;
2533 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
2536 p = strchr_m(name, '\\');
2538 /* TODO: properly parse the domain prefix here, and use it to
2543 ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", name);
2545 const char *sid_str = ldb_msg_find_string(res[0], "objectSid", NULL);
2546 if (sid_str == NULL) {
2547 return NT_STATUS_INVALID_SID;
2550 *sid = dom_sid_parse_talloc(mem_ctx, sid_str);
2552 return NT_STATUS_INVALID_SID;
2555 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
2557 return NT_STATUS_OK;
2560 /* need to add a call into sidmap to check for a allocated sid */
2562 return NT_STATUS_INVALID_SID;
2569 static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call,
2570 TALLOC_CTX *mem_ctx,
2571 struct lsa_LookupNames3 *r)
2573 struct lsa_policy_state *state;
2574 struct dcesrv_handle *h;
2576 NTSTATUS status = NT_STATUS_OK;
2578 r->out.domains = NULL;
2580 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2584 r->out.domains = talloc_zero_p(mem_ctx, struct lsa_RefDomainList);
2585 if (r->out.domains == NULL) {
2586 return NT_STATUS_NO_MEMORY;
2589 r->out.sids = talloc_zero_p(mem_ctx, struct lsa_TransSidArray3);
2590 if (r->out.sids == NULL) {
2591 return NT_STATUS_NO_MEMORY;
2596 r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_TranslatedSid3,
2598 if (r->out.sids->sids == NULL) {
2599 return NT_STATUS_NO_MEMORY;
2602 for (i=0;i<r->in.num_names;i++) {
2603 const char *name = r->in.names[i].string;
2604 struct dom_sid *sid;
2605 uint32_t atype, rtype, sid_index;
2608 r->out.sids->count++;
2611 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
2612 r->out.sids->sids[i].sid = NULL;
2613 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
2614 r->out.sids->sids[i].unknown = 0;
2616 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
2617 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
2618 status = STATUS_SOME_UNMAPPED;
2622 rtype = samdb_atype_map(atype);
2623 if (rtype == SID_NAME_UNKNOWN) {
2624 status = STATUS_SOME_UNMAPPED;
2628 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
2629 if (!NT_STATUS_IS_OK(status2)) {
2633 r->out.sids->sids[i].sid_type = rtype;
2634 r->out.sids->sids[i].sid = sid;
2635 r->out.sids->sids[i].sid_index = sid_index;
2636 r->out.sids->sids[i].unknown = 0;
2645 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
2646 TALLOC_CTX *mem_ctx,
2647 struct lsa_LookupNames2 *r)
2649 struct lsa_policy_state *state;
2650 struct dcesrv_handle *h;
2652 NTSTATUS status = NT_STATUS_OK;
2654 r->out.domains = NULL;
2656 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2660 r->out.domains = talloc_zero_p(mem_ctx, struct lsa_RefDomainList);
2661 if (r->out.domains == NULL) {
2662 return NT_STATUS_NO_MEMORY;
2665 r->out.sids = talloc_zero_p(mem_ctx, struct lsa_TransSidArray2);
2666 if (r->out.sids == NULL) {
2667 return NT_STATUS_NO_MEMORY;
2672 r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_TranslatedSid2,
2674 if (r->out.sids->sids == NULL) {
2675 return NT_STATUS_NO_MEMORY;
2678 for (i=0;i<r->in.num_names;i++) {
2679 const char *name = r->in.names[i].string;
2680 struct dom_sid *sid;
2681 uint32_t atype, rtype, sid_index;
2684 r->out.sids->count++;
2687 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
2688 r->out.sids->sids[i].rid = 0xFFFFFFFF;
2689 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
2690 r->out.sids->sids[i].unknown = 0;
2692 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
2693 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
2694 status = STATUS_SOME_UNMAPPED;
2698 rtype = samdb_atype_map(atype);
2699 if (rtype == SID_NAME_UNKNOWN) {
2700 status = STATUS_SOME_UNMAPPED;
2704 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
2705 if (!NT_STATUS_IS_OK(status2)) {
2709 r->out.sids->sids[i].sid_type = rtype;
2710 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
2711 r->out.sids->sids[i].sid_index = sid_index;
2712 r->out.sids->sids[i].unknown = 0;
2721 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2722 struct lsa_LookupNames *r)
2724 struct lsa_LookupNames2 r2;
2728 r2.in.handle = r->in.handle;
2729 r2.in.num_names = r->in.num_names;
2730 r2.in.names = r->in.names;
2732 r2.in.level = r->in.level;
2733 r2.in.count = r->in.count;
2736 r2.out.count = r->out.count;
2738 status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
2739 if (dce_call->fault_code != 0) {
2743 r->out.domains = r2.out.domains;
2744 r->out.sids = talloc_p(mem_ctx, struct lsa_TransSidArray);
2745 if (r->out.sids == NULL) {
2746 return NT_STATUS_NO_MEMORY;
2748 r->out.sids->count = r2.out.sids->count;
2749 r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_TranslatedSid,
2750 r->out.sids->count);
2751 if (r->out.sids->sids == NULL) {
2752 return NT_STATUS_NO_MEMORY;
2754 for (i=0;i<r->out.sids->count;i++) {
2755 r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type;
2756 r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid;
2757 r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index;
2766 static NTSTATUS lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2767 struct lsa_CREDRWRITE *r)
2769 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2776 static NTSTATUS lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2777 struct lsa_CREDRREAD *r)
2779 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2786 static NTSTATUS lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2787 struct lsa_CREDRENUMERATE *r)
2789 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2794 lsa_CREDRWRITEDOMAINCREDENTIALS
2796 static NTSTATUS lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2797 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2799 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2804 lsa_CREDRREADDOMAINCREDENTIALS
2806 static NTSTATUS lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2807 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2809 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2816 static NTSTATUS lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2817 struct lsa_CREDRDELETE *r)
2819 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2824 lsa_CREDRGETTARGETINFO
2826 static NTSTATUS lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2827 struct lsa_CREDRGETTARGETINFO *r)
2829 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2834 lsa_CREDRPROFILELOADED
2836 static NTSTATUS lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2837 struct lsa_CREDRPROFILELOADED *r)
2839 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2844 lsa_CREDRGETSESSIONTYPES
2846 static NTSTATUS lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2847 struct lsa_CREDRGETSESSIONTYPES *r)
2849 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2854 lsa_LSARREGISTERAUDITEVENT
2856 static NTSTATUS lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2857 struct lsa_LSARREGISTERAUDITEVENT *r)
2859 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2864 lsa_LSARGENAUDITEVENT
2866 static NTSTATUS lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2867 struct lsa_LSARGENAUDITEVENT *r)
2869 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2874 lsa_LSARUNREGISTERAUDITEVENT
2876 static NTSTATUS lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2877 struct lsa_LSARUNREGISTERAUDITEVENT *r)
2879 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2884 lsa_LSARQUERYFORESTTRUSTINFORMATION
2886 static NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2887 struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
2889 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2894 lsa_LSARSETFORESTTRUSTINFORMATION
2896 static NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2897 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2899 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2906 static NTSTATUS lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2907 struct lsa_CREDRRENAME *r)
2909 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2914 lsa_LSARLOOKUPNAMES4
2916 static NTSTATUS lsa_LSARLOOKUPNAMES4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2917 struct lsa_LSARLOOKUPNAMES4 *r)
2919 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2924 lsa_LSAROPENPOLICYSCE
2926 static NTSTATUS lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2927 struct lsa_LSAROPENPOLICYSCE *r)
2929 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2934 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
2936 static NTSTATUS lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2937 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2939 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2944 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
2946 static NTSTATUS lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2947 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2949 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2954 lsa_LSARADTREPORTSECURITYEVENT
2956 static NTSTATUS lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2957 struct lsa_LSARADTREPORTSECURITYEVENT *r)
2959 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2963 /* include the generated boilerplate */
2964 #include "librpc/gen_ndr/ndr_lsa_s.c"