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"
35 this type allows us to distinguish handle types
41 LSA_HANDLE_TRUSTED_DOMAIN
45 state associated with a lsa_OpenPolicy() operation
47 struct lsa_policy_state {
48 struct dcesrv_handle *handle;
49 struct ldb_context *sam_ldb;
50 struct sidmap_context *sidmap;
52 const char *domain_dn;
53 const char *builtin_dn;
54 const char *system_dn;
55 const char *domain_name;
56 struct dom_sid *domain_sid;
57 struct dom_sid *builtin_sid;
62 state associated with a lsa_OpenAccount() operation
64 struct lsa_account_state {
65 struct lsa_policy_state *policy;
67 struct dom_sid *account_sid;
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_context *sam_ldb;
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_ldb, 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_ldb, 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(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;
224 state = talloc(mem_ctx, struct lsa_policy_state);
226 return NT_STATUS_NO_MEMORY;
229 /* make sure the sam database is accessible */
230 state->sam_ldb = samdb_connect(state);
231 if (state->sam_ldb == NULL) {
232 return NT_STATUS_INVALID_SYSTEM_SERVICE;
235 state->sidmap = sidmap_open(state);
236 if (state->sidmap == NULL) {
237 return NT_STATUS_INVALID_SYSTEM_SERVICE;
240 /* work out the domain_dn - useful for so many calls its worth
242 state->domain_dn = talloc_reference(state,
243 samdb_search_string(state->sam_ldb, mem_ctx, NULL,
244 "dn", "(&(objectClass=domain)(!(objectclass=builtinDomain)))"));
245 if (!state->domain_dn) {
246 return NT_STATUS_NO_SUCH_DOMAIN;
249 /* work out the builtin_dn - useful for so many calls its worth
251 state->builtin_dn = talloc_reference(state,
252 samdb_search_string(state->sam_ldb, mem_ctx, NULL,
253 "dn", "objectClass=builtinDomain"));
254 if (!state->builtin_dn) {
255 return NT_STATUS_NO_SUCH_DOMAIN;
258 /* work out the system_dn - useful for so many calls its worth
260 state->system_dn = talloc_reference(state,
261 samdb_search_string(state->sam_ldb, mem_ctx, state->domain_dn,
262 "dn", "(&(objectClass=container)(cn=System))"));
263 if (!state->system_dn) {
264 return NT_STATUS_NO_SUCH_DOMAIN;
267 state->domain_sid = samdb_search_dom_sid(state->sam_ldb, state,
268 state->domain_dn, "objectSid",
269 "dn=%s", state->domain_dn);
270 if (!state->domain_sid) {
271 return NT_STATUS_NO_SUCH_DOMAIN;
274 state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
275 if (!state->builtin_sid) {
276 return NT_STATUS_NO_SUCH_DOMAIN;
279 state->domain_name = talloc_reference(state,
280 samdb_search_string(state->sam_ldb, mem_ctx,
281 state->domain_dn, "name",
282 "dn=%s", state->domain_dn));
283 if (!state->domain_name) {
284 return NT_STATUS_NO_SUCH_DOMAIN;
295 static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
296 struct lsa_OpenPolicy2 *r)
299 struct lsa_policy_state *state;
300 struct dcesrv_handle *handle;
302 ZERO_STRUCTP(r->out.handle);
304 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
305 if (!NT_STATUS_IS_OK(status)) {
309 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
311 return NT_STATUS_NO_MEMORY;
314 handle->data = talloc_steal(handle, state);
316 state->access_mask = r->in.access_mask;
317 state->handle = handle;
318 *r->out.handle = handle->wire_handle;
320 /* note that we have completely ignored the attr element of
321 the OpenPolicy. As far as I can tell, this is what w2k3
329 a wrapper around lsa_OpenPolicy2
331 static NTSTATUS lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
332 struct lsa_OpenPolicy *r)
334 struct lsa_OpenPolicy2 r2;
336 r2.in.system_name = NULL;
337 r2.in.attr = r->in.attr;
338 r2.in.access_mask = r->in.access_mask;
339 r2.out.handle = r->out.handle;
341 return lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
348 fill in the AccountDomain info
350 static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
351 struct lsa_DomainInfo *info)
353 const char * const attrs[] = { "objectSid", "name", NULL};
355 struct ldb_message **res;
357 ret = gendb_search_dn(state->sam_ldb, mem_ctx, state->domain_dn, &res, attrs);
359 return NT_STATUS_INTERNAL_DB_CORRUPTION;
362 info->name.string = samdb_result_string(res[0], "name", NULL);
363 info->sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
369 fill in the DNS domain info
371 static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
372 struct lsa_DnsDomainInfo *info)
374 const char * const attrs[] = { "name", "dnsDomain", "objectGUID", "objectSid", NULL };
376 struct ldb_message **res;
378 ret = gendb_search_dn(state->sam_ldb, mem_ctx, state->domain_dn, &res, attrs);
380 return NT_STATUS_INTERNAL_DB_CORRUPTION;
383 info->name.string = samdb_result_string(res[0], "name", NULL);
384 info->dns_domain.string = samdb_result_string(res[0], "dnsDomain", NULL);
385 info->dns_forest.string = samdb_result_string(res[0], "dnsDomain", NULL);
386 info->domain_guid = samdb_result_guid(res[0], "objectGUID");
387 info->sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
395 static NTSTATUS lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
396 struct lsa_QueryInfoPolicy2 *r)
398 struct lsa_policy_state *state;
399 struct dcesrv_handle *h;
403 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
407 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
409 return NT_STATUS_NO_MEMORY;
412 ZERO_STRUCTP(r->out.info);
414 switch (r->in.level) {
415 case LSA_POLICY_INFO_DOMAIN:
416 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
417 return lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
419 case LSA_POLICY_INFO_DNS:
420 return lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
423 return NT_STATUS_INVALID_INFO_CLASS;
429 static NTSTATUS lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
430 struct lsa_QueryInfoPolicy *r)
432 struct lsa_QueryInfoPolicy2 r2;
435 r2.in.handle = r->in.handle;
436 r2.in.level = r->in.level;
438 status = lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
440 r->out.info = r2.out.info;
448 static NTSTATUS lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
449 struct lsa_SetInfoPolicy *r)
451 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
458 static NTSTATUS lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
459 struct lsa_ClearAuditLog *r)
461 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
468 static NTSTATUS lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
469 struct lsa_CreateAccount *r)
471 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
478 static NTSTATUS lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
479 struct lsa_EnumAccounts *r)
481 struct dcesrv_handle *h;
482 struct lsa_policy_state *state;
484 struct ldb_message **res;
485 const char * const attrs[] = { "objectSid", NULL};
488 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
492 ret = gendb_search(state->sam_ldb, mem_ctx, state->builtin_dn, &res, attrs,
495 return NT_STATUS_NO_SUCH_USER;
498 if (*r->in.resume_handle >= ret) {
499 return NT_STATUS_NO_MORE_ENTRIES;
502 count = ret - *r->in.resume_handle;
503 if (count > r->in.num_entries) {
504 count = r->in.num_entries;
508 return NT_STATUS_NO_MORE_ENTRIES;
511 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
512 if (r->out.sids->sids == NULL) {
513 return NT_STATUS_NO_MEMORY;
516 for (i=0;i<count;i++) {
517 r->out.sids->sids[i].sid =
518 samdb_result_dom_sid(r->out.sids->sids,
519 res[i + *r->in.resume_handle],
521 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
524 r->out.sids->num_sids = count;
525 *r->out.resume_handle = count + *r->in.resume_handle;
533 lsa_CreateTrustedDomainEx2
535 static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
537 struct lsa_CreateTrustedDomainEx2 *r)
539 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
543 lsa_CreateTrustedDomainEx
545 static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
547 struct lsa_CreateTrustedDomainEx *r)
549 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
553 lsa_CreateTrustedDomain
555 static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
556 struct lsa_CreateTrustedDomain *r)
558 struct dcesrv_handle *policy_handle;
559 struct lsa_policy_state *policy_state;
560 struct lsa_trusted_domain_state *trusted_domain_state;
561 struct dcesrv_handle *handle;
562 struct ldb_message **msgs, *msg;
563 const char *attrs[] = {
569 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
570 ZERO_STRUCTP(r->out.trustdom_handle);
572 policy_state = policy_handle->data;
574 if (!r->in.info->name.string) {
575 return NT_STATUS_INVALID_PARAMETER;
577 name = r->in.info->name.string;
579 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
580 if (!trusted_domain_state) {
581 return NT_STATUS_NO_MEMORY;
583 trusted_domain_state->policy = policy_state;
585 msg = ldb_msg_new(mem_ctx);
587 return NT_STATUS_NO_MEMORY;
590 /* search for the trusted_domain record */
591 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
592 mem_ctx, policy_state->system_dn, &msgs, attrs,
593 "(&(cn=%s)(objectclass=trustedDomain))",
594 r->in.info->name.string);
596 return NT_STATUS_OBJECT_NAME_COLLISION;
599 if (ret < 0 || ret > 1) {
600 DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
601 return NT_STATUS_INTERNAL_DB_CORRUPTION;
604 msg->dn = talloc_asprintf(mem_ctx, "cn=%s,%s", r->in.info->name.string,
605 policy_state->system_dn);
607 return NT_STATUS_NO_MEMORY;
610 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "cn", name);
611 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
613 if (r->in.info->sid) {
614 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
616 return NT_STATUS_NO_MEMORY;
619 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
622 /* pull in all the template attributes. */
623 ret = samdb_copy_template(trusted_domain_state->policy->sam_ldb, mem_ctx, msg,
624 "(&(name=TemplateTrustedDomain)(objectclass=trustedDomainTemplate))");
626 DEBUG(0,("Failed to load TemplateTrustedDomain from samdb\n"));
627 return NT_STATUS_INTERNAL_DB_CORRUPTION;
630 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
632 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
634 /* create the trusted_domain */
635 ret = samdb_add(trusted_domain_state->policy->sam_ldb, mem_ctx, msg);
637 DEBUG(0,("Failed to create trusted_domain record %s\n", msg->dn));
638 return NT_STATUS_INTERNAL_DB_CORRUPTION;
641 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
643 return NT_STATUS_NO_MEMORY;
646 handle->data = talloc_steal(handle, trusted_domain_state);
648 trusted_domain_state->access_mask = r->in.access_mask;
649 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
651 *r->out.trustdom_handle = handle->wire_handle;
657 lsa_OpenTrustedDomain
659 static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
660 struct lsa_OpenTrustedDomain *r)
662 struct dcesrv_handle *policy_handle;
664 struct lsa_policy_state *policy_state;
665 struct lsa_trusted_domain_state *trusted_domain_state;
666 struct dcesrv_handle *handle;
667 struct ldb_message **msgs;
668 const char *attrs[] = {
672 const char *sid_string;
675 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
676 ZERO_STRUCTP(r->out.trustdom_handle);
677 policy_state = policy_handle->data;
679 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
680 if (!trusted_domain_state) {
681 return NT_STATUS_NO_MEMORY;
683 trusted_domain_state->policy = policy_state;
685 sid_string = dom_sid_string(mem_ctx, r->in.sid);
687 return NT_STATUS_NO_MEMORY;
690 /* search for the trusted_domain record */
691 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
692 mem_ctx, policy_state->system_dn, &msgs, attrs,
693 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
696 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
700 DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
701 return NT_STATUS_INTERNAL_DB_CORRUPTION;
704 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
706 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
708 return NT_STATUS_NO_MEMORY;
711 handle->data = talloc_steal(handle, trusted_domain_state);
713 trusted_domain_state->access_mask = r->in.access_mask;
714 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
716 *r->out.trustdom_handle = handle->wire_handle;
723 lsa_OpenTrustedDomainByName
725 static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
727 struct lsa_OpenTrustedDomainByName *r)
729 struct dcesrv_handle *policy_handle;
731 struct lsa_policy_state *policy_state;
732 struct lsa_trusted_domain_state *trusted_domain_state;
733 struct dcesrv_handle *handle;
734 struct ldb_message **msgs;
735 const char *attrs[] = {
741 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
742 ZERO_STRUCTP(r->out.trustdom_handle);
743 policy_state = policy_handle->data;
745 if (!r->in.name.string) {
746 return NT_STATUS_INVALID_PARAMETER;
749 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
750 if (!trusted_domain_state) {
751 return NT_STATUS_NO_MEMORY;
753 trusted_domain_state->policy = policy_state;
755 /* search for the trusted_domain record */
756 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
757 mem_ctx, policy_state->system_dn, &msgs, attrs,
758 "(&(flatname=%s)(objectclass=trustedDomain))",
761 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
765 DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
766 return NT_STATUS_INTERNAL_DB_CORRUPTION;
769 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
771 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
773 return NT_STATUS_NO_MEMORY;
776 handle->data = talloc_steal(handle, trusted_domain_state);
778 trusted_domain_state->access_mask = r->in.access_mask;
779 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
781 *r->out.trustdom_handle = handle->wire_handle;
788 lsa_QueryTrustedDomainInfoBySid
790 static NTSTATUS lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
791 struct lsa_QueryTrustedDomainInfoBySid *r)
793 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
798 lsa_SetTrustDomainInfo
800 static NTSTATUS lsa_SetTrustDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
801 struct lsa_SetTrustDomainInfo *r)
803 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
808 lsa_DeleteTrustDomain
810 static NTSTATUS lsa_DeleteTrustDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
811 struct lsa_DeleteTrustDomain *r)
813 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
818 lsa_QueryTrustedDomainInfo
820 static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
821 struct lsa_QueryTrustedDomainInfo *r)
823 struct dcesrv_handle *h;
824 struct lsa_trusted_domain_state *trusted_domain_state;
825 struct ldb_message *msg;
827 struct ldb_message **res;
828 const char *attrs[] = {
832 "securityIdentifier",
836 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
838 trusted_domain_state = h->data;
840 /* pull all the user attributes */
841 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
842 trusted_domain_state->trusted_domain_dn, &res, attrs);
844 return NT_STATUS_INTERNAL_DB_CORRUPTION;
848 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
850 return NT_STATUS_NO_MEMORY;
852 switch (r->in.level) {
853 case LSA_TRUSTED_DOMAIN_INFO_NAME:
854 r->out.info->name.netbios_name.string
855 = samdb_result_string(msg, "flatname", NULL);
857 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
858 r->out.info->posix_offset.posix_offset
859 = samdb_result_uint(msg, "posixOffset", 0);
862 /* oops, we don't want to return the info after all */
863 talloc_free(r->out.info);
865 return NT_STATUS_INVALID_INFO_CLASS;
873 lsa_SetInformationTrustedDomain
875 static NTSTATUS lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
876 struct lsa_SetInformationTrustedDomain *r)
878 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
883 lsa_QueryTrustedDomainInfoByName
885 static NTSTATUS lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
887 struct lsa_QueryTrustedDomainInfoByName *r)
889 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
893 lsa_SetTrustedDomainInfoByName
895 static NTSTATUS lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
897 struct lsa_SetTrustedDomainInfoByName *r)
899 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
903 lsa_EnumTrustedDomainsEx
905 static NTSTATUS lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call,
907 struct lsa_EnumTrustedDomainsEx *r)
909 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
913 lsa_CloseTrustedDomainEx
915 static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
917 struct lsa_CloseTrustedDomainEx *r)
919 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
924 comparison function for sorting lsa_DomainInformation array
926 static int compare_DomainInformation(struct lsa_DomainInformation *e1, struct lsa_DomainInformation *e2)
928 return strcasecmp(e1->name.string, e2->name.string);
934 static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
935 struct lsa_EnumTrustDom *r)
937 struct dcesrv_handle *policy_handle;
938 struct lsa_DomainInformation *entries;
939 struct lsa_policy_state *policy_state;
940 struct ldb_message **domains;
941 const char *attrs[] = {
943 "securityIdentifier",
950 *r->out.resume_handle = 0;
952 r->out.domains->domains = NULL;
953 r->out.domains->count = 0;
955 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
957 policy_state = policy_handle->data;
959 /* search for all users in this domain. This could possibly be cached and
960 resumed based on resume_key */
961 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
962 "objectclass=trustedDomain");
964 return NT_STATUS_INTERNAL_DB_CORRUPTION;
966 if (count == 0 || r->in.max_size == 0) {
970 /* convert to lsa_DomainInformation format */
971 entries = talloc_array(mem_ctx, struct lsa_DomainInformation, count);
973 return NT_STATUS_NO_MEMORY;
975 for (i=0;i<count;i++) {
976 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
977 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
980 /* sort the results by name */
981 qsort(entries, count, sizeof(struct lsa_DomainInformation),
982 (comparison_fn_t)compare_DomainInformation);
984 if (*r->in.resume_handle >= count) {
985 *r->out.resume_handle = -1;
987 return NT_STATUS_NO_MORE_ENTRIES;
990 /* return the rest, limit by max_size. Note that we
991 use the w2k3 element size value of 60 */
992 r->out.domains->count = count - *r->in.resume_handle;
993 r->out.domains->count = MIN(r->out.domains->count,
994 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
996 r->out.domains->domains = entries + *r->in.resume_handle;
997 r->out.domains->count = r->out.domains->count;
999 if (r->out.domains->count < count - *r->in.resume_handle) {
1000 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1001 return STATUS_MORE_ENTRIES;
1004 return NT_STATUS_OK;
1009 return the authority name and authority sid, given a sid
1011 static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
1012 TALLOC_CTX *mem_ctx, struct dom_sid *sid,
1013 const char **authority_name,
1014 struct dom_sid **authority_sid)
1016 if (dom_sid_in_domain(state->domain_sid, sid)) {
1017 *authority_name = state->domain_name;
1018 *authority_sid = state->domain_sid;
1019 return NT_STATUS_OK;
1022 if (dom_sid_in_domain(state->builtin_sid, sid)) {
1023 *authority_name = "BUILTIN";
1024 *authority_sid = state->builtin_sid;
1025 return NT_STATUS_OK;
1028 *authority_sid = dom_sid_dup(mem_ctx, sid);
1029 if (*authority_sid == NULL) {
1030 return NT_STATUS_NO_MEMORY;
1032 (*authority_sid)->num_auths = 0;
1033 *authority_name = dom_sid_string(mem_ctx, *authority_sid);
1034 if (*authority_name == NULL) {
1035 return NT_STATUS_NO_MEMORY;
1038 return NT_STATUS_OK;
1042 add to the lsa_RefDomainList for LookupSids and LookupNames
1044 static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1045 struct dom_sid *sid,
1046 struct lsa_RefDomainList *domains,
1047 uint32_t *sid_index)
1050 const char *authority_name;
1051 struct dom_sid *authority_sid;
1054 /* work out the authority name */
1055 status = lsa_authority_name(state, mem_ctx, sid,
1056 &authority_name, &authority_sid);
1057 if (!NT_STATUS_IS_OK(status)) {
1061 /* see if we've already done this authority name */
1062 for (i=0;i<domains->count;i++) {
1063 if (strcmp(authority_name, domains->domains[i].name.string) == 0) {
1065 return NT_STATUS_OK;
1069 domains->domains = talloc_realloc(domains,
1071 struct lsa_TrustInformation,
1073 if (domains->domains == NULL) {
1074 return NT_STATUS_NO_MEMORY;
1076 domains->domains[i].name.string = authority_name;
1077 domains->domains[i].sid = authority_sid;
1081 return NT_STATUS_OK;
1085 lookup a name for 1 SID
1087 static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1088 struct dom_sid *sid, const char *sid_str,
1089 const char **name, uint32_t *atype)
1092 struct ldb_message **res;
1093 const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "name", NULL};
1096 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1097 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
1099 *name = ldb_msg_find_string(res[0], "sAMAccountName", NULL);
1101 *name = ldb_msg_find_string(res[0], "name", NULL);
1103 *name = talloc_strdup(mem_ctx, sid_str);
1104 NTSTATUS_TALLOC_CHECK(*name);
1108 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
1110 return NT_STATUS_OK;
1113 status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype);
1122 static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
1123 TALLOC_CTX *mem_ctx,
1124 struct lsa_LookupSids3 *r)
1126 struct lsa_policy_state *state;
1128 NTSTATUS status = NT_STATUS_OK;
1130 r->out.domains = NULL;
1132 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
1133 if (!NT_STATUS_IS_OK(status)) {
1137 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
1138 if (r->out.domains == NULL) {
1139 return NT_STATUS_NO_MEMORY;
1142 r->out.names = talloc_zero(mem_ctx, struct lsa_TransNameArray2);
1143 if (r->out.names == NULL) {
1144 return NT_STATUS_NO_MEMORY;
1149 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName2,
1150 r->in.sids->num_sids);
1151 if (r->out.names->names == NULL) {
1152 return NT_STATUS_NO_MEMORY;
1155 for (i=0;i<r->in.sids->num_sids;i++) {
1156 struct dom_sid *sid = r->in.sids->sids[i].sid;
1157 char *sid_str = dom_sid_string(mem_ctx, sid);
1159 uint32_t atype, rtype, sid_index;
1162 r->out.names->count++;
1165 r->out.names->names[i].sid_type = SID_NAME_UNKNOWN;
1166 r->out.names->names[i].name.string = sid_str;
1167 r->out.names->names[i].sid_index = 0xFFFFFFFF;
1168 r->out.names->names[i].unknown = 0;
1170 if (sid_str == NULL) {
1171 r->out.names->names[i].name.string = "(SIDERROR)";
1172 status = STATUS_SOME_UNMAPPED;
1176 /* work out the authority name */
1177 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
1178 if (!NT_STATUS_IS_OK(status2)) {
1182 status2 = lsa_lookup_sid(state, mem_ctx, sid, sid_str,
1184 if (!NT_STATUS_IS_OK(status2)) {
1185 status = STATUS_SOME_UNMAPPED;
1189 rtype = samdb_atype_map(atype);
1190 if (rtype == SID_NAME_UNKNOWN) {
1191 status = STATUS_SOME_UNMAPPED;
1195 r->out.names->names[i].sid_type = rtype;
1196 r->out.names->names[i].name.string = name;
1197 r->out.names->names[i].sid_index = sid_index;
1198 r->out.names->names[i].unknown = 0;
1208 static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
1209 TALLOC_CTX *mem_ctx,
1210 struct lsa_LookupSids2 *r)
1212 struct lsa_LookupSids3 r3;
1215 r3.in.sids = r->in.sids;
1216 r3.in.names = r->in.names;
1217 r3.in.level = r->in.level;
1218 r3.in.count = r->in.count;
1219 r3.in.unknown1 = r->in.unknown1;
1220 r3.in.unknown2 = r->in.unknown2;
1221 r3.out.count = r->out.count;
1222 r3.out.names = r->out.names;
1224 status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
1225 if (dce_call->fault_code != 0) {
1229 r->out.domains = r3.out.domains;
1230 r->out.names = r3.out.names;
1231 r->out.count = r3.out.count;
1240 static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1241 struct lsa_LookupSids *r)
1243 struct lsa_LookupSids3 r3;
1247 r3.in.sids = r->in.sids;
1249 r3.in.level = r->in.level;
1250 r3.in.count = r->in.count;
1253 r3.out.count = r->out.count;
1255 status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
1256 if (dce_call->fault_code != 0) {
1260 r->out.domains = r3.out.domains;
1261 r->out.names = talloc(mem_ctx, struct lsa_TransNameArray);
1262 if (r->out.names == NULL) {
1263 return NT_STATUS_NO_MEMORY;
1265 r->out.names->count = r3.out.names->count;
1266 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName,
1267 r->out.names->count);
1268 if (r->out.names->names == NULL) {
1269 return NT_STATUS_NO_MEMORY;
1271 for (i=0;i<r->out.names->count;i++) {
1272 r->out.names->names[i].sid_type = r3.out.names->names[i].sid_type;
1273 r->out.names->names[i].name.string = r3.out.names->names[i].name.string;
1274 r->out.names->names[i].sid_index = r3.out.names->names[i].sid_index;
1284 static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1285 struct lsa_OpenAccount *r)
1287 struct dcesrv_handle *h, *ah;
1288 struct lsa_policy_state *state;
1289 struct lsa_account_state *astate;
1291 ZERO_STRUCTP(r->out.acct_handle);
1293 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1297 astate = talloc(dce_call->conn, struct lsa_account_state);
1298 if (astate == NULL) {
1299 return NT_STATUS_NO_MEMORY;
1302 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1303 if (astate->account_sid == NULL) {
1304 talloc_free(astate);
1305 return NT_STATUS_NO_MEMORY;
1308 /* check it really exists */
1309 astate->account_dn =
1310 samdb_search_string(state->sam_ldb, astate,
1312 "(&(objectSid=%s)(objectClass=group))",
1313 ldap_encode_ndr_dom_sid(mem_ctx,
1314 astate->account_sid));
1315 if (astate->account_dn == NULL) {
1316 talloc_free(astate);
1317 return NT_STATUS_NO_SUCH_USER;
1320 astate->policy = talloc_reference(astate, state);
1321 astate->access_mask = r->in.access_mask;
1323 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1325 talloc_free(astate);
1326 return NT_STATUS_NO_MEMORY;
1329 ah->data = talloc_steal(ah, astate);
1331 *r->out.acct_handle = ah->wire_handle;
1333 return NT_STATUS_OK;
1338 lsa_EnumPrivsAccount
1340 static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1341 TALLOC_CTX *mem_ctx,
1342 struct lsa_EnumPrivsAccount *r)
1344 struct dcesrv_handle *h;
1345 struct lsa_account_state *astate;
1347 struct ldb_message **res;
1348 const char * const attrs[] = { "privilege", NULL};
1349 struct ldb_message_element *el;
1351 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1355 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1356 r->out.privs->count = 0;
1357 r->out.privs->unknown = 0;
1358 r->out.privs->set = NULL;
1360 ret = gendb_search_dn(astate->policy->sam_ldb, mem_ctx,
1361 astate->account_dn, &res, attrs);
1363 return NT_STATUS_OK;
1366 el = ldb_msg_find_element(res[0], "privilege");
1367 if (el == NULL || el->num_values == 0) {
1368 return NT_STATUS_OK;
1371 r->out.privs->set = talloc_array(r->out.privs,
1372 struct lsa_LUIDAttribute, el->num_values);
1373 if (r->out.privs->set == NULL) {
1374 return NT_STATUS_NO_MEMORY;
1377 for (i=0;i<el->num_values;i++) {
1378 int id = sec_privilege_id((const char *)el->values[i].data);
1380 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1382 r->out.privs->set[i].attribute = 0;
1383 r->out.privs->set[i].luid.low = id;
1384 r->out.privs->set[i].luid.high = 0;
1387 r->out.privs->count = el->num_values;
1389 return NT_STATUS_OK;
1393 lsa_EnumAccountRights
1395 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1396 TALLOC_CTX *mem_ctx,
1397 struct lsa_EnumAccountRights *r)
1399 struct dcesrv_handle *h;
1400 struct lsa_policy_state *state;
1402 struct ldb_message **res;
1403 const char * const attrs[] = { "privilege", NULL};
1405 struct ldb_message_element *el;
1407 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1411 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1412 if (sidstr == NULL) {
1413 return NT_STATUS_NO_MEMORY;
1416 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1417 "objectSid=%s", sidstr);
1419 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1422 el = ldb_msg_find_element(res[0], "privilege");
1423 if (el == NULL || el->num_values == 0) {
1424 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1427 r->out.rights->count = el->num_values;
1428 r->out.rights->names = talloc_array(r->out.rights,
1429 struct lsa_String, r->out.rights->count);
1430 if (r->out.rights->names == NULL) {
1431 return NT_STATUS_NO_MEMORY;
1434 for (i=0;i<el->num_values;i++) {
1435 r->out.rights->names[i].string = (const char *)el->values[i].data;
1438 return NT_STATUS_OK;
1444 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1446 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1447 TALLOC_CTX *mem_ctx,
1448 struct lsa_policy_state *state,
1450 struct dom_sid *sid,
1451 const struct lsa_RightSet *rights)
1454 struct ldb_message *msg;
1455 struct ldb_message_element el;
1458 struct lsa_EnumAccountRights r2;
1460 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1461 if (sidstr == NULL) {
1462 return NT_STATUS_NO_MEMORY;
1465 msg = ldb_msg_new(mem_ctx);
1467 return NT_STATUS_NO_MEMORY;
1470 dn = samdb_search_string(state->sam_ldb, mem_ctx, NULL, "dn",
1471 "objectSid=%s", sidstr);
1473 return NT_STATUS_NO_SUCH_USER;
1476 msg->dn = talloc_strdup(mem_ctx, dn);
1477 if (msg->dn == NULL) {
1478 return NT_STATUS_NO_MEMORY;
1481 if (ldb_msg_add_empty(state->sam_ldb, msg, "privilege", ldb_flag)) {
1482 return NT_STATUS_NO_MEMORY;
1485 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1488 r2.in.handle = &state->handle->wire_handle;
1490 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1492 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1493 if (!NT_STATUS_IS_OK(status)) {
1494 ZERO_STRUCTP(r2.out.rights);
1499 el.values = talloc_array(mem_ctx, struct ldb_val, rights->count);
1500 if (el.values == NULL) {
1501 return NT_STATUS_NO_MEMORY;
1503 for (i=0;i<rights->count;i++) {
1504 if (sec_privilege_id(rights->names[i].string) == -1) {
1505 return NT_STATUS_NO_SUCH_PRIVILEGE;
1508 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1510 for (j=0;j<r2.out.rights->count;j++) {
1511 if (StrCaseCmp(r2.out.rights->names[j].string,
1512 rights->names[i].string) == 0) {
1516 if (j != r2.out.rights->count) continue;
1520 el.values[el.num_values].length = strlen(rights->names[i].string);
1521 el.values[el.num_values].data = (uint8_t *)talloc_strdup(mem_ctx, rights->names[i].string);
1522 if (el.values[el.num_values].data == NULL) {
1523 return NT_STATUS_NO_MEMORY;
1528 if (el.num_values == 0) {
1529 return NT_STATUS_OK;
1532 ret = samdb_modify(state->sam_ldb, mem_ctx, msg);
1534 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1535 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1537 return NT_STATUS_UNEXPECTED_IO_ERROR;
1540 return NT_STATUS_OK;
1544 lsa_AddPrivilegesToAccount
1546 static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1547 struct lsa_AddPrivilegesToAccount *r)
1549 struct lsa_RightSet rights;
1550 struct dcesrv_handle *h;
1551 struct lsa_account_state *astate;
1554 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1558 rights.count = r->in.privs->count;
1559 rights.names = talloc_array(mem_ctx, struct lsa_String, rights.count);
1560 if (rights.names == NULL) {
1561 return NT_STATUS_NO_MEMORY;
1563 for (i=0;i<rights.count;i++) {
1564 int id = r->in.privs->set[i].luid.low;
1565 if (r->in.privs->set[i].luid.high) {
1566 return NT_STATUS_NO_SUCH_PRIVILEGE;
1568 rights.names[i].string = sec_privilege_name(id);
1569 if (rights.names[i].string == NULL) {
1570 return NT_STATUS_NO_SUCH_PRIVILEGE;
1574 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1575 LDB_FLAG_MOD_ADD, astate->account_sid,
1581 lsa_RemovePrivilegesFromAccount
1583 static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1584 struct lsa_RemovePrivilegesFromAccount *r)
1586 struct lsa_RightSet *rights;
1587 struct dcesrv_handle *h;
1588 struct lsa_account_state *astate;
1591 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1595 rights = talloc(mem_ctx, struct lsa_RightSet);
1597 if (r->in.remove_all == 1 &&
1598 r->in.privs == NULL) {
1599 struct lsa_EnumAccountRights r2;
1602 r2.in.handle = &astate->policy->handle->wire_handle;
1603 r2.in.sid = astate->account_sid;
1604 r2.out.rights = rights;
1606 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1607 if (!NT_STATUS_IS_OK(status)) {
1611 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1612 LDB_FLAG_MOD_DELETE, astate->account_sid,
1616 if (r->in.remove_all != 0) {
1617 return NT_STATUS_INVALID_PARAMETER;
1620 rights->count = r->in.privs->count;
1621 rights->names = talloc_array(mem_ctx, struct lsa_String, rights->count);
1622 if (rights->names == NULL) {
1623 return NT_STATUS_NO_MEMORY;
1625 for (i=0;i<rights->count;i++) {
1626 int id = r->in.privs->set[i].luid.low;
1627 if (r->in.privs->set[i].luid.high) {
1628 return NT_STATUS_NO_SUCH_PRIVILEGE;
1630 rights->names[i].string = sec_privilege_name(id);
1631 if (rights->names[i].string == NULL) {
1632 return NT_STATUS_NO_SUCH_PRIVILEGE;
1636 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1637 LDB_FLAG_MOD_DELETE, astate->account_sid,
1643 lsa_GetQuotasForAccount
1645 static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1646 struct lsa_GetQuotasForAccount *r)
1648 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1653 lsa_SetQuotasForAccount
1655 static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1656 struct lsa_SetQuotasForAccount *r)
1658 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1663 lsa_GetSystemAccessAccount
1665 static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1666 struct lsa_GetSystemAccessAccount *r)
1668 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1673 lsa_SetSystemAccessAccount
1675 static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1676 struct lsa_SetSystemAccessAccount *r)
1678 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1685 static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1686 struct lsa_CreateSecret *r)
1688 struct dcesrv_handle *policy_handle;
1689 struct lsa_policy_state *policy_state;
1690 struct lsa_secret_state *secret_state;
1691 struct dcesrv_handle *handle;
1692 struct ldb_message **msgs, *msg;
1693 const char *attrs[] = {
1701 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1702 ZERO_STRUCTP(r->out.sec_handle);
1704 policy_state = policy_handle->data;
1706 if (!r->in.name.string) {
1707 return NT_STATUS_INVALID_PARAMETER;
1710 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1711 if (!secret_state) {
1712 return NT_STATUS_NO_MEMORY;
1714 secret_state->policy = policy_state;
1716 msg = ldb_msg_new(mem_ctx);
1718 return NT_STATUS_NO_MEMORY;
1721 if (strncmp("G$", r->in.name.string, 2) == 0) {
1723 name = &r->in.name.string[2];
1724 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1725 secret_state->global = True;
1727 if (strlen(name) < 1) {
1728 return NT_STATUS_INVALID_PARAMETER;
1731 name2 = talloc_asprintf(mem_ctx, "%s Secret", name);
1732 /* search for the secret record */
1733 ret = gendb_search(secret_state->sam_ldb,
1734 mem_ctx, policy_state->system_dn, &msgs, attrs,
1735 "(&(cn=%s)(objectclass=secret))",
1738 return NT_STATUS_OBJECT_NAME_COLLISION;
1741 if (ret < 0 || ret > 1) {
1742 DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
1743 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1746 msg->dn = talloc_asprintf(mem_ctx, "cn=%s,%s", name2, policy_state->system_dn);
1747 if (!name2 || !msg->dn) {
1748 return NT_STATUS_NO_MEMORY;
1751 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
1754 secret_state->global = False;
1756 name = r->in.name.string;
1757 if (strlen(name) < 1) {
1758 return NT_STATUS_INVALID_PARAMETER;
1761 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1762 /* search for the secret record */
1763 ret = gendb_search(secret_state->sam_ldb,
1764 mem_ctx, "cn=LSA Secrets", &msgs, attrs,
1765 "(&(cn=%s)(objectclass=secret))",
1768 return NT_STATUS_OBJECT_NAME_COLLISION;
1771 if (ret < 0 || ret > 1) {
1772 DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
1773 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1776 msg->dn = talloc_asprintf(mem_ctx, "cn=%s,cn=LSA Secrets", name);
1777 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
1780 /* pull in all the template attributes. Note this is always from the global samdb */
1781 ret = samdb_copy_template(secret_state->policy->sam_ldb, mem_ctx, msg,
1782 "(&(name=TemplateSecret)(objectclass=secretTemplate))");
1784 DEBUG(0,("Failed to load TemplateSecret from samdb\n"));
1785 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1788 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
1790 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1792 /* create the secret */
1793 ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
1795 DEBUG(0,("Failed to create secret record %s\n", msg->dn));
1796 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1799 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1801 return NT_STATUS_NO_MEMORY;
1804 handle->data = talloc_steal(handle, secret_state);
1806 secret_state->access_mask = r->in.access_mask;
1807 secret_state->policy = talloc_reference(secret_state, policy_state);
1809 *r->out.sec_handle = handle->wire_handle;
1811 return NT_STATUS_OK;
1818 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1819 struct lsa_OpenSecret *r)
1821 struct dcesrv_handle *policy_handle;
1823 struct lsa_policy_state *policy_state;
1824 struct lsa_secret_state *secret_state;
1825 struct dcesrv_handle *handle;
1826 struct ldb_message **msgs;
1827 const char *attrs[] = {
1835 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1836 ZERO_STRUCTP(r->out.sec_handle);
1837 policy_state = policy_handle->data;
1839 if (!r->in.name.string) {
1840 return NT_STATUS_INVALID_PARAMETER;
1843 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1844 if (!secret_state) {
1845 return NT_STATUS_NO_MEMORY;
1847 secret_state->policy = policy_state;
1849 if (strncmp("G$", r->in.name.string, 2) == 0) {
1850 name = &r->in.name.string[2];
1851 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1852 secret_state->global = True;
1854 if (strlen(name) < 1) {
1855 return NT_STATUS_INVALID_PARAMETER;
1858 /* search for the secret record */
1859 ret = gendb_search(secret_state->sam_ldb,
1860 mem_ctx, policy_state->system_dn, &msgs, attrs,
1861 "(&(cn=%s Secret)(objectclass=secret))",
1864 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1868 DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
1869 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1873 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1875 secret_state->global = False;
1876 name = r->in.name.string;
1877 if (strlen(name) < 1) {
1878 return NT_STATUS_INVALID_PARAMETER;
1881 /* search for the secret record */
1882 ret = gendb_search(secret_state->sam_ldb,
1883 mem_ctx, "cn=LSA Secrets", &msgs, attrs,
1884 "(&(cn=%s)(objectclass=secret))",
1887 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1891 DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
1892 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1896 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1898 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1900 return NT_STATUS_NO_MEMORY;
1903 handle->data = talloc_steal(handle, secret_state);
1905 secret_state->access_mask = r->in.access_mask;
1906 secret_state->policy = talloc_reference(secret_state, policy_state);
1908 *r->out.sec_handle = handle->wire_handle;
1910 return NT_STATUS_OK;
1917 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1918 struct lsa_SetSecret *r)
1921 struct dcesrv_handle *h;
1922 struct lsa_secret_state *secret_state;
1923 struct ldb_message *msg;
1924 DATA_BLOB session_key;
1925 DATA_BLOB crypt_secret, secret;
1928 NTSTATUS status = NT_STATUS_OK;
1930 struct timeval now = timeval_current();
1931 NTTIME nt_now = timeval_to_nttime(&now);
1933 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
1935 secret_state = h->data;
1937 msg = ldb_msg_new(mem_ctx);
1939 return NT_STATUS_NO_MEMORY;
1942 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
1944 return NT_STATUS_NO_MEMORY;
1946 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
1947 if (!NT_STATUS_IS_OK(status)) {
1951 if (r->in.old_val) {
1953 crypt_secret.data = r->in.old_val->data;
1954 crypt_secret.length = r->in.old_val->size;
1956 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1957 if (!NT_STATUS_IS_OK(status)) {
1961 val.data = secret.data;
1962 val.length = secret.length;
1965 if (samdb_msg_add_value(secret_state->sam_ldb,
1966 mem_ctx, msg, "priorSecret", &val) != 0) {
1967 return NT_STATUS_NO_MEMORY;
1970 /* set old value mtime */
1971 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1972 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
1973 return NT_STATUS_NO_MEMORY;
1976 if (!r->in.new_val) {
1977 /* This behaviour varies depending of if this is a local, or a global secret... */
1978 if (secret_state->global) {
1979 /* set old 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 (samdb_msg_add_delete(secret_state->sam_ldb,
1986 mem_ctx, msg, "secret")) {
1987 return NT_STATUS_NO_MEMORY;
1989 if (samdb_msg_add_delete(secret_state->sam_ldb,
1990 mem_ctx, msg, "lastSetTime")) {
1991 return NT_STATUS_NO_MEMORY;
1997 if (r->in.new_val) {
1999 crypt_secret.data = r->in.new_val->data;
2000 crypt_secret.length = r->in.new_val->size;
2002 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2003 if (!NT_STATUS_IS_OK(status)) {
2007 val.data = secret.data;
2008 val.length = secret.length;
2011 if (samdb_msg_add_value(secret_state->sam_ldb,
2012 mem_ctx, msg, "secret", &val) != 0) {
2013 return NT_STATUS_NO_MEMORY;
2016 /* set new value mtime */
2017 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2018 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2019 return NT_STATUS_NO_MEMORY;
2022 /* If the old value is not set, then migrate the
2023 * current value to the old value */
2024 if (!r->in.old_val) {
2025 const struct ldb_val *new_val;
2026 NTTIME last_set_time;
2027 struct ldb_message **res;
2028 const char *attrs[] = {
2034 /* search for the secret record */
2035 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2036 secret_state->secret_dn, &res, attrs);
2038 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2042 DEBUG(0,("Found %d records matching dn=%s\n", ret, secret_state->secret_dn));
2043 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2046 new_val = ldb_msg_find_ldb_val(res[0], "secret");
2047 last_set_time = ldb_msg_find_uint64(res[0], "lastSetTime", 0);
2051 if (samdb_msg_add_value(secret_state->sam_ldb,
2052 mem_ctx, msg, "priorSecret",
2054 return NT_STATUS_NO_MEMORY;
2058 /* set new value mtime */
2059 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2060 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2061 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2062 return NT_STATUS_NO_MEMORY;
2068 /* modify the samdb record */
2069 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2071 /* we really need samdb.c to return NTSTATUS */
2072 return NT_STATUS_UNSUCCESSFUL;
2075 return NT_STATUS_OK;
2082 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2083 struct lsa_QuerySecret *r)
2085 struct dcesrv_handle *h;
2086 struct lsa_secret_state *secret_state;
2087 struct ldb_message *msg;
2088 DATA_BLOB session_key;
2089 DATA_BLOB crypt_secret, secret;
2091 struct ldb_message **res;
2092 const char *attrs[] = {
2102 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2104 secret_state = h->data;
2106 /* pull all the user attributes */
2107 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2108 secret_state->secret_dn, &res, attrs);
2110 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2114 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2115 if (!NT_STATUS_IS_OK(nt_status)) {
2119 if (r->in.old_val) {
2120 const struct ldb_val *prior_val;
2121 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2122 if (!r->out.old_val) {
2123 return NT_STATUS_NO_MEMORY;
2126 prior_val = ldb_msg_find_ldb_val(res[0], "priorSecret");
2128 if (prior_val && prior_val->length) {
2129 secret.data = prior_val->data;
2130 secret.length = prior_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.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2137 if (!r->out.old_val->buf) {
2138 return NT_STATUS_NO_MEMORY;
2140 r->out.old_val->buf->size = crypt_secret.length;
2141 r->out.old_val->buf->length = crypt_secret.length;
2142 r->out.old_val->buf->data = crypt_secret.data;
2146 if (r->in.old_mtime) {
2147 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2148 if (!r->out.old_mtime) {
2149 return NT_STATUS_NO_MEMORY;
2151 *r->out.old_mtime = ldb_msg_find_uint64(res[0], "priorSetTime", 0);
2154 if (r->in.new_val) {
2155 const struct ldb_val *new_val;
2156 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2157 if (!r->out.new_val) {
2158 return NT_STATUS_NO_MEMORY;
2162 new_val = ldb_msg_find_ldb_val(res[0], "secret");
2164 if (new_val && new_val->length) {
2165 secret.data = new_val->data;
2166 secret.length = new_val->length;
2168 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2169 if (!crypt_secret.length) {
2170 return NT_STATUS_NO_MEMORY;
2172 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2173 if (!r->out.new_val->buf) {
2174 return NT_STATUS_NO_MEMORY;
2176 r->out.new_val->buf->length = crypt_secret.length;
2177 r->out.new_val->buf->size = crypt_secret.length;
2178 r->out.new_val->buf->data = crypt_secret.data;
2182 if (r->in.new_mtime) {
2183 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2184 if (!r->out.new_mtime) {
2185 return NT_STATUS_NO_MEMORY;
2187 *r->out.new_mtime = ldb_msg_find_uint64(res[0], "lastSetTime", 0);
2190 return NT_STATUS_OK;
2197 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2198 TALLOC_CTX *mem_ctx,
2199 struct lsa_LookupPrivValue *r)
2201 struct dcesrv_handle *h;
2202 struct lsa_policy_state *state;
2205 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2209 id = sec_privilege_id(r->in.name->string);
2211 return NT_STATUS_NO_SUCH_PRIVILEGE;
2214 r->out.luid->low = id;
2215 r->out.luid->high = 0;
2217 return NT_STATUS_OK;
2224 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2225 TALLOC_CTX *mem_ctx,
2226 struct lsa_LookupPrivName *r)
2228 struct dcesrv_handle *h;
2229 struct lsa_policy_state *state;
2230 const char *privname;
2232 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2236 if (r->in.luid->high != 0) {
2237 return NT_STATUS_NO_SUCH_PRIVILEGE;
2240 privname = sec_privilege_name(r->in.luid->low);
2241 if (privname == NULL) {
2242 return NT_STATUS_NO_SUCH_PRIVILEGE;
2245 r->out.name = talloc(mem_ctx, struct lsa_String);
2246 if (r->out.name == NULL) {
2247 return NT_STATUS_NO_MEMORY;
2249 r->out.name->string = privname;
2251 return NT_STATUS_OK;
2256 lsa_LookupPrivDisplayName
2258 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2259 TALLOC_CTX *mem_ctx,
2260 struct lsa_LookupPrivDisplayName *r)
2262 struct dcesrv_handle *h;
2263 struct lsa_policy_state *state;
2266 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2270 id = sec_privilege_id(r->in.name->string);
2272 return NT_STATUS_NO_SUCH_PRIVILEGE;
2275 r->out.disp_name = talloc(mem_ctx, struct lsa_String);
2276 if (r->out.disp_name == NULL) {
2277 return NT_STATUS_NO_MEMORY;
2280 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2281 if (r->out.disp_name->string == NULL) {
2282 return NT_STATUS_INTERNAL_ERROR;
2285 return NT_STATUS_OK;
2292 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2293 struct lsa_DeleteObject *r)
2295 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2300 lsa_EnumAccountsWithUserRight
2302 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2303 TALLOC_CTX *mem_ctx,
2304 struct lsa_EnumAccountsWithUserRight *r)
2306 struct dcesrv_handle *h;
2307 struct lsa_policy_state *state;
2309 struct ldb_message **res;
2310 const char * const attrs[] = { "objectSid", NULL};
2311 const char *privname;
2313 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2317 if (r->in.name == NULL) {
2318 return NT_STATUS_NO_SUCH_PRIVILEGE;
2321 privname = r->in.name->string;
2322 if (sec_privilege_id(privname) == -1) {
2323 return NT_STATUS_NO_SUCH_PRIVILEGE;
2326 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2327 "privilege=%s", privname);
2329 return NT_STATUS_NO_SUCH_USER;
2332 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2333 if (r->out.sids->sids == NULL) {
2334 return NT_STATUS_NO_MEMORY;
2336 for (i=0;i<ret;i++) {
2337 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2338 res[i], "objectSid");
2339 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2341 r->out.sids->num_sids = ret;
2343 return NT_STATUS_OK;
2348 lsa_AddAccountRights
2350 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2351 TALLOC_CTX *mem_ctx,
2352 struct lsa_AddAccountRights *r)
2354 struct dcesrv_handle *h;
2355 struct lsa_policy_state *state;
2357 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2361 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2363 r->in.sid, r->in.rights);
2368 lsa_RemoveAccountRights
2370 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2371 TALLOC_CTX *mem_ctx,
2372 struct lsa_RemoveAccountRights *r)
2374 struct dcesrv_handle *h;
2375 struct lsa_policy_state *state;
2377 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2381 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2382 LDB_FLAG_MOD_DELETE,
2383 r->in.sid, r->in.rights);
2388 lsa_StorePrivateData
2390 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2391 struct lsa_StorePrivateData *r)
2393 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2398 lsa_RetrievePrivateData
2400 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2401 struct lsa_RetrievePrivateData *r)
2403 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2410 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2411 struct lsa_GetUserName *r)
2413 NTSTATUS status = NT_STATUS_OK;
2414 const char *account_name;
2415 const char *authority_name;
2416 struct lsa_String *_account_name;
2417 struct lsa_StringPointer *_authority_name = NULL;
2419 /* this is what w2k3 does */
2420 r->out.account_name = r->in.account_name;
2421 r->out.authority_name = r->in.authority_name;
2423 if (r->in.account_name && r->in.account_name->string) {
2424 return NT_STATUS_INVALID_PARAMETER;
2427 if (r->in.authority_name &&
2428 r->in.authority_name->string &&
2429 r->in.authority_name->string->string) {
2430 return NT_STATUS_INVALID_PARAMETER;
2433 /* TODO: this check should go and we should rely on the calling code that this is valid */
2434 if (!dce_call->conn->auth_state.session_info ||
2435 !dce_call->conn->auth_state.session_info->server_info ||
2436 !dce_call->conn->auth_state.session_info->server_info->account_name ||
2437 !dce_call->conn->auth_state.session_info->server_info->domain_name) {
2438 return NT_STATUS_INTERNAL_ERROR;
2441 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2442 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2444 _account_name = talloc(mem_ctx, struct lsa_String);
2445 NTSTATUS_TALLOC_CHECK(_account_name);
2446 _account_name->string = account_name;
2448 if (r->in.authority_name) {
2449 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2450 NTSTATUS_TALLOC_CHECK(_authority_name);
2451 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2452 NTSTATUS_TALLOC_CHECK(_authority_name->string);
2453 _authority_name->string->string = authority_name;
2456 r->out.account_name = _account_name;
2457 r->out.authority_name = _authority_name;
2465 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2466 TALLOC_CTX *mem_ctx,
2467 struct lsa_SetInfoPolicy2 *r)
2469 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2473 lsa_QueryDomainInformationPolicy
2475 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2476 TALLOC_CTX *mem_ctx,
2477 struct lsa_QueryDomainInformationPolicy *r)
2479 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2483 lsa_SetDomInfoPolicy
2485 static NTSTATUS lsa_SetDomInfoPolicy(struct dcesrv_call_state *dce_call,
2486 TALLOC_CTX *mem_ctx,
2487 struct lsa_SetDomInfoPolicy *r)
2489 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2495 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
2496 TALLOC_CTX *mem_ctx,
2497 struct lsa_TestCall *r)
2499 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2503 lookup a SID for 1 name
2505 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
2506 const char *name, struct dom_sid **sid, uint32_t *atype)
2509 struct ldb_message **res;
2510 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
2513 p = strchr_m(name, '\\');
2515 /* TODO: properly parse the domain prefix here, and use it to
2520 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", name);
2522 *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
2524 return NT_STATUS_INVALID_SID;
2527 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
2529 return NT_STATUS_OK;
2532 /* need to add a call into sidmap to check for a allocated sid */
2534 return NT_STATUS_INVALID_SID;
2541 static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call,
2542 TALLOC_CTX *mem_ctx,
2543 struct lsa_LookupNames3 *r)
2545 struct lsa_policy_state *state;
2546 struct dcesrv_handle *h;
2548 NTSTATUS status = NT_STATUS_OK;
2550 r->out.domains = NULL;
2552 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2556 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
2557 if (r->out.domains == NULL) {
2558 return NT_STATUS_NO_MEMORY;
2561 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
2562 if (r->out.sids == NULL) {
2563 return NT_STATUS_NO_MEMORY;
2568 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3,
2570 if (r->out.sids->sids == NULL) {
2571 return NT_STATUS_NO_MEMORY;
2574 for (i=0;i<r->in.num_names;i++) {
2575 const char *name = r->in.names[i].string;
2576 struct dom_sid *sid;
2577 uint32_t atype, rtype, sid_index;
2580 r->out.sids->count++;
2583 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
2584 r->out.sids->sids[i].sid = NULL;
2585 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
2586 r->out.sids->sids[i].unknown = 0;
2588 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
2589 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
2590 status = STATUS_SOME_UNMAPPED;
2594 rtype = samdb_atype_map(atype);
2595 if (rtype == SID_NAME_UNKNOWN) {
2596 status = STATUS_SOME_UNMAPPED;
2600 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
2601 if (!NT_STATUS_IS_OK(status2)) {
2605 r->out.sids->sids[i].sid_type = rtype;
2606 r->out.sids->sids[i].sid = sid;
2607 r->out.sids->sids[i].sid_index = sid_index;
2608 r->out.sids->sids[i].unknown = 0;
2617 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
2618 TALLOC_CTX *mem_ctx,
2619 struct lsa_LookupNames2 *r)
2621 struct lsa_policy_state *state;
2622 struct dcesrv_handle *h;
2624 NTSTATUS status = NT_STATUS_OK;
2626 r->out.domains = NULL;
2628 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2632 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
2633 if (r->out.domains == NULL) {
2634 return NT_STATUS_NO_MEMORY;
2637 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray2);
2638 if (r->out.sids == NULL) {
2639 return NT_STATUS_NO_MEMORY;
2644 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2,
2646 if (r->out.sids->sids == NULL) {
2647 return NT_STATUS_NO_MEMORY;
2650 for (i=0;i<r->in.num_names;i++) {
2651 const char *name = r->in.names[i].string;
2652 struct dom_sid *sid;
2653 uint32_t atype, rtype, sid_index;
2656 r->out.sids->count++;
2659 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
2660 r->out.sids->sids[i].rid = 0xFFFFFFFF;
2661 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
2662 r->out.sids->sids[i].unknown = 0;
2664 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
2665 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
2666 status = STATUS_SOME_UNMAPPED;
2670 rtype = samdb_atype_map(atype);
2671 if (rtype == SID_NAME_UNKNOWN) {
2672 status = STATUS_SOME_UNMAPPED;
2676 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
2677 if (!NT_STATUS_IS_OK(status2)) {
2681 r->out.sids->sids[i].sid_type = rtype;
2682 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
2683 r->out.sids->sids[i].sid_index = sid_index;
2684 r->out.sids->sids[i].unknown = 0;
2693 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2694 struct lsa_LookupNames *r)
2696 struct lsa_LookupNames2 r2;
2700 r2.in.handle = r->in.handle;
2701 r2.in.num_names = r->in.num_names;
2702 r2.in.names = r->in.names;
2704 r2.in.level = r->in.level;
2705 r2.in.count = r->in.count;
2708 r2.out.count = r->out.count;
2710 status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
2711 if (dce_call->fault_code != 0) {
2715 r->out.domains = r2.out.domains;
2716 r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
2717 if (r->out.sids == NULL) {
2718 return NT_STATUS_NO_MEMORY;
2720 r->out.sids->count = r2.out.sids->count;
2721 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid,
2722 r->out.sids->count);
2723 if (r->out.sids->sids == NULL) {
2724 return NT_STATUS_NO_MEMORY;
2726 for (i=0;i<r->out.sids->count;i++) {
2727 r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type;
2728 r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid;
2729 r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index;
2738 static NTSTATUS lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2739 struct lsa_CREDRWRITE *r)
2741 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2748 static NTSTATUS lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2749 struct lsa_CREDRREAD *r)
2751 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2758 static NTSTATUS lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2759 struct lsa_CREDRENUMERATE *r)
2761 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2766 lsa_CREDRWRITEDOMAINCREDENTIALS
2768 static NTSTATUS lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2769 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2771 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2776 lsa_CREDRREADDOMAINCREDENTIALS
2778 static NTSTATUS lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2779 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2781 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2788 static NTSTATUS lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2789 struct lsa_CREDRDELETE *r)
2791 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2796 lsa_CREDRGETTARGETINFO
2798 static NTSTATUS lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2799 struct lsa_CREDRGETTARGETINFO *r)
2801 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2806 lsa_CREDRPROFILELOADED
2808 static NTSTATUS lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2809 struct lsa_CREDRPROFILELOADED *r)
2811 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2816 lsa_CREDRGETSESSIONTYPES
2818 static NTSTATUS lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2819 struct lsa_CREDRGETSESSIONTYPES *r)
2821 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2826 lsa_LSARREGISTERAUDITEVENT
2828 static NTSTATUS lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2829 struct lsa_LSARREGISTERAUDITEVENT *r)
2831 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2836 lsa_LSARGENAUDITEVENT
2838 static NTSTATUS lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2839 struct lsa_LSARGENAUDITEVENT *r)
2841 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2846 lsa_LSARUNREGISTERAUDITEVENT
2848 static NTSTATUS lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2849 struct lsa_LSARUNREGISTERAUDITEVENT *r)
2851 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2856 lsa_LSARQUERYFORESTTRUSTINFORMATION
2858 static NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2859 struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
2861 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2866 lsa_LSARSETFORESTTRUSTINFORMATION
2868 static NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2869 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2871 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2878 static NTSTATUS lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2879 struct lsa_CREDRRENAME *r)
2881 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2886 lsa_LSARLOOKUPNAMES4
2888 static NTSTATUS lsa_LSARLOOKUPNAMES4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2889 struct lsa_LSARLOOKUPNAMES4 *r)
2891 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2896 lsa_LSAROPENPOLICYSCE
2898 static NTSTATUS lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2899 struct lsa_LSAROPENPOLICYSCE *r)
2901 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2906 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
2908 static NTSTATUS lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2909 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2911 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2916 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
2918 static NTSTATUS lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2919 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2921 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2926 lsa_LSARADTREPORTSECURITYEVENT
2928 static NTSTATUS lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2929 struct lsa_LSARADTREPORTSECURITYEVENT *r)
2931 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2935 /* include the generated boilerplate */
2936 #include "librpc/gen_ndr/ndr_lsa_s.c"