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 "system/time.h"
32 #include "auth/auth.h"
33 #include "dsdb/samdb/samdb.h"
34 #include "libcli/ldap/ldap.h"
37 this type allows us to distinguish handle types
43 LSA_HANDLE_TRUSTED_DOMAIN
47 state associated with a lsa_OpenPolicy() operation
49 struct lsa_policy_state {
50 struct dcesrv_handle *handle;
51 struct ldb_context *sam_ldb;
52 struct sidmap_context *sidmap;
54 const struct ldb_dn *domain_dn;
55 const struct ldb_dn *builtin_dn;
56 const struct ldb_dn *system_dn;
57 const char *domain_name;
58 struct dom_sid *domain_sid;
59 struct dom_sid *builtin_sid;
64 state associated with a lsa_OpenAccount() operation
66 struct lsa_account_state {
67 struct lsa_policy_state *policy;
69 struct dom_sid *account_sid;
70 const struct ldb_dn *account_dn;
75 state associated with a lsa_OpenSecret() operation
77 struct lsa_secret_state {
78 struct lsa_policy_state *policy;
80 const struct ldb_dn *secret_dn;
81 struct ldb_context *sam_ldb;
86 state associated with a lsa_OpenTrustedDomain() operation
88 struct lsa_trusted_domain_state {
89 struct lsa_policy_state *policy;
91 const struct ldb_dn *trusted_domain_dn;
97 static NTSTATUS lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
100 struct dcesrv_handle *h;
102 *r->out.handle = *r->in.handle;
104 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
108 ZERO_STRUCTP(r->out.handle);
117 static NTSTATUS lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
118 struct lsa_Delete *r)
120 struct dcesrv_handle *h;
123 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
124 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
125 struct lsa_secret_state *secret_state = h->data;
126 ret = samdb_delete(secret_state->sam_ldb, mem_ctx, secret_state->secret_dn);
129 return NT_STATUS_INVALID_HANDLE;
133 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
134 struct lsa_trusted_domain_state *trusted_domain_state = h->data;
135 ret = samdb_delete(trusted_domain_state->policy->sam_ldb, mem_ctx,
136 trusted_domain_state->trusted_domain_dn);
139 return NT_STATUS_INVALID_HANDLE;
145 return NT_STATUS_INVALID_HANDLE;
152 static NTSTATUS lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
153 struct lsa_EnumPrivs *r)
155 struct dcesrv_handle *h;
156 struct lsa_policy_state *state;
158 const char *privname;
160 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
164 i = *r->in.resume_handle;
167 while ((privname = sec_privilege_name(i)) &&
168 r->out.privs->count < r->in.max_count) {
169 struct lsa_PrivEntry *e;
171 r->out.privs->privs = talloc_realloc(r->out.privs,
173 struct lsa_PrivEntry,
174 r->out.privs->count+1);
175 if (r->out.privs->privs == NULL) {
176 return NT_STATUS_NO_MEMORY;
178 e = &r->out.privs->privs[r->out.privs->count];
181 e->name.string = privname;
182 r->out.privs->count++;
186 *r->out.resume_handle = i;
195 static NTSTATUS lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
196 struct lsa_QuerySecurity *r)
198 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
205 static NTSTATUS lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
206 struct lsa_SetSecObj *r)
208 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
215 static NTSTATUS lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
216 struct lsa_ChangePassword *r)
218 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
221 static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
222 struct lsa_policy_state **_state)
224 struct lsa_policy_state *state;
226 state = talloc(mem_ctx, struct lsa_policy_state);
228 return NT_STATUS_NO_MEMORY;
231 /* make sure the sam database is accessible */
232 state->sam_ldb = samdb_connect(state, dce_call->conn->auth_state.session_info);
233 if (state->sam_ldb == NULL) {
234 return NT_STATUS_INVALID_SYSTEM_SERVICE;
237 state->sidmap = sidmap_open(state);
238 if (state->sidmap == NULL) {
239 return NT_STATUS_INVALID_SYSTEM_SERVICE;
242 /* work out the domain_dn - useful for so many calls its worth
244 state->domain_dn = samdb_base_dn(state);
245 if (!state->domain_dn) {
246 return NT_STATUS_NO_MEMORY;
250 = samdb_search_string(state->sam_ldb, state, NULL, "nETBIOSName",
251 "(&(objectclass=crossRef)(ncName=%s))", ldb_dn_linearize(mem_ctx, state->domain_dn));
253 if (!state->domain_name) {
254 return NT_STATUS_NO_SUCH_DOMAIN;
256 talloc_steal(state, state->domain_name);
258 /* work out the builtin_dn - useful for so many calls its worth
260 state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
261 if (!state->builtin_dn) {
262 return NT_STATUS_NO_SUCH_DOMAIN;
265 /* work out the system_dn - useful for so many calls its worth
267 state->system_dn = samdb_search_dn(state->sam_ldb, state,
268 state->domain_dn, "(&(objectClass=container)(cn=System))");
269 if (!state->system_dn) {
270 return NT_STATUS_NO_SUCH_DOMAIN;
273 state->domain_sid = samdb_search_dom_sid(state->sam_ldb, state,
274 state->domain_dn, "objectSid", NULL);
275 if (!state->domain_sid) {
276 return NT_STATUS_NO_SUCH_DOMAIN;
279 talloc_steal(state, state->domain_sid);
281 state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
282 if (!state->builtin_sid) {
283 return NT_STATUS_NO_SUCH_DOMAIN;
294 static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
295 struct lsa_OpenPolicy2 *r)
298 struct lsa_policy_state *state;
299 struct dcesrv_handle *handle;
301 ZERO_STRUCTP(r->out.handle);
303 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
304 if (!NT_STATUS_IS_OK(status)) {
308 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
310 return NT_STATUS_NO_MEMORY;
313 handle->data = talloc_steal(handle, state);
315 state->access_mask = r->in.access_mask;
316 state->handle = handle;
317 *r->out.handle = handle->wire_handle;
319 /* note that we have completely ignored the attr element of
320 the OpenPolicy. As far as I can tell, this is what w2k3
328 a wrapper around lsa_OpenPolicy2
330 static NTSTATUS lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
331 struct lsa_OpenPolicy *r)
333 struct lsa_OpenPolicy2 r2;
335 r2.in.system_name = NULL;
336 r2.in.attr = r->in.attr;
337 r2.in.access_mask = r->in.access_mask;
338 r2.out.handle = r->out.handle;
340 return lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
347 fill in the AccountDomain info
349 static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
350 struct lsa_DomainInfo *info)
352 info->name.string = state->domain_name;
353 info->sid = state->domain_sid;
359 fill in the DNS domain info
361 static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
362 struct lsa_DnsDomainInfo *info)
364 const char * const attrs[] = { "dnsDomain", "objectGUID", "objectSid", NULL };
366 struct ldb_message **res;
368 ret = gendb_search_dn(state->sam_ldb, mem_ctx, state->domain_dn, &res, attrs);
370 return NT_STATUS_INTERNAL_DB_CORRUPTION;
373 info->name.string = state->domain_name;
374 info->sid = state->domain_sid;
375 info->dns_domain.string = samdb_result_string(res[0], "dnsDomain", NULL);
376 info->dns_forest.string = samdb_result_string(res[0], "dnsDomain", NULL);
377 info->domain_guid = samdb_result_guid(res[0], "objectGUID");
385 static NTSTATUS lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
386 struct lsa_QueryInfoPolicy2 *r)
388 struct lsa_policy_state *state;
389 struct dcesrv_handle *h;
393 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
397 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
399 return NT_STATUS_NO_MEMORY;
402 ZERO_STRUCTP(r->out.info);
404 switch (r->in.level) {
405 case LSA_POLICY_INFO_DOMAIN:
406 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
407 return lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
409 case LSA_POLICY_INFO_DNS:
410 return lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
413 return NT_STATUS_INVALID_INFO_CLASS;
419 static NTSTATUS lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
420 struct lsa_QueryInfoPolicy *r)
422 struct lsa_QueryInfoPolicy2 r2;
425 r2.in.handle = r->in.handle;
426 r2.in.level = r->in.level;
428 status = lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
430 r->out.info = r2.out.info;
438 static NTSTATUS lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
439 struct lsa_SetInfoPolicy *r)
441 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
448 static NTSTATUS lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
449 struct lsa_ClearAuditLog *r)
451 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
458 static NTSTATUS lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
459 struct lsa_CreateAccount *r)
461 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
468 static NTSTATUS lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
469 struct lsa_EnumAccounts *r)
471 struct dcesrv_handle *h;
472 struct lsa_policy_state *state;
474 struct ldb_message **res;
475 const char * const attrs[] = { "objectSid", NULL};
478 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
482 ret = gendb_search(state->sam_ldb, mem_ctx, state->builtin_dn, &res, attrs,
483 "(|(privilege=*)(objectSid=*))");
485 return NT_STATUS_NO_SUCH_USER;
488 if (*r->in.resume_handle >= ret) {
489 return NT_STATUS_NO_MORE_ENTRIES;
492 count = ret - *r->in.resume_handle;
493 if (count > r->in.num_entries) {
494 count = r->in.num_entries;
498 return NT_STATUS_NO_MORE_ENTRIES;
501 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
502 if (r->out.sids->sids == NULL) {
503 return NT_STATUS_NO_MEMORY;
506 for (i=0;i<count;i++) {
507 r->out.sids->sids[i].sid =
508 samdb_result_dom_sid(r->out.sids->sids,
509 res[i + *r->in.resume_handle],
511 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
514 r->out.sids->num_sids = count;
515 *r->out.resume_handle = count + *r->in.resume_handle;
523 lsa_CreateTrustedDomainEx2
525 static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
527 struct lsa_CreateTrustedDomainEx2 *r)
529 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
533 lsa_CreateTrustedDomainEx
535 static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
537 struct lsa_CreateTrustedDomainEx *r)
539 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
543 lsa_CreateTrustedDomain
545 static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
546 struct lsa_CreateTrustedDomain *r)
548 struct dcesrv_handle *policy_handle;
549 struct lsa_policy_state *policy_state;
550 struct lsa_trusted_domain_state *trusted_domain_state;
551 struct dcesrv_handle *handle;
552 struct ldb_message **msgs, *msg;
553 const char *attrs[] = {
559 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
560 ZERO_STRUCTP(r->out.trustdom_handle);
562 policy_state = policy_handle->data;
564 if (!r->in.info->name.string) {
565 return NT_STATUS_INVALID_PARAMETER;
567 name = r->in.info->name.string;
569 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
570 if (!trusted_domain_state) {
571 return NT_STATUS_NO_MEMORY;
573 trusted_domain_state->policy = policy_state;
575 msg = ldb_msg_new(mem_ctx);
577 return NT_STATUS_NO_MEMORY;
580 /* search for the trusted_domain record */
581 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
582 mem_ctx, policy_state->system_dn, &msgs, attrs,
583 "(&(cn=%s)(objectclass=trustedDomain))",
584 ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
586 return NT_STATUS_OBJECT_NAME_COLLISION;
589 if (ret < 0 || ret > 1) {
590 DEBUG(0,("Found %d records matching DN %s\n", ret,
591 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
592 return NT_STATUS_INTERNAL_DB_CORRUPTION;
595 msg->dn = ldb_dn_build_child(mem_ctx, "cn",
596 r->in.info->name.string,
597 policy_state->system_dn);
599 return NT_STATUS_NO_MEMORY;
602 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "cn", name);
603 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
605 if (r->in.info->sid) {
606 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
608 return NT_STATUS_NO_MEMORY;
611 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
614 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
616 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
618 /* create the trusted_domain */
619 ret = samdb_add(trusted_domain_state->policy->sam_ldb, mem_ctx, msg);
621 DEBUG(0,("Failed to create trusted_domain record %s\n",
622 ldb_dn_linearize(mem_ctx, msg->dn)));
623 return NT_STATUS_INTERNAL_DB_CORRUPTION;
626 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
628 return NT_STATUS_NO_MEMORY;
631 handle->data = talloc_steal(handle, trusted_domain_state);
633 trusted_domain_state->access_mask = r->in.access_mask;
634 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
636 *r->out.trustdom_handle = handle->wire_handle;
642 lsa_OpenTrustedDomain
644 static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
645 struct lsa_OpenTrustedDomain *r)
647 struct dcesrv_handle *policy_handle;
649 struct lsa_policy_state *policy_state;
650 struct lsa_trusted_domain_state *trusted_domain_state;
651 struct dcesrv_handle *handle;
652 struct ldb_message **msgs;
653 const char *attrs[] = {
657 const char *sid_string;
660 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
661 ZERO_STRUCTP(r->out.trustdom_handle);
662 policy_state = policy_handle->data;
664 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
665 if (!trusted_domain_state) {
666 return NT_STATUS_NO_MEMORY;
668 trusted_domain_state->policy = policy_state;
670 sid_string = dom_sid_string(mem_ctx, r->in.sid);
672 return NT_STATUS_NO_MEMORY;
675 /* search for the trusted_domain record */
676 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
677 mem_ctx, policy_state->system_dn, &msgs, attrs,
678 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
681 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
685 DEBUG(0,("Found %d records matching DN %s\n", ret,
686 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
687 return NT_STATUS_INTERNAL_DB_CORRUPTION;
690 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
692 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
694 return NT_STATUS_NO_MEMORY;
697 handle->data = talloc_steal(handle, trusted_domain_state);
699 trusted_domain_state->access_mask = r->in.access_mask;
700 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
702 *r->out.trustdom_handle = handle->wire_handle;
709 lsa_OpenTrustedDomainByName
711 static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
713 struct lsa_OpenTrustedDomainByName *r)
715 struct dcesrv_handle *policy_handle;
717 struct lsa_policy_state *policy_state;
718 struct lsa_trusted_domain_state *trusted_domain_state;
719 struct dcesrv_handle *handle;
720 struct ldb_message **msgs;
721 const char *attrs[] = {
727 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
728 ZERO_STRUCTP(r->out.trustdom_handle);
729 policy_state = policy_handle->data;
731 if (!r->in.name.string) {
732 return NT_STATUS_INVALID_PARAMETER;
735 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
736 if (!trusted_domain_state) {
737 return NT_STATUS_NO_MEMORY;
739 trusted_domain_state->policy = policy_state;
741 /* search for the trusted_domain record */
742 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
743 mem_ctx, policy_state->system_dn, &msgs, attrs,
744 "(&(flatname=%s)(objectclass=trustedDomain))",
745 ldb_binary_encode_string(mem_ctx, r->in.name.string));
747 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
751 DEBUG(0,("Found %d records matching DN %s\n", ret,
752 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
753 return NT_STATUS_INTERNAL_DB_CORRUPTION;
756 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
758 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
760 return NT_STATUS_NO_MEMORY;
763 handle->data = talloc_steal(handle, trusted_domain_state);
765 trusted_domain_state->access_mask = r->in.access_mask;
766 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
768 *r->out.trustdom_handle = handle->wire_handle;
775 lsa_QueryTrustedDomainInfoBySid
777 static NTSTATUS lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
778 struct lsa_QueryTrustedDomainInfoBySid *r)
780 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
785 lsa_SetTrustDomainInfo
787 static NTSTATUS lsa_SetTrustDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
788 struct lsa_SetTrustDomainInfo *r)
790 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
795 lsa_DeleteTrustDomain
797 static NTSTATUS lsa_DeleteTrustDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
798 struct lsa_DeleteTrustDomain *r)
800 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
805 lsa_QueryTrustedDomainInfo
807 static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
808 struct lsa_QueryTrustedDomainInfo *r)
810 struct dcesrv_handle *h;
811 struct lsa_trusted_domain_state *trusted_domain_state;
812 struct ldb_message *msg;
814 struct ldb_message **res;
815 const char *attrs[] = {
819 "securityIdentifier",
823 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
825 trusted_domain_state = h->data;
827 /* pull all the user attributes */
828 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
829 trusted_domain_state->trusted_domain_dn, &res, attrs);
831 return NT_STATUS_INTERNAL_DB_CORRUPTION;
835 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
837 return NT_STATUS_NO_MEMORY;
839 switch (r->in.level) {
840 case LSA_TRUSTED_DOMAIN_INFO_NAME:
841 r->out.info->name.netbios_name.string
842 = samdb_result_string(msg, "flatname", NULL);
844 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
845 r->out.info->posix_offset.posix_offset
846 = samdb_result_uint(msg, "posixOffset", 0);
849 /* oops, we don't want to return the info after all */
850 talloc_free(r->out.info);
852 return NT_STATUS_INVALID_INFO_CLASS;
860 lsa_SetInformationTrustedDomain
862 static NTSTATUS lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
863 struct lsa_SetInformationTrustedDomain *r)
865 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
870 lsa_QueryTrustedDomainInfoByName
872 static NTSTATUS lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
874 struct lsa_QueryTrustedDomainInfoByName *r)
876 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
880 lsa_SetTrustedDomainInfoByName
882 static NTSTATUS lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
884 struct lsa_SetTrustedDomainInfoByName *r)
886 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
890 lsa_EnumTrustedDomainsEx
892 static NTSTATUS lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call,
894 struct lsa_EnumTrustedDomainsEx *r)
896 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
900 lsa_CloseTrustedDomainEx
902 static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
904 struct lsa_CloseTrustedDomainEx *r)
906 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
911 comparison function for sorting lsa_DomainInformation array
913 static int compare_DomainInformation(struct lsa_DomainInformation *e1, struct lsa_DomainInformation *e2)
915 return strcasecmp(e1->name.string, e2->name.string);
921 static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
922 struct lsa_EnumTrustDom *r)
924 struct dcesrv_handle *policy_handle;
925 struct lsa_DomainInformation *entries;
926 struct lsa_policy_state *policy_state;
927 struct ldb_message **domains;
928 const char *attrs[] = {
930 "securityIdentifier",
937 *r->out.resume_handle = 0;
939 r->out.domains->domains = NULL;
940 r->out.domains->count = 0;
942 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
944 policy_state = policy_handle->data;
946 /* search for all users in this domain. This could possibly be cached and
947 resumed based on resume_key */
948 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
949 "objectclass=trustedDomain");
951 return NT_STATUS_INTERNAL_DB_CORRUPTION;
953 if (count == 0 || r->in.max_size == 0) {
957 /* convert to lsa_DomainInformation format */
958 entries = talloc_array(mem_ctx, struct lsa_DomainInformation, count);
960 return NT_STATUS_NO_MEMORY;
962 for (i=0;i<count;i++) {
963 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
964 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
967 /* sort the results by name */
968 qsort(entries, count, sizeof(struct lsa_DomainInformation),
969 (comparison_fn_t)compare_DomainInformation);
971 if (*r->in.resume_handle >= count) {
972 *r->out.resume_handle = -1;
974 return NT_STATUS_NO_MORE_ENTRIES;
977 /* return the rest, limit by max_size. Note that we
978 use the w2k3 element size value of 60 */
979 r->out.domains->count = count - *r->in.resume_handle;
980 r->out.domains->count = MIN(r->out.domains->count,
981 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
983 r->out.domains->domains = entries + *r->in.resume_handle;
984 r->out.domains->count = r->out.domains->count;
986 if (r->out.domains->count < count - *r->in.resume_handle) {
987 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
988 return STATUS_MORE_ENTRIES;
996 return the authority name and authority sid, given a sid
998 static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
999 TALLOC_CTX *mem_ctx, struct dom_sid *sid,
1000 const char **authority_name,
1001 struct dom_sid **authority_sid)
1003 if (dom_sid_in_domain(state->domain_sid, sid)) {
1004 *authority_name = state->domain_name;
1005 *authority_sid = state->domain_sid;
1006 return NT_STATUS_OK;
1009 if (dom_sid_in_domain(state->builtin_sid, sid)) {
1010 *authority_name = "BUILTIN";
1011 *authority_sid = state->builtin_sid;
1012 return NT_STATUS_OK;
1015 *authority_sid = dom_sid_dup(mem_ctx, sid);
1016 if (*authority_sid == NULL) {
1017 return NT_STATUS_NO_MEMORY;
1019 (*authority_sid)->num_auths = 0;
1020 *authority_name = dom_sid_string(mem_ctx, *authority_sid);
1021 if (*authority_name == NULL) {
1022 return NT_STATUS_NO_MEMORY;
1025 return NT_STATUS_OK;
1029 add to the lsa_RefDomainList for LookupSids and LookupNames
1031 static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1032 struct dom_sid *sid,
1033 struct lsa_RefDomainList *domains,
1034 uint32_t *sid_index)
1037 const char *authority_name;
1038 struct dom_sid *authority_sid;
1041 /* work out the authority name */
1042 status = lsa_authority_name(state, mem_ctx, sid,
1043 &authority_name, &authority_sid);
1044 if (!NT_STATUS_IS_OK(status)) {
1048 /* see if we've already done this authority name */
1049 for (i=0;i<domains->count;i++) {
1050 if (strcmp(authority_name, domains->domains[i].name.string) == 0) {
1052 return NT_STATUS_OK;
1056 domains->domains = talloc_realloc(domains,
1058 struct lsa_TrustInformation,
1060 if (domains->domains == NULL) {
1061 return NT_STATUS_NO_MEMORY;
1063 domains->domains[i].name.string = authority_name;
1064 domains->domains[i].sid = authority_sid;
1068 return NT_STATUS_OK;
1072 lookup a name for 1 SID
1074 static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1075 struct dom_sid *sid, const char *sid_str,
1076 const char **name, uint32_t *atype)
1079 struct ldb_message **res;
1080 const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "name", NULL};
1083 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1084 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
1086 *name = ldb_msg_find_string(res[0], "sAMAccountName", NULL);
1088 *name = ldb_msg_find_string(res[0], "name", NULL);
1090 *name = talloc_strdup(mem_ctx, sid_str);
1091 NTSTATUS_TALLOC_CHECK(*name);
1095 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
1097 return NT_STATUS_OK;
1100 status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype);
1109 static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
1110 TALLOC_CTX *mem_ctx,
1111 struct lsa_LookupSids3 *r)
1113 struct lsa_policy_state *state;
1115 NTSTATUS status = NT_STATUS_OK;
1117 r->out.domains = NULL;
1119 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
1120 if (!NT_STATUS_IS_OK(status)) {
1124 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
1125 if (r->out.domains == NULL) {
1126 return NT_STATUS_NO_MEMORY;
1129 r->out.names = talloc_zero(mem_ctx, struct lsa_TransNameArray2);
1130 if (r->out.names == NULL) {
1131 return NT_STATUS_NO_MEMORY;
1136 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName2,
1137 r->in.sids->num_sids);
1138 if (r->out.names->names == NULL) {
1139 return NT_STATUS_NO_MEMORY;
1142 for (i=0;i<r->in.sids->num_sids;i++) {
1143 struct dom_sid *sid = r->in.sids->sids[i].sid;
1144 char *sid_str = dom_sid_string(mem_ctx, sid);
1146 uint32_t atype, rtype, sid_index;
1149 r->out.names->count++;
1152 r->out.names->names[i].sid_type = SID_NAME_UNKNOWN;
1153 r->out.names->names[i].name.string = sid_str;
1154 r->out.names->names[i].sid_index = 0xFFFFFFFF;
1155 r->out.names->names[i].unknown = 0;
1157 if (sid_str == NULL) {
1158 r->out.names->names[i].name.string = "(SIDERROR)";
1159 status = STATUS_SOME_UNMAPPED;
1163 /* work out the authority name */
1164 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
1165 if (!NT_STATUS_IS_OK(status2)) {
1169 status2 = lsa_lookup_sid(state, mem_ctx, sid, sid_str,
1171 if (!NT_STATUS_IS_OK(status2)) {
1172 status = STATUS_SOME_UNMAPPED;
1176 rtype = samdb_atype_map(atype);
1177 if (rtype == SID_NAME_UNKNOWN) {
1178 status = STATUS_SOME_UNMAPPED;
1182 r->out.names->names[i].sid_type = rtype;
1183 r->out.names->names[i].name.string = name;
1184 r->out.names->names[i].sid_index = sid_index;
1185 r->out.names->names[i].unknown = 0;
1195 static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
1196 TALLOC_CTX *mem_ctx,
1197 struct lsa_LookupSids2 *r)
1199 struct lsa_LookupSids3 r3;
1202 r3.in.sids = r->in.sids;
1203 r3.in.names = r->in.names;
1204 r3.in.level = r->in.level;
1205 r3.in.count = r->in.count;
1206 r3.in.unknown1 = r->in.unknown1;
1207 r3.in.unknown2 = r->in.unknown2;
1208 r3.out.count = r->out.count;
1209 r3.out.names = r->out.names;
1211 status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
1212 if (dce_call->fault_code != 0) {
1216 r->out.domains = r3.out.domains;
1217 r->out.names = r3.out.names;
1218 r->out.count = r3.out.count;
1227 static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1228 struct lsa_LookupSids *r)
1230 struct lsa_LookupSids3 r3;
1234 r3.in.sids = r->in.sids;
1236 r3.in.level = r->in.level;
1237 r3.in.count = r->in.count;
1240 r3.out.count = r->out.count;
1241 r3.out.names = NULL;
1243 status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
1244 if (dce_call->fault_code != 0) {
1248 r->out.domains = r3.out.domains;
1249 if (!r3.out.names) {
1250 r->out.names = NULL;
1254 r->out.names = talloc(mem_ctx, struct lsa_TransNameArray);
1255 if (r->out.names == NULL) {
1256 return NT_STATUS_NO_MEMORY;
1258 r->out.names->count = r3.out.names->count;
1259 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName,
1260 r->out.names->count);
1261 if (r->out.names->names == NULL) {
1262 return NT_STATUS_NO_MEMORY;
1264 for (i=0;i<r->out.names->count;i++) {
1265 r->out.names->names[i].sid_type = r3.out.names->names[i].sid_type;
1266 r->out.names->names[i].name.string = r3.out.names->names[i].name.string;
1267 r->out.names->names[i].sid_index = r3.out.names->names[i].sid_index;
1277 static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1278 struct lsa_OpenAccount *r)
1280 struct dcesrv_handle *h, *ah;
1281 struct lsa_policy_state *state;
1282 struct lsa_account_state *astate;
1284 ZERO_STRUCTP(r->out.acct_handle);
1286 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1290 astate = talloc(dce_call->conn, struct lsa_account_state);
1291 if (astate == NULL) {
1292 return NT_STATUS_NO_MEMORY;
1295 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1296 if (astate->account_sid == NULL) {
1297 talloc_free(astate);
1298 return NT_STATUS_NO_MEMORY;
1301 /* check it really exists */
1302 astate->account_dn = samdb_search_dn(state->sam_ldb, astate,
1303 NULL, "(&(objectSid=%s)(objectClass=group))",
1304 ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid));
1305 if (astate->account_dn == NULL) {
1306 talloc_free(astate);
1307 return NT_STATUS_NO_SUCH_USER;
1310 astate->policy = talloc_reference(astate, state);
1311 astate->access_mask = r->in.access_mask;
1313 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1315 talloc_free(astate);
1316 return NT_STATUS_NO_MEMORY;
1319 ah->data = talloc_steal(ah, astate);
1321 *r->out.acct_handle = ah->wire_handle;
1323 return NT_STATUS_OK;
1328 lsa_EnumPrivsAccount
1330 static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1331 TALLOC_CTX *mem_ctx,
1332 struct lsa_EnumPrivsAccount *r)
1334 struct dcesrv_handle *h;
1335 struct lsa_account_state *astate;
1337 struct ldb_message **res;
1338 const char * const attrs[] = { "privilege", NULL};
1339 struct ldb_message_element *el;
1341 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1345 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1346 r->out.privs->count = 0;
1347 r->out.privs->unknown = 0;
1348 r->out.privs->set = NULL;
1350 ret = gendb_search_dn(astate->policy->sam_ldb, mem_ctx,
1351 astate->account_dn, &res, attrs);
1353 return NT_STATUS_OK;
1356 el = ldb_msg_find_element(res[0], "privilege");
1357 if (el == NULL || el->num_values == 0) {
1358 return NT_STATUS_OK;
1361 r->out.privs->set = talloc_array(r->out.privs,
1362 struct lsa_LUIDAttribute, el->num_values);
1363 if (r->out.privs->set == NULL) {
1364 return NT_STATUS_NO_MEMORY;
1367 for (i=0;i<el->num_values;i++) {
1368 int id = sec_privilege_id((const char *)el->values[i].data);
1370 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1372 r->out.privs->set[i].attribute = 0;
1373 r->out.privs->set[i].luid.low = id;
1374 r->out.privs->set[i].luid.high = 0;
1377 r->out.privs->count = el->num_values;
1379 return NT_STATUS_OK;
1383 lsa_EnumAccountRights
1385 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1386 TALLOC_CTX *mem_ctx,
1387 struct lsa_EnumAccountRights *r)
1389 struct dcesrv_handle *h;
1390 struct lsa_policy_state *state;
1392 struct ldb_message **res;
1393 const char * const attrs[] = { "privilege", NULL};
1395 struct ldb_message_element *el;
1397 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1401 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1402 if (sidstr == NULL) {
1403 return NT_STATUS_NO_MEMORY;
1406 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1407 "objectSid=%s", sidstr);
1409 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1412 el = ldb_msg_find_element(res[0], "privilege");
1413 if (el == NULL || el->num_values == 0) {
1414 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1417 r->out.rights->count = el->num_values;
1418 r->out.rights->names = talloc_array(r->out.rights,
1419 struct lsa_String, r->out.rights->count);
1420 if (r->out.rights->names == NULL) {
1421 return NT_STATUS_NO_MEMORY;
1424 for (i=0;i<el->num_values;i++) {
1425 r->out.rights->names[i].string = (const char *)el->values[i].data;
1428 return NT_STATUS_OK;
1434 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1436 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1437 TALLOC_CTX *mem_ctx,
1438 struct lsa_policy_state *state,
1440 struct dom_sid *sid,
1441 const struct lsa_RightSet *rights)
1444 struct ldb_message *msg;
1445 struct ldb_message_element el;
1447 struct lsa_EnumAccountRights r2;
1449 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1450 if (sidstr == NULL) {
1451 return NT_STATUS_NO_MEMORY;
1454 msg = ldb_msg_new(mem_ctx);
1456 return NT_STATUS_NO_MEMORY;
1459 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx, NULL, "objectSid=%s", sidstr);
1460 if (msg->dn == NULL) {
1461 return NT_STATUS_NO_SUCH_USER;
1464 if (ldb_msg_add_empty(msg, "privilege", ldb_flag)) {
1465 return NT_STATUS_NO_MEMORY;
1468 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1471 r2.in.handle = &state->handle->wire_handle;
1473 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1475 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1476 if (!NT_STATUS_IS_OK(status)) {
1477 ZERO_STRUCTP(r2.out.rights);
1482 el.values = talloc_array(mem_ctx, struct ldb_val, rights->count);
1483 if (el.values == NULL) {
1484 return NT_STATUS_NO_MEMORY;
1486 for (i=0;i<rights->count;i++) {
1487 if (sec_privilege_id(rights->names[i].string) == -1) {
1488 return NT_STATUS_NO_SUCH_PRIVILEGE;
1491 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1493 for (j=0;j<r2.out.rights->count;j++) {
1494 if (strcasecmp_m(r2.out.rights->names[j].string,
1495 rights->names[i].string) == 0) {
1499 if (j != r2.out.rights->count) continue;
1503 el.values[el.num_values].length = strlen(rights->names[i].string);
1504 el.values[el.num_values].data = (uint8_t *)talloc_strdup(mem_ctx, rights->names[i].string);
1505 if (el.values[el.num_values].data == NULL) {
1506 return NT_STATUS_NO_MEMORY;
1511 if (el.num_values == 0) {
1512 return NT_STATUS_OK;
1515 ret = samdb_modify(state->sam_ldb, mem_ctx, msg);
1517 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1518 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1520 return NT_STATUS_UNEXPECTED_IO_ERROR;
1523 return NT_STATUS_OK;
1527 lsa_AddPrivilegesToAccount
1529 static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1530 struct lsa_AddPrivilegesToAccount *r)
1532 struct lsa_RightSet rights;
1533 struct dcesrv_handle *h;
1534 struct lsa_account_state *astate;
1537 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1541 rights.count = r->in.privs->count;
1542 rights.names = talloc_array(mem_ctx, struct lsa_String, rights.count);
1543 if (rights.names == NULL) {
1544 return NT_STATUS_NO_MEMORY;
1546 for (i=0;i<rights.count;i++) {
1547 int id = r->in.privs->set[i].luid.low;
1548 if (r->in.privs->set[i].luid.high) {
1549 return NT_STATUS_NO_SUCH_PRIVILEGE;
1551 rights.names[i].string = sec_privilege_name(id);
1552 if (rights.names[i].string == NULL) {
1553 return NT_STATUS_NO_SUCH_PRIVILEGE;
1557 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1558 LDB_FLAG_MOD_ADD, astate->account_sid,
1564 lsa_RemovePrivilegesFromAccount
1566 static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1567 struct lsa_RemovePrivilegesFromAccount *r)
1569 struct lsa_RightSet *rights;
1570 struct dcesrv_handle *h;
1571 struct lsa_account_state *astate;
1574 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1578 rights = talloc(mem_ctx, struct lsa_RightSet);
1580 if (r->in.remove_all == 1 &&
1581 r->in.privs == NULL) {
1582 struct lsa_EnumAccountRights r2;
1585 r2.in.handle = &astate->policy->handle->wire_handle;
1586 r2.in.sid = astate->account_sid;
1587 r2.out.rights = rights;
1589 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1590 if (!NT_STATUS_IS_OK(status)) {
1594 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1595 LDB_FLAG_MOD_DELETE, astate->account_sid,
1599 if (r->in.remove_all != 0) {
1600 return NT_STATUS_INVALID_PARAMETER;
1603 rights->count = r->in.privs->count;
1604 rights->names = talloc_array(mem_ctx, struct lsa_String, rights->count);
1605 if (rights->names == NULL) {
1606 return NT_STATUS_NO_MEMORY;
1608 for (i=0;i<rights->count;i++) {
1609 int id = r->in.privs->set[i].luid.low;
1610 if (r->in.privs->set[i].luid.high) {
1611 return NT_STATUS_NO_SUCH_PRIVILEGE;
1613 rights->names[i].string = sec_privilege_name(id);
1614 if (rights->names[i].string == NULL) {
1615 return NT_STATUS_NO_SUCH_PRIVILEGE;
1619 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1620 LDB_FLAG_MOD_DELETE, astate->account_sid,
1626 lsa_GetQuotasForAccount
1628 static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1629 struct lsa_GetQuotasForAccount *r)
1631 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1636 lsa_SetQuotasForAccount
1638 static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1639 struct lsa_SetQuotasForAccount *r)
1641 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1646 lsa_GetSystemAccessAccount
1648 static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1649 struct lsa_GetSystemAccessAccount *r)
1651 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1656 lsa_SetSystemAccessAccount
1658 static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1659 struct lsa_SetSystemAccessAccount *r)
1661 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1668 static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1669 struct lsa_CreateSecret *r)
1671 struct dcesrv_handle *policy_handle;
1672 struct lsa_policy_state *policy_state;
1673 struct lsa_secret_state *secret_state;
1674 struct dcesrv_handle *handle;
1675 struct ldb_message **msgs, *msg;
1676 const char *attrs[] = {
1684 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1685 ZERO_STRUCTP(r->out.sec_handle);
1687 policy_state = policy_handle->data;
1689 if (!r->in.name.string) {
1690 return NT_STATUS_INVALID_PARAMETER;
1693 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1694 if (!secret_state) {
1695 return NT_STATUS_NO_MEMORY;
1697 secret_state->policy = policy_state;
1699 msg = ldb_msg_new(mem_ctx);
1701 return NT_STATUS_NO_MEMORY;
1704 if (strncmp("G$", r->in.name.string, 2) == 0) {
1706 name = &r->in.name.string[2];
1707 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1708 secret_state->global = True;
1710 if (strlen(name) < 1) {
1711 return NT_STATUS_INVALID_PARAMETER;
1714 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
1715 /* search for the secret record */
1716 ret = gendb_search(secret_state->sam_ldb,
1717 mem_ctx, policy_state->system_dn, &msgs, attrs,
1718 "(&(cn=%s)(objectclass=secret))",
1721 return NT_STATUS_OBJECT_NAME_COLLISION;
1724 if (ret < 0 || ret > 1) {
1725 DEBUG(0,("Found %d records matching DN %s\n", ret,
1726 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
1727 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1730 msg->dn = ldb_dn_build_child(mem_ctx, "cn", name2, policy_state->system_dn);
1731 if (!name2 || !msg->dn) {
1732 return NT_STATUS_NO_MEMORY;
1735 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
1738 secret_state->global = False;
1740 name = r->in.name.string;
1741 if (strlen(name) < 1) {
1742 return NT_STATUS_INVALID_PARAMETER;
1745 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1746 /* search for the secret record */
1747 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1748 ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
1750 "(&(cn=%s)(objectclass=secret))",
1751 ldb_binary_encode_string(mem_ctx, name));
1753 return NT_STATUS_OBJECT_NAME_COLLISION;
1756 if (ret < 0 || ret > 1) {
1757 DEBUG(0,("Found %d records matching DN %s\n", ret,
1758 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
1759 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1762 msg->dn = ldb_dn_string_compose(mem_ctx, NULL, "cn=%s,cn=LSA Secrets", name);
1763 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
1766 /* pull in all the template attributes. Note this is always from the global samdb */
1767 ret = samdb_copy_template(secret_state->policy->sam_ldb, mem_ctx, msg,
1768 "(&(name=TemplateSecret)(objectclass=secretTemplate))");
1770 DEBUG(0,("Failed to load TemplateSecret from samdb\n"));
1771 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1774 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
1776 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1778 /* create the secret */
1779 ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
1781 DEBUG(0,("Failed to create secret record %s\n",
1782 ldb_dn_linearize(mem_ctx, msg->dn)));
1783 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1786 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1788 return NT_STATUS_NO_MEMORY;
1791 handle->data = talloc_steal(handle, secret_state);
1793 secret_state->access_mask = r->in.access_mask;
1794 secret_state->policy = talloc_reference(secret_state, policy_state);
1796 *r->out.sec_handle = handle->wire_handle;
1798 return NT_STATUS_OK;
1805 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1806 struct lsa_OpenSecret *r)
1808 struct dcesrv_handle *policy_handle;
1810 struct lsa_policy_state *policy_state;
1811 struct lsa_secret_state *secret_state;
1812 struct dcesrv_handle *handle;
1813 struct ldb_message **msgs;
1814 const char *attrs[] = {
1822 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1823 ZERO_STRUCTP(r->out.sec_handle);
1824 policy_state = policy_handle->data;
1826 if (!r->in.name.string) {
1827 return NT_STATUS_INVALID_PARAMETER;
1830 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1831 if (!secret_state) {
1832 return NT_STATUS_NO_MEMORY;
1834 secret_state->policy = policy_state;
1836 if (strncmp("G$", r->in.name.string, 2) == 0) {
1837 name = &r->in.name.string[2];
1838 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1839 secret_state->global = True;
1841 if (strlen(name) < 1) {
1842 return NT_STATUS_INVALID_PARAMETER;
1845 /* search for the secret record */
1846 ret = gendb_search(secret_state->sam_ldb,
1847 mem_ctx, policy_state->system_dn, &msgs, attrs,
1848 "(&(cn=%s Secret)(objectclass=secret))",
1849 ldb_binary_encode_string(mem_ctx, name));
1851 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1855 DEBUG(0,("Found %d records matching DN %s\n", ret,
1856 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
1857 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1861 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1863 secret_state->global = False;
1864 name = r->in.name.string;
1865 if (strlen(name) < 1) {
1866 return NT_STATUS_INVALID_PARAMETER;
1869 /* search for the secret record */
1870 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1871 ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
1873 "(&(cn=%s)(objectclass=secret))",
1874 ldb_binary_encode_string(mem_ctx, name));
1876 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1880 DEBUG(0,("Found %d records matching DN %s\n", ret,
1881 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
1882 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1886 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1888 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1890 return NT_STATUS_NO_MEMORY;
1893 handle->data = talloc_steal(handle, secret_state);
1895 secret_state->access_mask = r->in.access_mask;
1896 secret_state->policy = talloc_reference(secret_state, policy_state);
1898 *r->out.sec_handle = handle->wire_handle;
1900 return NT_STATUS_OK;
1907 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1908 struct lsa_SetSecret *r)
1911 struct dcesrv_handle *h;
1912 struct lsa_secret_state *secret_state;
1913 struct ldb_message *msg;
1914 DATA_BLOB session_key;
1915 DATA_BLOB crypt_secret, secret;
1918 NTSTATUS status = NT_STATUS_OK;
1920 struct timeval now = timeval_current();
1921 NTTIME nt_now = timeval_to_nttime(&now);
1923 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
1925 secret_state = h->data;
1927 msg = ldb_msg_new(mem_ctx);
1929 return NT_STATUS_NO_MEMORY;
1932 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
1934 return NT_STATUS_NO_MEMORY;
1936 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
1937 if (!NT_STATUS_IS_OK(status)) {
1941 if (r->in.old_val) {
1943 crypt_secret.data = r->in.old_val->data;
1944 crypt_secret.length = r->in.old_val->size;
1946 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1947 if (!NT_STATUS_IS_OK(status)) {
1951 val.data = secret.data;
1952 val.length = secret.length;
1955 if (samdb_msg_add_value(secret_state->sam_ldb,
1956 mem_ctx, msg, "priorSecret", &val) != 0) {
1957 return NT_STATUS_NO_MEMORY;
1960 /* set old value mtime */
1961 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1962 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
1963 return NT_STATUS_NO_MEMORY;
1966 if (!r->in.new_val) {
1967 /* This behaviour varies depending of if this is a local, or a global secret... */
1968 if (secret_state->global) {
1969 /* set old value mtime */
1970 if (samdb_msg_add_uint64(secret_state->sam_ldb,
1971 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
1972 return NT_STATUS_NO_MEMORY;
1975 if (samdb_msg_add_delete(secret_state->sam_ldb,
1976 mem_ctx, msg, "secret")) {
1977 return NT_STATUS_NO_MEMORY;
1979 if (samdb_msg_add_delete(secret_state->sam_ldb,
1980 mem_ctx, msg, "lastSetTime")) {
1981 return NT_STATUS_NO_MEMORY;
1987 if (r->in.new_val) {
1989 crypt_secret.data = r->in.new_val->data;
1990 crypt_secret.length = r->in.new_val->size;
1992 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1993 if (!NT_STATUS_IS_OK(status)) {
1997 val.data = secret.data;
1998 val.length = secret.length;
2001 if (samdb_msg_add_value(secret_state->sam_ldb,
2002 mem_ctx, msg, "secret", &val) != 0) {
2003 return NT_STATUS_NO_MEMORY;
2006 /* set new value mtime */
2007 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2008 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2009 return NT_STATUS_NO_MEMORY;
2012 /* If the old value is not set, then migrate the
2013 * current value to the old value */
2014 if (!r->in.old_val) {
2015 const struct ldb_val *new_val;
2016 NTTIME last_set_time;
2017 struct ldb_message **res;
2018 const char *attrs[] = {
2024 /* search for the secret record */
2025 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2026 secret_state->secret_dn, &res, attrs);
2028 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2032 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2033 ldb_dn_linearize(mem_ctx, secret_state->secret_dn)));
2034 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2037 new_val = ldb_msg_find_ldb_val(res[0], "secret");
2038 last_set_time = ldb_msg_find_uint64(res[0], "lastSetTime", 0);
2042 if (samdb_msg_add_value(secret_state->sam_ldb,
2043 mem_ctx, msg, "priorSecret",
2045 return NT_STATUS_NO_MEMORY;
2049 /* set new value mtime */
2050 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2051 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2052 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2053 return NT_STATUS_NO_MEMORY;
2059 /* modify the samdb record */
2060 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2062 /* we really need samdb.c to return NTSTATUS */
2063 return NT_STATUS_UNSUCCESSFUL;
2066 return NT_STATUS_OK;
2073 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2074 struct lsa_QuerySecret *r)
2076 struct dcesrv_handle *h;
2077 struct lsa_secret_state *secret_state;
2078 struct ldb_message *msg;
2079 DATA_BLOB session_key;
2080 DATA_BLOB crypt_secret, secret;
2082 struct ldb_message **res;
2083 const char *attrs[] = {
2093 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2095 secret_state = h->data;
2097 /* pull all the user attributes */
2098 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2099 secret_state->secret_dn, &res, attrs);
2101 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2105 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2106 if (!NT_STATUS_IS_OK(nt_status)) {
2110 if (r->in.old_val) {
2111 const struct ldb_val *prior_val;
2112 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2113 if (!r->out.old_val) {
2114 return NT_STATUS_NO_MEMORY;
2117 prior_val = ldb_msg_find_ldb_val(res[0], "priorSecret");
2119 if (prior_val && prior_val->length) {
2120 secret.data = prior_val->data;
2121 secret.length = prior_val->length;
2123 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2124 if (!crypt_secret.length) {
2125 return NT_STATUS_NO_MEMORY;
2127 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2128 if (!r->out.old_val->buf) {
2129 return NT_STATUS_NO_MEMORY;
2131 r->out.old_val->buf->size = crypt_secret.length;
2132 r->out.old_val->buf->length = crypt_secret.length;
2133 r->out.old_val->buf->data = crypt_secret.data;
2137 if (r->in.old_mtime) {
2138 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2139 if (!r->out.old_mtime) {
2140 return NT_STATUS_NO_MEMORY;
2142 *r->out.old_mtime = ldb_msg_find_uint64(res[0], "priorSetTime", 0);
2145 if (r->in.new_val) {
2146 const struct ldb_val *new_val;
2147 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2148 if (!r->out.new_val) {
2149 return NT_STATUS_NO_MEMORY;
2153 new_val = ldb_msg_find_ldb_val(res[0], "secret");
2155 if (new_val && new_val->length) {
2156 secret.data = new_val->data;
2157 secret.length = new_val->length;
2159 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2160 if (!crypt_secret.length) {
2161 return NT_STATUS_NO_MEMORY;
2163 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2164 if (!r->out.new_val->buf) {
2165 return NT_STATUS_NO_MEMORY;
2167 r->out.new_val->buf->length = crypt_secret.length;
2168 r->out.new_val->buf->size = crypt_secret.length;
2169 r->out.new_val->buf->data = crypt_secret.data;
2173 if (r->in.new_mtime) {
2174 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2175 if (!r->out.new_mtime) {
2176 return NT_STATUS_NO_MEMORY;
2178 *r->out.new_mtime = ldb_msg_find_uint64(res[0], "lastSetTime", 0);
2181 return NT_STATUS_OK;
2188 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2189 TALLOC_CTX *mem_ctx,
2190 struct lsa_LookupPrivValue *r)
2192 struct dcesrv_handle *h;
2193 struct lsa_policy_state *state;
2196 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2200 id = sec_privilege_id(r->in.name->string);
2202 return NT_STATUS_NO_SUCH_PRIVILEGE;
2205 r->out.luid->low = id;
2206 r->out.luid->high = 0;
2208 return NT_STATUS_OK;
2215 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2216 TALLOC_CTX *mem_ctx,
2217 struct lsa_LookupPrivName *r)
2219 struct dcesrv_handle *h;
2220 struct lsa_policy_state *state;
2221 const char *privname;
2223 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2227 if (r->in.luid->high != 0) {
2228 return NT_STATUS_NO_SUCH_PRIVILEGE;
2231 privname = sec_privilege_name(r->in.luid->low);
2232 if (privname == NULL) {
2233 return NT_STATUS_NO_SUCH_PRIVILEGE;
2236 r->out.name = talloc(mem_ctx, struct lsa_String);
2237 if (r->out.name == NULL) {
2238 return NT_STATUS_NO_MEMORY;
2240 r->out.name->string = privname;
2242 return NT_STATUS_OK;
2247 lsa_LookupPrivDisplayName
2249 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2250 TALLOC_CTX *mem_ctx,
2251 struct lsa_LookupPrivDisplayName *r)
2253 struct dcesrv_handle *h;
2254 struct lsa_policy_state *state;
2257 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2261 id = sec_privilege_id(r->in.name->string);
2263 return NT_STATUS_NO_SUCH_PRIVILEGE;
2266 r->out.disp_name = talloc(mem_ctx, struct lsa_String);
2267 if (r->out.disp_name == NULL) {
2268 return NT_STATUS_NO_MEMORY;
2271 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2272 if (r->out.disp_name->string == NULL) {
2273 return NT_STATUS_INTERNAL_ERROR;
2276 return NT_STATUS_OK;
2283 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2284 struct lsa_DeleteObject *r)
2286 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2291 lsa_EnumAccountsWithUserRight
2293 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2294 TALLOC_CTX *mem_ctx,
2295 struct lsa_EnumAccountsWithUserRight *r)
2297 struct dcesrv_handle *h;
2298 struct lsa_policy_state *state;
2300 struct ldb_message **res;
2301 const char * const attrs[] = { "objectSid", NULL};
2302 const char *privname;
2304 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2308 if (r->in.name == NULL) {
2309 return NT_STATUS_NO_SUCH_PRIVILEGE;
2312 privname = r->in.name->string;
2313 if (sec_privilege_id(privname) == -1) {
2314 return NT_STATUS_NO_SUCH_PRIVILEGE;
2317 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2318 "privilege=%s", privname);
2320 return NT_STATUS_NO_SUCH_USER;
2323 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2324 if (r->out.sids->sids == NULL) {
2325 return NT_STATUS_NO_MEMORY;
2327 for (i=0;i<ret;i++) {
2328 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2329 res[i], "objectSid");
2330 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2332 r->out.sids->num_sids = ret;
2334 return NT_STATUS_OK;
2339 lsa_AddAccountRights
2341 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2342 TALLOC_CTX *mem_ctx,
2343 struct lsa_AddAccountRights *r)
2345 struct dcesrv_handle *h;
2346 struct lsa_policy_state *state;
2348 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2352 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2354 r->in.sid, r->in.rights);
2359 lsa_RemoveAccountRights
2361 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2362 TALLOC_CTX *mem_ctx,
2363 struct lsa_RemoveAccountRights *r)
2365 struct dcesrv_handle *h;
2366 struct lsa_policy_state *state;
2368 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2372 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2373 LDB_FLAG_MOD_DELETE,
2374 r->in.sid, r->in.rights);
2379 lsa_StorePrivateData
2381 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2382 struct lsa_StorePrivateData *r)
2384 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2389 lsa_RetrievePrivateData
2391 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2392 struct lsa_RetrievePrivateData *r)
2394 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2401 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2402 struct lsa_GetUserName *r)
2404 NTSTATUS status = NT_STATUS_OK;
2405 const char *account_name;
2406 const char *authority_name;
2407 struct lsa_String *_account_name;
2408 struct lsa_StringPointer *_authority_name = NULL;
2410 /* this is what w2k3 does */
2411 r->out.account_name = r->in.account_name;
2412 r->out.authority_name = r->in.authority_name;
2414 if (r->in.account_name && r->in.account_name->string) {
2415 return NT_STATUS_INVALID_PARAMETER;
2418 if (r->in.authority_name &&
2419 r->in.authority_name->string &&
2420 r->in.authority_name->string->string) {
2421 return NT_STATUS_INVALID_PARAMETER;
2424 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2425 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2427 _account_name = talloc(mem_ctx, struct lsa_String);
2428 NTSTATUS_TALLOC_CHECK(_account_name);
2429 _account_name->string = account_name;
2431 if (r->in.authority_name) {
2432 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2433 NTSTATUS_TALLOC_CHECK(_authority_name);
2434 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2435 NTSTATUS_TALLOC_CHECK(_authority_name->string);
2436 _authority_name->string->string = authority_name;
2439 r->out.account_name = _account_name;
2440 r->out.authority_name = _authority_name;
2448 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2449 TALLOC_CTX *mem_ctx,
2450 struct lsa_SetInfoPolicy2 *r)
2452 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2456 lsa_QueryDomainInformationPolicy
2458 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2459 TALLOC_CTX *mem_ctx,
2460 struct lsa_QueryDomainInformationPolicy *r)
2462 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2466 lsa_SetDomInfoPolicy
2468 static NTSTATUS lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2469 TALLOC_CTX *mem_ctx,
2470 struct lsa_SetDomainInformationPolicy *r)
2472 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2478 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
2479 TALLOC_CTX *mem_ctx,
2480 struct lsa_TestCall *r)
2482 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2486 lookup a SID for 1 name
2488 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
2489 const char *name, struct dom_sid **sid, uint32_t *atype)
2492 struct ldb_message **res;
2493 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
2496 p = strchr_m(name, '\\');
2498 /* TODO: properly parse the domain prefix here, and use it to
2503 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", ldb_binary_encode_string(mem_ctx, name));
2505 *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
2507 return NT_STATUS_INVALID_SID;
2510 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
2512 return NT_STATUS_OK;
2515 /* need to add a call into sidmap to check for a allocated sid */
2517 return NT_STATUS_INVALID_SID;
2524 static NTSTATUS lsa_LookupNames4(struct dcesrv_call_state *dce_call,
2525 TALLOC_CTX *mem_ctx,
2526 struct lsa_LookupNames4 *r)
2528 struct lsa_policy_state *state;
2530 NTSTATUS status = NT_STATUS_OK;
2532 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
2533 if (!NT_STATUS_IS_OK(status)) {
2537 r->out.domains = NULL;
2539 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
2540 if (r->out.domains == NULL) {
2541 return NT_STATUS_NO_MEMORY;
2544 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
2545 if (r->out.sids == NULL) {
2546 return NT_STATUS_NO_MEMORY;
2551 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3,
2553 if (r->out.sids->sids == NULL) {
2554 return NT_STATUS_NO_MEMORY;
2557 for (i=0;i<r->in.num_names;i++) {
2558 const char *name = r->in.names[i].string;
2559 struct dom_sid *sid;
2560 uint32_t atype, rtype, sid_index;
2563 r->out.sids->count++;
2566 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
2567 r->out.sids->sids[i].sid = NULL;
2568 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
2569 r->out.sids->sids[i].unknown = 0;
2571 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
2572 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
2573 status = STATUS_SOME_UNMAPPED;
2577 rtype = samdb_atype_map(atype);
2578 if (rtype == SID_NAME_UNKNOWN) {
2579 status = STATUS_SOME_UNMAPPED;
2583 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
2584 if (!NT_STATUS_IS_OK(status2)) {
2588 r->out.sids->sids[i].sid_type = rtype;
2589 r->out.sids->sids[i].sid = sid;
2590 r->out.sids->sids[i].sid_index = sid_index;
2591 r->out.sids->sids[i].unknown = 0;
2600 static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2601 struct lsa_LookupNames3 *r)
2603 struct lsa_LookupNames4 r2;
2605 struct dcesrv_handle *h;
2606 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2608 r2.in.num_names = r->in.num_names;
2609 r2.in.names = r->in.names;
2610 r2.in.sids = r->in.sids;
2611 r2.in.count = r->in.count;
2612 r2.in.unknown1 = r->in.unknown1;
2613 r2.in.unknown2 = r->in.unknown2;
2614 r2.out.domains = r->out.domains;
2615 r2.out.sids = r->out.sids;
2616 r2.out.count = r->out.count;
2618 status = lsa_LookupNames4(dce_call, mem_ctx, &r2);
2619 if (dce_call->fault_code != 0) {
2623 r->out.domains = r2.out.domains;
2624 r->out.sids = r2.out.sids;
2625 r->out.count = r2.out.count;
2632 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
2633 TALLOC_CTX *mem_ctx,
2634 struct lsa_LookupNames2 *r)
2636 struct lsa_policy_state *state;
2637 struct dcesrv_handle *h;
2639 NTSTATUS status = NT_STATUS_OK;
2641 r->out.domains = NULL;
2643 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2647 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
2648 if (r->out.domains == NULL) {
2649 return NT_STATUS_NO_MEMORY;
2652 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray2);
2653 if (r->out.sids == NULL) {
2654 return NT_STATUS_NO_MEMORY;
2659 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2,
2661 if (r->out.sids->sids == NULL) {
2662 return NT_STATUS_NO_MEMORY;
2665 for (i=0;i<r->in.num_names;i++) {
2666 const char *name = r->in.names[i].string;
2667 struct dom_sid *sid;
2668 uint32_t atype, rtype, sid_index;
2671 r->out.sids->count++;
2674 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
2675 r->out.sids->sids[i].rid = 0xFFFFFFFF;
2676 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
2677 r->out.sids->sids[i].unknown = 0;
2679 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
2680 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
2681 status = STATUS_SOME_UNMAPPED;
2685 rtype = samdb_atype_map(atype);
2686 if (rtype == SID_NAME_UNKNOWN) {
2687 status = STATUS_SOME_UNMAPPED;
2691 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
2692 if (!NT_STATUS_IS_OK(status2)) {
2696 r->out.sids->sids[i].sid_type = rtype;
2697 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
2698 r->out.sids->sids[i].sid_index = sid_index;
2699 r->out.sids->sids[i].unknown = 0;
2708 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2709 struct lsa_LookupNames *r)
2711 struct lsa_LookupNames2 r2;
2715 r2.in.handle = r->in.handle;
2716 r2.in.num_names = r->in.num_names;
2717 r2.in.names = r->in.names;
2719 r2.in.level = r->in.level;
2720 r2.in.count = r->in.count;
2723 r2.out.count = r->out.count;
2725 status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
2726 if (dce_call->fault_code != 0) {
2730 r->out.domains = r2.out.domains;
2731 r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
2732 if (r->out.sids == NULL) {
2733 return NT_STATUS_NO_MEMORY;
2735 r->out.sids->count = r2.out.sids->count;
2736 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid,
2737 r->out.sids->count);
2738 if (r->out.sids->sids == NULL) {
2739 return NT_STATUS_NO_MEMORY;
2741 for (i=0;i<r->out.sids->count;i++) {
2742 r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type;
2743 r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid;
2744 r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index;
2753 static NTSTATUS lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2754 struct lsa_CREDRWRITE *r)
2756 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2763 static NTSTATUS lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2764 struct lsa_CREDRREAD *r)
2766 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2773 static NTSTATUS lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2774 struct lsa_CREDRENUMERATE *r)
2776 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2781 lsa_CREDRWRITEDOMAINCREDENTIALS
2783 static NTSTATUS lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2784 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2786 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2791 lsa_CREDRREADDOMAINCREDENTIALS
2793 static NTSTATUS lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2794 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2796 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2803 static NTSTATUS lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2804 struct lsa_CREDRDELETE *r)
2806 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2811 lsa_CREDRGETTARGETINFO
2813 static NTSTATUS lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2814 struct lsa_CREDRGETTARGETINFO *r)
2816 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2821 lsa_CREDRPROFILELOADED
2823 static NTSTATUS lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2824 struct lsa_CREDRPROFILELOADED *r)
2826 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2831 lsa_CREDRGETSESSIONTYPES
2833 static NTSTATUS lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2834 struct lsa_CREDRGETSESSIONTYPES *r)
2836 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2841 lsa_LSARREGISTERAUDITEVENT
2843 static NTSTATUS lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2844 struct lsa_LSARREGISTERAUDITEVENT *r)
2846 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2851 lsa_LSARGENAUDITEVENT
2853 static NTSTATUS lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2854 struct lsa_LSARGENAUDITEVENT *r)
2856 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2861 lsa_LSARUNREGISTERAUDITEVENT
2863 static NTSTATUS lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2864 struct lsa_LSARUNREGISTERAUDITEVENT *r)
2866 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2871 lsa_LSARQUERYFORESTTRUSTINFORMATION
2873 static NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2874 struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
2876 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2881 lsa_LSARSETFORESTTRUSTINFORMATION
2883 static NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2884 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2886 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2893 static NTSTATUS lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2894 struct lsa_CREDRRENAME *r)
2896 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2902 lsa_LSAROPENPOLICYSCE
2904 static NTSTATUS lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2905 struct lsa_LSAROPENPOLICYSCE *r)
2907 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2912 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
2914 static NTSTATUS lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2915 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2917 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2922 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
2924 static NTSTATUS lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2925 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2927 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2932 lsa_LSARADTREPORTSECURITYEVENT
2934 static NTSTATUS lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2935 struct lsa_LSARADTREPORTSECURITYEVENT *r)
2937 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2941 /* include the generated boilerplate */
2942 #include "librpc/gen_ndr/ndr_lsa_s.c"