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 "rpc_server/dcerpc_server.h"
26 #include "rpc_server/common/common.h"
27 #include "auth/auth.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "libcli/ldap/ldap.h"
30 #include "lib/ldb/include/ldb_errors.h"
31 #include "libcli/security/security.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "passdb/secrets.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;
74 state associated with a lsa_OpenSecret() operation
76 struct lsa_secret_state {
77 struct lsa_policy_state *policy;
79 const struct ldb_dn *secret_dn;
80 struct ldb_context *sam_ldb;
85 state associated with a lsa_OpenTrustedDomain() operation
87 struct lsa_trusted_domain_state {
88 struct lsa_policy_state *policy;
90 const struct ldb_dn *trusted_domain_dn;
93 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
95 struct lsa_EnumAccountRights *r);
97 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
99 struct lsa_policy_state *state,
102 const struct lsa_RightSet *rights);
107 static NTSTATUS lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
110 struct dcesrv_handle *h;
112 *r->out.handle = *r->in.handle;
114 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
118 ZERO_STRUCTP(r->out.handle);
127 static NTSTATUS lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
128 struct lsa_Delete *r)
130 struct dcesrv_handle *h;
133 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
134 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
135 struct lsa_secret_state *secret_state = h->data;
136 ret = samdb_delete(secret_state->sam_ldb, mem_ctx, secret_state->secret_dn);
139 return NT_STATUS_INVALID_HANDLE;
143 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
144 struct lsa_trusted_domain_state *trusted_domain_state = h->data;
145 ret = samdb_delete(trusted_domain_state->policy->sam_ldb, mem_ctx,
146 trusted_domain_state->trusted_domain_dn);
149 return NT_STATUS_INVALID_HANDLE;
153 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
154 struct lsa_RightSet *rights;
155 struct lsa_account_state *astate;
156 struct lsa_EnumAccountRights r2;
159 rights = talloc(mem_ctx, struct lsa_RightSet);
161 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
165 r2.in.handle = &astate->policy->handle->wire_handle;
166 r2.in.sid = astate->account_sid;
167 r2.out.rights = rights;
169 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
170 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
174 if (!NT_STATUS_IS_OK(status)) {
178 status = lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
179 LDB_FLAG_MOD_DELETE, astate->account_sid,
181 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
185 if (!NT_STATUS_IS_OK(status)) {
190 return NT_STATUS_INVALID_HANDLE;
197 static NTSTATUS lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
198 struct lsa_EnumPrivs *r)
200 struct dcesrv_handle *h;
201 struct lsa_policy_state *state;
203 const char *privname;
205 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
209 i = *r->in.resume_handle;
212 while ((privname = sec_privilege_name(i)) &&
213 r->out.privs->count < r->in.max_count) {
214 struct lsa_PrivEntry *e;
216 r->out.privs->privs = talloc_realloc(r->out.privs,
218 struct lsa_PrivEntry,
219 r->out.privs->count+1);
220 if (r->out.privs->privs == NULL) {
221 return NT_STATUS_NO_MEMORY;
223 e = &r->out.privs->privs[r->out.privs->count];
226 e->name.string = privname;
227 r->out.privs->count++;
231 *r->out.resume_handle = i;
240 static NTSTATUS lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
241 struct lsa_QuerySecurity *r)
243 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
250 static NTSTATUS lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
251 struct lsa_SetSecObj *r)
253 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
260 static NTSTATUS lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
261 struct lsa_ChangePassword *r)
263 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
266 static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
267 struct lsa_policy_state **_state)
269 struct lsa_policy_state *state;
270 const struct ldb_dn *partitions_basedn = ldb_dn_string_compose(mem_ctx, samdb_base_dn(mem_ctx), "CN=Partitions,CN=Configuration");
272 state = talloc(mem_ctx, struct lsa_policy_state);
274 return NT_STATUS_NO_MEMORY;
277 /* make sure the sam database is accessible */
278 state->sam_ldb = samdb_connect(state, dce_call->conn->auth_state.session_info);
279 if (state->sam_ldb == NULL) {
280 return NT_STATUS_INVALID_SYSTEM_SERVICE;
283 state->sidmap = sidmap_open(state);
284 if (state->sidmap == NULL) {
285 return NT_STATUS_INVALID_SYSTEM_SERVICE;
288 /* work out the domain_dn - useful for so many calls its worth
290 state->domain_dn = samdb_base_dn(state);
291 if (!state->domain_dn) {
292 return NT_STATUS_NO_MEMORY;
296 = samdb_search_string(state->sam_ldb, state, partitions_basedn, "nETBIOSName",
297 "(&(objectclass=crossRef)(ncName=%s))", ldb_dn_linearize(mem_ctx, state->domain_dn));
299 if (!state->domain_name) {
300 return NT_STATUS_NO_SUCH_DOMAIN;
302 talloc_steal(state, state->domain_name);
304 /* work out the builtin_dn - useful for so many calls its worth
306 state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
307 if (!state->builtin_dn) {
308 return NT_STATUS_NO_SUCH_DOMAIN;
311 /* work out the system_dn - useful for so many calls its worth
313 state->system_dn = samdb_search_dn(state->sam_ldb, state,
314 state->domain_dn, "(&(objectClass=container)(cn=System))");
315 if (!state->system_dn) {
316 return NT_STATUS_NO_SUCH_DOMAIN;
319 state->domain_sid = samdb_search_dom_sid(state->sam_ldb, state,
320 state->domain_dn, "objectSid", NULL);
321 if (!state->domain_sid) {
322 return NT_STATUS_NO_SUCH_DOMAIN;
325 talloc_steal(state, state->domain_sid);
327 state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
328 if (!state->builtin_sid) {
329 return NT_STATUS_NO_SUCH_DOMAIN;
340 static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
341 struct lsa_OpenPolicy2 *r)
344 struct lsa_policy_state *state;
345 struct dcesrv_handle *handle;
347 ZERO_STRUCTP(r->out.handle);
349 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
350 if (!NT_STATUS_IS_OK(status)) {
354 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
356 return NT_STATUS_NO_MEMORY;
359 handle->data = talloc_steal(handle, state);
361 state->access_mask = r->in.access_mask;
362 state->handle = handle;
363 *r->out.handle = handle->wire_handle;
365 /* note that we have completely ignored the attr element of
366 the OpenPolicy. As far as I can tell, this is what w2k3
374 a wrapper around lsa_OpenPolicy2
376 static NTSTATUS lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
377 struct lsa_OpenPolicy *r)
379 struct lsa_OpenPolicy2 r2;
381 r2.in.system_name = NULL;
382 r2.in.attr = r->in.attr;
383 r2.in.access_mask = r->in.access_mask;
384 r2.out.handle = r->out.handle;
386 return lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
393 fill in the AccountDomain info
395 static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
396 struct lsa_DomainInfo *info)
398 info->name.string = state->domain_name;
399 info->sid = state->domain_sid;
405 fill in the DNS domain info
407 static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
408 struct lsa_DnsDomainInfo *info)
410 const char * const attrs[] = { "dnsDomain", "objectGUID", "objectSid", NULL };
412 struct ldb_message **res;
414 ret = gendb_search_dn(state->sam_ldb, mem_ctx, state->domain_dn, &res, attrs);
416 return NT_STATUS_INTERNAL_DB_CORRUPTION;
419 info->name.string = state->domain_name;
420 info->sid = state->domain_sid;
421 info->dns_domain.string = samdb_result_string(res[0], "dnsDomain", NULL);
422 info->dns_forest.string = samdb_result_string(res[0], "dnsDomain", NULL);
423 info->domain_guid = samdb_result_guid(res[0], "objectGUID");
431 static NTSTATUS lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
432 struct lsa_QueryInfoPolicy2 *r)
434 struct lsa_policy_state *state;
435 struct dcesrv_handle *h;
439 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
443 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
445 return NT_STATUS_NO_MEMORY;
448 ZERO_STRUCTP(r->out.info);
450 switch (r->in.level) {
451 case LSA_POLICY_INFO_DOMAIN:
452 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
453 return lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
455 case LSA_POLICY_INFO_DNS:
456 return lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
459 return NT_STATUS_INVALID_INFO_CLASS;
465 static NTSTATUS lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
466 struct lsa_QueryInfoPolicy *r)
468 struct lsa_QueryInfoPolicy2 r2;
471 r2.in.handle = r->in.handle;
472 r2.in.level = r->in.level;
474 status = lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
476 r->out.info = r2.out.info;
484 static NTSTATUS lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
485 struct lsa_SetInfoPolicy *r)
487 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
494 static NTSTATUS lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
495 struct lsa_ClearAuditLog *r)
497 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
504 static NTSTATUS lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
505 struct lsa_CreateAccount *r)
507 struct lsa_account_state *astate;
509 struct lsa_policy_state *state;
510 struct dcesrv_handle *h, *ah;
512 ZERO_STRUCTP(r->out.acct_handle);
514 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
518 astate = talloc(dce_call->conn, struct lsa_account_state);
519 if (astate == NULL) {
520 return NT_STATUS_NO_MEMORY;
523 astate->account_sid = dom_sid_dup(astate, r->in.sid);
524 if (astate->account_sid == NULL) {
526 return NT_STATUS_NO_MEMORY;
529 astate->policy = talloc_reference(astate, state);
530 astate->access_mask = r->in.access_mask;
532 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
535 return NT_STATUS_NO_MEMORY;
538 ah->data = talloc_steal(ah, astate);
540 *r->out.acct_handle = ah->wire_handle;
549 static NTSTATUS lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
550 struct lsa_EnumAccounts *r)
552 struct dcesrv_handle *h;
553 struct lsa_policy_state *state;
555 struct ldb_message **res;
556 const char * const attrs[] = { "objectSid", NULL};
559 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
563 /* NOTE: This call must only return accounts that have at least
566 ret = gendb_search(state->sam_ldb, mem_ctx, samdb_base_dn(mem_ctx), &res, attrs,
567 "(&(objectSid=*)(privilege=*))");
569 return NT_STATUS_NO_SUCH_USER;
572 if (*r->in.resume_handle >= ret) {
573 return NT_STATUS_NO_MORE_ENTRIES;
576 count = ret - *r->in.resume_handle;
577 if (count > r->in.num_entries) {
578 count = r->in.num_entries;
582 return NT_STATUS_NO_MORE_ENTRIES;
585 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
586 if (r->out.sids->sids == NULL) {
587 return NT_STATUS_NO_MEMORY;
590 for (i=0;i<count;i++) {
591 r->out.sids->sids[i].sid =
592 samdb_result_dom_sid(r->out.sids->sids,
593 res[i + *r->in.resume_handle],
595 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
598 r->out.sids->num_sids = count;
599 *r->out.resume_handle = count + *r->in.resume_handle;
607 lsa_CreateTrustedDomainEx2
609 static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
611 struct lsa_CreateTrustedDomainEx2 *r)
613 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
617 lsa_CreateTrustedDomainEx
619 static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
621 struct lsa_CreateTrustedDomainEx *r)
623 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
627 lsa_CreateTrustedDomain
629 static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
630 struct lsa_CreateTrustedDomain *r)
632 struct dcesrv_handle *policy_handle;
633 struct lsa_policy_state *policy_state;
634 struct lsa_trusted_domain_state *trusted_domain_state;
635 struct dcesrv_handle *handle;
636 struct ldb_message **msgs, *msg;
637 const char *attrs[] = {
643 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
644 ZERO_STRUCTP(r->out.trustdom_handle);
646 policy_state = policy_handle->data;
648 if (!r->in.info->name.string) {
649 return NT_STATUS_INVALID_PARAMETER;
651 name = r->in.info->name.string;
653 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
654 if (!trusted_domain_state) {
655 return NT_STATUS_NO_MEMORY;
657 trusted_domain_state->policy = policy_state;
659 msg = ldb_msg_new(mem_ctx);
661 return NT_STATUS_NO_MEMORY;
664 /* search for the trusted_domain record */
665 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
666 mem_ctx, policy_state->system_dn, &msgs, attrs,
667 "(&(cn=%s)(objectclass=trustedDomain))",
668 ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
670 return NT_STATUS_OBJECT_NAME_COLLISION;
673 if (ret < 0 || ret > 1) {
674 DEBUG(0,("Found %d records matching DN %s\n", ret,
675 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
676 return NT_STATUS_INTERNAL_DB_CORRUPTION;
679 msg->dn = ldb_dn_build_child(mem_ctx, "cn",
680 r->in.info->name.string,
681 policy_state->system_dn);
683 return NT_STATUS_NO_MEMORY;
686 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "cn", name);
687 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
689 if (r->in.info->sid) {
690 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
692 return NT_STATUS_NO_MEMORY;
695 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
698 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
700 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
702 /* create the trusted_domain */
703 ret = samdb_add(trusted_domain_state->policy->sam_ldb, mem_ctx, msg);
705 DEBUG(0,("Failed to create trusted_domain record %s\n",
706 ldb_dn_linearize(mem_ctx, msg->dn)));
707 return NT_STATUS_INTERNAL_DB_CORRUPTION;
710 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
712 return NT_STATUS_NO_MEMORY;
715 handle->data = talloc_steal(handle, trusted_domain_state);
717 trusted_domain_state->access_mask = r->in.access_mask;
718 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
720 *r->out.trustdom_handle = handle->wire_handle;
726 lsa_OpenTrustedDomain
728 static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
729 struct lsa_OpenTrustedDomain *r)
731 struct dcesrv_handle *policy_handle;
733 struct lsa_policy_state *policy_state;
734 struct lsa_trusted_domain_state *trusted_domain_state;
735 struct dcesrv_handle *handle;
736 struct ldb_message **msgs;
737 const char *attrs[] = {
741 const char *sid_string;
744 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
745 ZERO_STRUCTP(r->out.trustdom_handle);
746 policy_state = policy_handle->data;
748 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
749 if (!trusted_domain_state) {
750 return NT_STATUS_NO_MEMORY;
752 trusted_domain_state->policy = policy_state;
754 sid_string = dom_sid_string(mem_ctx, r->in.sid);
756 return NT_STATUS_NO_MEMORY;
759 /* search for the trusted_domain record */
760 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
761 mem_ctx, policy_state->system_dn, &msgs, attrs,
762 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
765 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
769 DEBUG(0,("Found %d records matching DN %s\n", ret,
770 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
771 return NT_STATUS_INTERNAL_DB_CORRUPTION;
774 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
776 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
778 return NT_STATUS_NO_MEMORY;
781 handle->data = talloc_steal(handle, trusted_domain_state);
783 trusted_domain_state->access_mask = r->in.access_mask;
784 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
786 *r->out.trustdom_handle = handle->wire_handle;
793 lsa_OpenTrustedDomainByName
795 static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
797 struct lsa_OpenTrustedDomainByName *r)
799 struct dcesrv_handle *policy_handle;
801 struct lsa_policy_state *policy_state;
802 struct lsa_trusted_domain_state *trusted_domain_state;
803 struct dcesrv_handle *handle;
804 struct ldb_message **msgs;
805 const char *attrs[] = {
811 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
812 ZERO_STRUCTP(r->out.trustdom_handle);
813 policy_state = policy_handle->data;
815 if (!r->in.name.string) {
816 return NT_STATUS_INVALID_PARAMETER;
819 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
820 if (!trusted_domain_state) {
821 return NT_STATUS_NO_MEMORY;
823 trusted_domain_state->policy = policy_state;
825 /* search for the trusted_domain record */
826 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
827 mem_ctx, policy_state->system_dn, &msgs, attrs,
828 "(&(flatname=%s)(objectclass=trustedDomain))",
829 ldb_binary_encode_string(mem_ctx, r->in.name.string));
831 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
835 DEBUG(0,("Found %d records matching DN %s\n", ret,
836 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
837 return NT_STATUS_INTERNAL_DB_CORRUPTION;
840 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
842 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
844 return NT_STATUS_NO_MEMORY;
847 handle->data = talloc_steal(handle, trusted_domain_state);
849 trusted_domain_state->access_mask = r->in.access_mask;
850 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
852 *r->out.trustdom_handle = handle->wire_handle;
859 lsa_QueryTrustedDomainInfoBySid
861 static NTSTATUS lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
862 struct lsa_QueryTrustedDomainInfoBySid *r)
864 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
869 lsa_SetTrustDomainInfo
871 static NTSTATUS lsa_SetTrustDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
872 struct lsa_SetTrustDomainInfo *r)
874 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
879 lsa_DeleteTrustDomain
881 static NTSTATUS lsa_DeleteTrustDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
882 struct lsa_DeleteTrustDomain *r)
884 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
889 lsa_QueryTrustedDomainInfo
891 static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
892 struct lsa_QueryTrustedDomainInfo *r)
894 struct dcesrv_handle *h;
895 struct lsa_trusted_domain_state *trusted_domain_state;
896 struct ldb_message *msg;
898 struct ldb_message **res;
899 const char *attrs[] = {
903 "securityIdentifier",
907 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
909 trusted_domain_state = h->data;
911 /* pull all the user attributes */
912 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
913 trusted_domain_state->trusted_domain_dn, &res, attrs);
915 return NT_STATUS_INTERNAL_DB_CORRUPTION;
919 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
921 return NT_STATUS_NO_MEMORY;
923 switch (r->in.level) {
924 case LSA_TRUSTED_DOMAIN_INFO_NAME:
925 r->out.info->name.netbios_name.string
926 = samdb_result_string(msg, "flatname", NULL);
928 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
929 r->out.info->posix_offset.posix_offset
930 = samdb_result_uint(msg, "posixOffset", 0);
933 /* oops, we don't want to return the info after all */
934 talloc_free(r->out.info);
936 return NT_STATUS_INVALID_INFO_CLASS;
944 lsa_SetInformationTrustedDomain
946 static NTSTATUS lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
947 struct lsa_SetInformationTrustedDomain *r)
949 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
954 lsa_QueryTrustedDomainInfoByName
956 static NTSTATUS lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
958 struct lsa_QueryTrustedDomainInfoByName *r)
960 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
964 lsa_SetTrustedDomainInfoByName
966 static NTSTATUS lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
968 struct lsa_SetTrustedDomainInfoByName *r)
970 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
974 lsa_EnumTrustedDomainsEx
976 static NTSTATUS lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call,
978 struct lsa_EnumTrustedDomainsEx *r)
980 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
984 lsa_CloseTrustedDomainEx
986 static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
988 struct lsa_CloseTrustedDomainEx *r)
990 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
995 comparison function for sorting lsa_DomainInformation array
997 static int compare_DomainInformation(struct lsa_DomainInformation *e1, struct lsa_DomainInformation *e2)
999 return strcasecmp(e1->name.string, e2->name.string);
1005 static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1006 struct lsa_EnumTrustDom *r)
1008 struct dcesrv_handle *policy_handle;
1009 struct lsa_DomainInformation *entries;
1010 struct lsa_policy_state *policy_state;
1011 struct ldb_message **domains;
1012 const char *attrs[] = {
1014 "securityIdentifier",
1021 *r->out.resume_handle = 0;
1023 r->out.domains->domains = NULL;
1024 r->out.domains->count = 0;
1026 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1028 policy_state = policy_handle->data;
1030 /* search for all users in this domain. This could possibly be cached and
1031 resumed based on resume_key */
1032 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1033 "objectclass=trustedDomain");
1035 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1037 if (count == 0 || r->in.max_size == 0) {
1038 return NT_STATUS_OK;
1041 /* convert to lsa_DomainInformation format */
1042 entries = talloc_array(mem_ctx, struct lsa_DomainInformation, count);
1044 return NT_STATUS_NO_MEMORY;
1046 for (i=0;i<count;i++) {
1047 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1048 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1051 /* sort the results by name */
1052 qsort(entries, count, sizeof(struct lsa_DomainInformation),
1053 (comparison_fn_t)compare_DomainInformation);
1055 if (*r->in.resume_handle >= count) {
1056 *r->out.resume_handle = -1;
1058 return NT_STATUS_NO_MORE_ENTRIES;
1061 /* return the rest, limit by max_size. Note that we
1062 use the w2k3 element size value of 60 */
1063 r->out.domains->count = count - *r->in.resume_handle;
1064 r->out.domains->count = MIN(r->out.domains->count,
1065 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1067 r->out.domains->domains = entries + *r->in.resume_handle;
1068 r->out.domains->count = r->out.domains->count;
1070 if (r->out.domains->count < count - *r->in.resume_handle) {
1071 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1072 return STATUS_MORE_ENTRIES;
1075 return NT_STATUS_OK;
1080 return the authority name and authority sid, given a sid
1082 static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
1083 TALLOC_CTX *mem_ctx, struct dom_sid *sid,
1084 const char **authority_name,
1085 struct dom_sid **authority_sid)
1087 if (dom_sid_in_domain(state->domain_sid, sid)) {
1088 *authority_name = state->domain_name;
1089 *authority_sid = state->domain_sid;
1090 return NT_STATUS_OK;
1093 if (dom_sid_in_domain(state->builtin_sid, sid)) {
1094 *authority_name = "BUILTIN";
1095 *authority_sid = state->builtin_sid;
1096 return NT_STATUS_OK;
1099 *authority_sid = dom_sid_dup(mem_ctx, sid);
1100 if (*authority_sid == NULL) {
1101 return NT_STATUS_NO_MEMORY;
1103 (*authority_sid)->num_auths = 0;
1104 *authority_name = dom_sid_string(mem_ctx, *authority_sid);
1105 if (*authority_name == NULL) {
1106 return NT_STATUS_NO_MEMORY;
1109 return NT_STATUS_OK;
1113 add to the lsa_RefDomainList for LookupSids and LookupNames
1115 static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1116 struct dom_sid *sid,
1117 struct lsa_RefDomainList *domains,
1118 uint32_t *sid_index)
1121 const char *authority_name;
1122 struct dom_sid *authority_sid;
1125 /* work out the authority name */
1126 status = lsa_authority_name(state, mem_ctx, sid,
1127 &authority_name, &authority_sid);
1128 if (!NT_STATUS_IS_OK(status)) {
1132 /* see if we've already done this authority name */
1133 for (i=0;i<domains->count;i++) {
1134 if (strcmp(authority_name, domains->domains[i].name.string) == 0) {
1136 return NT_STATUS_OK;
1140 domains->domains = talloc_realloc(domains,
1142 struct lsa_TrustInformation,
1144 if (domains->domains == NULL) {
1145 return NT_STATUS_NO_MEMORY;
1147 domains->domains[i].name.string = authority_name;
1148 domains->domains[i].sid = authority_sid;
1152 return NT_STATUS_OK;
1156 lookup a name for 1 SID
1158 static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1159 struct dom_sid *sid, const char *sid_str,
1160 const char **name, uint32_t *atype)
1163 struct ldb_message **res;
1164 const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "name", NULL};
1167 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1168 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
1170 *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
1172 *name = ldb_msg_find_attr_as_string(res[0], "name", NULL);
1174 *name = talloc_strdup(mem_ctx, sid_str);
1175 NT_STATUS_HAVE_NO_MEMORY(*name);
1179 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
1181 return NT_STATUS_OK;
1184 status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype);
1193 static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
1194 TALLOC_CTX *mem_ctx,
1195 struct lsa_LookupSids3 *r)
1197 struct lsa_policy_state *state;
1199 NTSTATUS status = NT_STATUS_OK;
1201 r->out.domains = NULL;
1203 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
1204 if (!NT_STATUS_IS_OK(status)) {
1208 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
1209 if (r->out.domains == NULL) {
1210 return NT_STATUS_NO_MEMORY;
1213 r->out.names = talloc_zero(mem_ctx, struct lsa_TransNameArray2);
1214 if (r->out.names == NULL) {
1215 return NT_STATUS_NO_MEMORY;
1220 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName2,
1221 r->in.sids->num_sids);
1222 if (r->out.names->names == NULL) {
1223 return NT_STATUS_NO_MEMORY;
1226 for (i=0;i<r->in.sids->num_sids;i++) {
1227 struct dom_sid *sid = r->in.sids->sids[i].sid;
1228 char *sid_str = dom_sid_string(mem_ctx, sid);
1230 uint32_t atype, rtype, sid_index;
1233 r->out.names->count++;
1236 r->out.names->names[i].sid_type = SID_NAME_UNKNOWN;
1237 r->out.names->names[i].name.string = sid_str;
1238 r->out.names->names[i].sid_index = 0xFFFFFFFF;
1239 r->out.names->names[i].unknown = 0;
1241 if (sid_str == NULL) {
1242 r->out.names->names[i].name.string = "(SIDERROR)";
1243 status = STATUS_SOME_UNMAPPED;
1247 /* work out the authority name */
1248 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
1249 if (!NT_STATUS_IS_OK(status2)) {
1253 status2 = lsa_lookup_sid(state, mem_ctx, sid, sid_str,
1255 if (!NT_STATUS_IS_OK(status2)) {
1256 status = STATUS_SOME_UNMAPPED;
1260 rtype = samdb_atype_map(atype);
1261 if (rtype == SID_NAME_UNKNOWN) {
1262 status = STATUS_SOME_UNMAPPED;
1266 r->out.names->names[i].sid_type = rtype;
1267 r->out.names->names[i].name.string = name;
1268 r->out.names->names[i].sid_index = sid_index;
1269 r->out.names->names[i].unknown = 0;
1279 static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
1280 TALLOC_CTX *mem_ctx,
1281 struct lsa_LookupSids2 *r)
1283 struct lsa_LookupSids3 r3;
1286 r3.in.sids = r->in.sids;
1287 r3.in.names = r->in.names;
1288 r3.in.level = r->in.level;
1289 r3.in.count = r->in.count;
1290 r3.in.unknown1 = r->in.unknown1;
1291 r3.in.unknown2 = r->in.unknown2;
1292 r3.out.count = r->out.count;
1293 r3.out.names = r->out.names;
1295 status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
1296 if (dce_call->fault_code != 0) {
1300 r->out.domains = r3.out.domains;
1301 r->out.names = r3.out.names;
1302 r->out.count = r3.out.count;
1311 static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1312 struct lsa_LookupSids *r)
1314 struct lsa_LookupSids3 r3;
1318 r3.in.sids = r->in.sids;
1320 r3.in.level = r->in.level;
1321 r3.in.count = r->in.count;
1324 r3.out.count = r->out.count;
1325 r3.out.names = NULL;
1327 status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
1328 if (dce_call->fault_code != 0) {
1332 r->out.domains = r3.out.domains;
1333 if (!r3.out.names) {
1334 r->out.names = NULL;
1338 r->out.names = talloc(mem_ctx, struct lsa_TransNameArray);
1339 if (r->out.names == NULL) {
1340 return NT_STATUS_NO_MEMORY;
1342 r->out.names->count = r3.out.names->count;
1343 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName,
1344 r->out.names->count);
1345 if (r->out.names->names == NULL) {
1346 return NT_STATUS_NO_MEMORY;
1348 for (i=0;i<r->out.names->count;i++) {
1349 r->out.names->names[i].sid_type = r3.out.names->names[i].sid_type;
1350 r->out.names->names[i].name.string = r3.out.names->names[i].name.string;
1351 r->out.names->names[i].sid_index = r3.out.names->names[i].sid_index;
1361 static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1362 struct lsa_OpenAccount *r)
1364 struct dcesrv_handle *h, *ah;
1365 struct lsa_policy_state *state;
1366 struct lsa_account_state *astate;
1368 ZERO_STRUCTP(r->out.acct_handle);
1370 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1374 astate = talloc(dce_call->conn, struct lsa_account_state);
1375 if (astate == NULL) {
1376 return NT_STATUS_NO_MEMORY;
1379 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1380 if (astate->account_sid == NULL) {
1381 talloc_free(astate);
1382 return NT_STATUS_NO_MEMORY;
1385 astate->policy = talloc_reference(astate, state);
1386 astate->access_mask = r->in.access_mask;
1388 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1390 talloc_free(astate);
1391 return NT_STATUS_NO_MEMORY;
1394 ah->data = talloc_steal(ah, astate);
1396 *r->out.acct_handle = ah->wire_handle;
1398 return NT_STATUS_OK;
1403 lsa_EnumPrivsAccount
1405 static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1406 TALLOC_CTX *mem_ctx,
1407 struct lsa_EnumPrivsAccount *r)
1409 struct dcesrv_handle *h;
1410 struct lsa_account_state *astate;
1412 struct ldb_message **res;
1413 const char * const attrs[] = { "privilege", NULL};
1414 struct ldb_message_element *el;
1417 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1421 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1422 r->out.privs->count = 0;
1423 r->out.privs->unknown = 0;
1424 r->out.privs->set = NULL;
1426 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1427 if (sidstr == NULL) {
1428 return NT_STATUS_NO_MEMORY;
1431 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, samdb_base_dn(mem_ctx), &res, attrs,
1432 "objectSid=%s", sidstr);
1434 return NT_STATUS_OK;
1437 el = ldb_msg_find_element(res[0], "privilege");
1438 if (el == NULL || el->num_values == 0) {
1439 return NT_STATUS_OK;
1442 r->out.privs->set = talloc_array(r->out.privs,
1443 struct lsa_LUIDAttribute, el->num_values);
1444 if (r->out.privs->set == NULL) {
1445 return NT_STATUS_NO_MEMORY;
1448 for (i=0;i<el->num_values;i++) {
1449 int id = sec_privilege_id((const char *)el->values[i].data);
1451 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1453 r->out.privs->set[i].attribute = 0;
1454 r->out.privs->set[i].luid.low = id;
1455 r->out.privs->set[i].luid.high = 0;
1458 r->out.privs->count = el->num_values;
1460 return NT_STATUS_OK;
1464 lsa_EnumAccountRights
1466 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1467 TALLOC_CTX *mem_ctx,
1468 struct lsa_EnumAccountRights *r)
1470 struct dcesrv_handle *h;
1471 struct lsa_policy_state *state;
1473 struct ldb_message **res;
1474 const char * const attrs[] = { "privilege", NULL};
1476 struct ldb_message_element *el;
1478 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1482 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1483 if (sidstr == NULL) {
1484 return NT_STATUS_NO_MEMORY;
1487 ret = gendb_search(state->sam_ldb, mem_ctx, samdb_base_dn(mem_ctx), &res, attrs,
1488 "(&(objectSid=%s)(privilege=*))", sidstr);
1490 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1493 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1496 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1497 dom_sid_string(mem_ctx, r->in.sid),
1498 ldb_errstring(state->sam_ldb)));
1499 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1502 el = ldb_msg_find_element(res[0], "privilege");
1503 if (el == NULL || el->num_values == 0) {
1504 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1507 r->out.rights->count = el->num_values;
1508 r->out.rights->names = talloc_array(r->out.rights,
1509 struct lsa_StringLarge, r->out.rights->count);
1510 if (r->out.rights->names == NULL) {
1511 return NT_STATUS_NO_MEMORY;
1514 for (i=0;i<el->num_values;i++) {
1515 r->out.rights->names[i].string = (const char *)el->values[i].data;
1518 return NT_STATUS_OK;
1524 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1526 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1527 TALLOC_CTX *mem_ctx,
1528 struct lsa_policy_state *state,
1530 struct dom_sid *sid,
1531 const struct lsa_RightSet *rights)
1534 struct ldb_message *msg;
1535 struct ldb_message_element *el;
1537 struct lsa_EnumAccountRights r2;
1539 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1540 if (sidstr == NULL) {
1541 return NT_STATUS_NO_MEMORY;
1544 msg = ldb_msg_new(mem_ctx);
1546 return NT_STATUS_NO_MEMORY;
1549 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1550 samdb_base_dn(mem_ctx), "objectSid=%s", sidstr);
1551 if (msg->dn == NULL) {
1553 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1554 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1556 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1558 if (!NT_STATUS_IS_OK(status)) {
1561 return NT_STATUS_NO_SUCH_USER;
1564 if (ldb_msg_add_empty(msg, "privilege", ldb_flag)) {
1565 return NT_STATUS_NO_MEMORY;
1568 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1571 r2.in.handle = &state->handle->wire_handle;
1573 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1575 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1576 if (!NT_STATUS_IS_OK(status)) {
1577 ZERO_STRUCTP(r2.out.rights);
1581 for (i=0;i<rights->count;i++) {
1582 if (sec_privilege_id(rights->names[i].string) == -1) {
1583 return NT_STATUS_NO_SUCH_PRIVILEGE;
1586 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1588 for (j=0;j<r2.out.rights->count;j++) {
1589 if (strcasecmp_m(r2.out.rights->names[j].string,
1590 rights->names[i].string) == 0) {
1594 if (j != r2.out.rights->count) continue;
1597 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1598 if (ret != LDB_SUCCESS) {
1599 return NT_STATUS_NO_MEMORY;
1603 el = ldb_msg_find_element(msg, "privilege");
1605 return NT_STATUS_OK;
1608 ret = samdb_modify(state->sam_ldb, mem_ctx, msg);
1610 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1611 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1613 DEBUG(3, ("Could not %s attributes from %s: %s",
1614 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1615 ldb_dn_linearize(mem_ctx, msg->dn), ldb_errstring(state->sam_ldb)));
1616 return NT_STATUS_UNEXPECTED_IO_ERROR;
1619 return NT_STATUS_OK;
1623 lsa_AddPrivilegesToAccount
1625 static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1626 struct lsa_AddPrivilegesToAccount *r)
1628 struct lsa_RightSet rights;
1629 struct dcesrv_handle *h;
1630 struct lsa_account_state *astate;
1633 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1637 rights.count = r->in.privs->count;
1638 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1639 if (rights.names == NULL) {
1640 return NT_STATUS_NO_MEMORY;
1642 for (i=0;i<rights.count;i++) {
1643 int id = r->in.privs->set[i].luid.low;
1644 if (r->in.privs->set[i].luid.high) {
1645 return NT_STATUS_NO_SUCH_PRIVILEGE;
1647 rights.names[i].string = sec_privilege_name(id);
1648 if (rights.names[i].string == NULL) {
1649 return NT_STATUS_NO_SUCH_PRIVILEGE;
1653 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1654 LDB_FLAG_MOD_ADD, astate->account_sid,
1660 lsa_RemovePrivilegesFromAccount
1662 static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1663 struct lsa_RemovePrivilegesFromAccount *r)
1665 struct lsa_RightSet *rights;
1666 struct dcesrv_handle *h;
1667 struct lsa_account_state *astate;
1670 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1674 rights = talloc(mem_ctx, struct lsa_RightSet);
1676 if (r->in.remove_all == 1 &&
1677 r->in.privs == NULL) {
1678 struct lsa_EnumAccountRights r2;
1681 r2.in.handle = &astate->policy->handle->wire_handle;
1682 r2.in.sid = astate->account_sid;
1683 r2.out.rights = rights;
1685 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1686 if (!NT_STATUS_IS_OK(status)) {
1690 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1691 LDB_FLAG_MOD_DELETE, astate->account_sid,
1695 if (r->in.remove_all != 0) {
1696 return NT_STATUS_INVALID_PARAMETER;
1699 rights->count = r->in.privs->count;
1700 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
1701 if (rights->names == NULL) {
1702 return NT_STATUS_NO_MEMORY;
1704 for (i=0;i<rights->count;i++) {
1705 int id = r->in.privs->set[i].luid.low;
1706 if (r->in.privs->set[i].luid.high) {
1707 return NT_STATUS_NO_SUCH_PRIVILEGE;
1709 rights->names[i].string = sec_privilege_name(id);
1710 if (rights->names[i].string == NULL) {
1711 return NT_STATUS_NO_SUCH_PRIVILEGE;
1715 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
1716 LDB_FLAG_MOD_DELETE, astate->account_sid,
1722 lsa_GetQuotasForAccount
1724 static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1725 struct lsa_GetQuotasForAccount *r)
1727 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1732 lsa_SetQuotasForAccount
1734 static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1735 struct lsa_SetQuotasForAccount *r)
1737 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1742 lsa_GetSystemAccessAccount
1744 static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1745 struct lsa_GetSystemAccessAccount *r)
1747 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1752 lsa_SetSystemAccessAccount
1754 static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1755 struct lsa_SetSystemAccessAccount *r)
1757 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1764 static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1765 struct lsa_CreateSecret *r)
1767 struct dcesrv_handle *policy_handle;
1768 struct lsa_policy_state *policy_state;
1769 struct lsa_secret_state *secret_state;
1770 struct dcesrv_handle *handle;
1771 struct ldb_message **msgs, *msg;
1773 const char *attrs[] = {
1781 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1782 ZERO_STRUCTP(r->out.sec_handle);
1784 policy_state = policy_handle->data;
1786 if (!r->in.name.string) {
1787 return NT_STATUS_INVALID_PARAMETER;
1790 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1791 if (!secret_state) {
1792 return NT_STATUS_NO_MEMORY;
1794 secret_state->policy = policy_state;
1796 msg = ldb_msg_new(mem_ctx);
1798 return NT_STATUS_NO_MEMORY;
1801 if (strncmp("G$", r->in.name.string, 2) == 0) {
1803 name = &r->in.name.string[2];
1804 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1805 secret_state->global = True;
1807 if (strlen(name) < 1) {
1808 return NT_STATUS_INVALID_PARAMETER;
1811 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
1812 /* search for the secret record */
1813 ret = gendb_search(secret_state->sam_ldb,
1814 mem_ctx, policy_state->system_dn, &msgs, attrs,
1815 "(&(cn=%s)(objectclass=secret))",
1818 return NT_STATUS_OBJECT_NAME_COLLISION;
1822 DEBUG(0,("Failure searching for CN=%s: %s\n",
1823 name2, ldb_errstring(secret_state->sam_ldb)));
1824 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1827 msg->dn = ldb_dn_build_child(mem_ctx, "cn", name2, policy_state->system_dn);
1828 if (!name2 || !msg->dn) {
1829 return NT_STATUS_NO_MEMORY;
1832 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
1835 secret_state->global = False;
1837 name = r->in.name.string;
1838 if (strlen(name) < 1) {
1839 return NT_STATUS_INVALID_PARAMETER;
1842 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1843 /* search for the secret record */
1844 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1845 ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
1847 "(&(cn=%s)(objectclass=secret))",
1848 ldb_binary_encode_string(mem_ctx, name));
1850 return NT_STATUS_OBJECT_NAME_COLLISION;
1854 DEBUG(0,("Failure searching for CN=%s: %s\n",
1855 name, ldb_errstring(secret_state->sam_ldb)));
1856 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1859 msg->dn = ldb_dn_string_compose(mem_ctx, NULL, "cn=%s,cn=LSA Secrets", name);
1860 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
1863 /* pull in all the template attributes. Note this is always from the global samdb */
1864 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
1865 "(&(cn=TemplateSecret)(objectclass=secretTemplate))", &errstr);
1867 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
1869 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1872 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
1874 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1876 /* create the secret */
1877 ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
1879 DEBUG(0,("Failed to create secret record %s: %s\n",
1880 ldb_dn_linearize(mem_ctx, msg->dn),
1881 ldb_errstring(secret_state->sam_ldb)));
1882 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1885 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1887 return NT_STATUS_NO_MEMORY;
1890 handle->data = talloc_steal(handle, secret_state);
1892 secret_state->access_mask = r->in.access_mask;
1893 secret_state->policy = talloc_reference(secret_state, policy_state);
1895 *r->out.sec_handle = handle->wire_handle;
1897 return NT_STATUS_OK;
1904 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1905 struct lsa_OpenSecret *r)
1907 struct dcesrv_handle *policy_handle;
1909 struct lsa_policy_state *policy_state;
1910 struct lsa_secret_state *secret_state;
1911 struct dcesrv_handle *handle;
1912 struct ldb_message **msgs;
1913 const char *attrs[] = {
1921 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1922 ZERO_STRUCTP(r->out.sec_handle);
1923 policy_state = policy_handle->data;
1925 if (!r->in.name.string) {
1926 return NT_STATUS_INVALID_PARAMETER;
1929 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1930 if (!secret_state) {
1931 return NT_STATUS_NO_MEMORY;
1933 secret_state->policy = policy_state;
1935 if (strncmp("G$", r->in.name.string, 2) == 0) {
1936 name = &r->in.name.string[2];
1937 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1938 secret_state->global = True;
1940 if (strlen(name) < 1) {
1941 return NT_STATUS_INVALID_PARAMETER;
1944 /* search for the secret record */
1945 ret = gendb_search(secret_state->sam_ldb,
1946 mem_ctx, policy_state->system_dn, &msgs, attrs,
1947 "(&(cn=%s Secret)(objectclass=secret))",
1948 ldb_binary_encode_string(mem_ctx, name));
1950 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1954 DEBUG(0,("Found %d records matching DN %s\n", ret,
1955 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
1956 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1960 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1962 secret_state->global = False;
1963 name = r->in.name.string;
1964 if (strlen(name) < 1) {
1965 return NT_STATUS_INVALID_PARAMETER;
1968 /* search for the secret record */
1969 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1970 ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
1972 "(&(cn=%s)(objectclass=secret))",
1973 ldb_binary_encode_string(mem_ctx, name));
1975 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1979 DEBUG(0,("Found %d records matching DN %s\n", ret,
1980 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
1981 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1985 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1987 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1989 return NT_STATUS_NO_MEMORY;
1992 handle->data = talloc_steal(handle, secret_state);
1994 secret_state->access_mask = r->in.access_mask;
1995 secret_state->policy = talloc_reference(secret_state, policy_state);
1997 *r->out.sec_handle = handle->wire_handle;
1999 return NT_STATUS_OK;
2006 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2007 struct lsa_SetSecret *r)
2010 struct dcesrv_handle *h;
2011 struct lsa_secret_state *secret_state;
2012 struct ldb_message *msg;
2013 DATA_BLOB session_key;
2014 DATA_BLOB crypt_secret, secret;
2017 NTSTATUS status = NT_STATUS_OK;
2019 struct timeval now = timeval_current();
2020 NTTIME nt_now = timeval_to_nttime(&now);
2022 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2024 secret_state = h->data;
2026 msg = ldb_msg_new(mem_ctx);
2028 return NT_STATUS_NO_MEMORY;
2031 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2033 return NT_STATUS_NO_MEMORY;
2035 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2036 if (!NT_STATUS_IS_OK(status)) {
2040 if (r->in.old_val) {
2042 crypt_secret.data = r->in.old_val->data;
2043 crypt_secret.length = r->in.old_val->size;
2045 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2046 if (!NT_STATUS_IS_OK(status)) {
2050 val.data = secret.data;
2051 val.length = secret.length;
2054 if (samdb_msg_add_value(secret_state->sam_ldb,
2055 mem_ctx, msg, "priorSecret", &val) != 0) {
2056 return NT_STATUS_NO_MEMORY;
2059 /* set old value mtime */
2060 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2061 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2062 return NT_STATUS_NO_MEMORY;
2065 if (!r->in.new_val) {
2066 /* This behaviour varies depending of if this is a local, or a global secret... */
2067 if (secret_state->global) {
2068 /* set old value mtime */
2069 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2070 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2071 return NT_STATUS_NO_MEMORY;
2074 if (samdb_msg_add_delete(secret_state->sam_ldb,
2075 mem_ctx, msg, "secret")) {
2076 return NT_STATUS_NO_MEMORY;
2078 if (samdb_msg_add_delete(secret_state->sam_ldb,
2079 mem_ctx, msg, "lastSetTime")) {
2080 return NT_STATUS_NO_MEMORY;
2086 if (r->in.new_val) {
2088 crypt_secret.data = r->in.new_val->data;
2089 crypt_secret.length = r->in.new_val->size;
2091 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2092 if (!NT_STATUS_IS_OK(status)) {
2096 val.data = secret.data;
2097 val.length = secret.length;
2100 if (samdb_msg_add_value(secret_state->sam_ldb,
2101 mem_ctx, msg, "secret", &val) != 0) {
2102 return NT_STATUS_NO_MEMORY;
2105 /* set new value mtime */
2106 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2107 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2108 return NT_STATUS_NO_MEMORY;
2111 /* If the old value is not set, then migrate the
2112 * current value to the old value */
2113 if (!r->in.old_val) {
2114 const struct ldb_val *new_val;
2115 NTTIME last_set_time;
2116 struct ldb_message **res;
2117 const char *attrs[] = {
2123 /* search for the secret record */
2124 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2125 secret_state->secret_dn, &res, attrs);
2127 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2131 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2132 ldb_dn_linearize(mem_ctx, secret_state->secret_dn)));
2133 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2136 new_val = ldb_msg_find_ldb_val(res[0], "secret");
2137 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2141 if (samdb_msg_add_value(secret_state->sam_ldb,
2142 mem_ctx, msg, "priorSecret",
2144 return NT_STATUS_NO_MEMORY;
2148 /* set new value mtime */
2149 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2150 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2151 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2152 return NT_STATUS_NO_MEMORY;
2158 /* modify the samdb record */
2159 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2161 /* we really need samdb.c to return NTSTATUS */
2162 return NT_STATUS_UNSUCCESSFUL;
2165 return NT_STATUS_OK;
2172 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2173 struct lsa_QuerySecret *r)
2175 struct dcesrv_handle *h;
2176 struct lsa_secret_state *secret_state;
2177 struct ldb_message *msg;
2178 DATA_BLOB session_key;
2179 DATA_BLOB crypt_secret, secret;
2181 struct ldb_message **res;
2182 const char *attrs[] = {
2192 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2194 secret_state = h->data;
2196 /* pull all the user attributes */
2197 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2198 secret_state->secret_dn, &res, attrs);
2200 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2204 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2205 if (!NT_STATUS_IS_OK(nt_status)) {
2209 if (r->in.old_val) {
2210 const struct ldb_val *prior_val;
2211 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2212 if (!r->out.old_val) {
2213 return NT_STATUS_NO_MEMORY;
2216 prior_val = ldb_msg_find_ldb_val(res[0], "priorSecret");
2218 if (prior_val && prior_val->length) {
2219 secret.data = prior_val->data;
2220 secret.length = prior_val->length;
2222 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2223 if (!crypt_secret.length) {
2224 return NT_STATUS_NO_MEMORY;
2226 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2227 if (!r->out.old_val->buf) {
2228 return NT_STATUS_NO_MEMORY;
2230 r->out.old_val->buf->size = crypt_secret.length;
2231 r->out.old_val->buf->length = crypt_secret.length;
2232 r->out.old_val->buf->data = crypt_secret.data;
2236 if (r->in.old_mtime) {
2237 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2238 if (!r->out.old_mtime) {
2239 return NT_STATUS_NO_MEMORY;
2241 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2244 if (r->in.new_val) {
2245 const struct ldb_val *new_val;
2246 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2247 if (!r->out.new_val) {
2248 return NT_STATUS_NO_MEMORY;
2252 new_val = ldb_msg_find_ldb_val(res[0], "secret");
2254 if (new_val && new_val->length) {
2255 secret.data = new_val->data;
2256 secret.length = new_val->length;
2258 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2259 if (!crypt_secret.length) {
2260 return NT_STATUS_NO_MEMORY;
2262 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2263 if (!r->out.new_val->buf) {
2264 return NT_STATUS_NO_MEMORY;
2266 r->out.new_val->buf->length = crypt_secret.length;
2267 r->out.new_val->buf->size = crypt_secret.length;
2268 r->out.new_val->buf->data = crypt_secret.data;
2272 if (r->in.new_mtime) {
2273 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2274 if (!r->out.new_mtime) {
2275 return NT_STATUS_NO_MEMORY;
2277 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2280 return NT_STATUS_OK;
2287 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2288 TALLOC_CTX *mem_ctx,
2289 struct lsa_LookupPrivValue *r)
2291 struct dcesrv_handle *h;
2292 struct lsa_policy_state *state;
2295 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2299 id = sec_privilege_id(r->in.name->string);
2301 return NT_STATUS_NO_SUCH_PRIVILEGE;
2304 r->out.luid->low = id;
2305 r->out.luid->high = 0;
2307 return NT_STATUS_OK;
2314 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2315 TALLOC_CTX *mem_ctx,
2316 struct lsa_LookupPrivName *r)
2318 struct dcesrv_handle *h;
2319 struct lsa_policy_state *state;
2320 const char *privname;
2322 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2326 if (r->in.luid->high != 0) {
2327 return NT_STATUS_NO_SUCH_PRIVILEGE;
2330 privname = sec_privilege_name(r->in.luid->low);
2331 if (privname == NULL) {
2332 return NT_STATUS_NO_SUCH_PRIVILEGE;
2335 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2336 if (r->out.name == NULL) {
2337 return NT_STATUS_NO_MEMORY;
2339 r->out.name->string = privname;
2341 return NT_STATUS_OK;
2346 lsa_LookupPrivDisplayName
2348 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2349 TALLOC_CTX *mem_ctx,
2350 struct lsa_LookupPrivDisplayName *r)
2352 struct dcesrv_handle *h;
2353 struct lsa_policy_state *state;
2356 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2360 id = sec_privilege_id(r->in.name->string);
2362 return NT_STATUS_NO_SUCH_PRIVILEGE;
2365 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2366 if (r->out.disp_name == NULL) {
2367 return NT_STATUS_NO_MEMORY;
2370 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2371 if (r->out.disp_name->string == NULL) {
2372 return NT_STATUS_INTERNAL_ERROR;
2375 return NT_STATUS_OK;
2382 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2383 struct lsa_DeleteObject *r)
2385 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2390 lsa_EnumAccountsWithUserRight
2392 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2393 TALLOC_CTX *mem_ctx,
2394 struct lsa_EnumAccountsWithUserRight *r)
2396 struct dcesrv_handle *h;
2397 struct lsa_policy_state *state;
2399 struct ldb_message **res;
2400 const char * const attrs[] = { "objectSid", NULL};
2401 const char *privname;
2403 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2407 if (r->in.name == NULL) {
2408 return NT_STATUS_NO_SUCH_PRIVILEGE;
2411 privname = r->in.name->string;
2412 if (sec_privilege_id(privname) == -1) {
2413 return NT_STATUS_NO_SUCH_PRIVILEGE;
2416 ret = gendb_search(state->sam_ldb, mem_ctx, samdb_base_dn(mem_ctx), &res, attrs,
2417 "privilege=%s", privname);
2419 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2422 return NT_STATUS_NO_MORE_ENTRIES;
2425 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2426 if (r->out.sids->sids == NULL) {
2427 return NT_STATUS_NO_MEMORY;
2429 for (i=0;i<ret;i++) {
2430 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2431 res[i], "objectSid");
2432 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2434 r->out.sids->num_sids = ret;
2436 return NT_STATUS_OK;
2441 lsa_AddAccountRights
2443 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2444 TALLOC_CTX *mem_ctx,
2445 struct lsa_AddAccountRights *r)
2447 struct dcesrv_handle *h;
2448 struct lsa_policy_state *state;
2450 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2454 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2456 r->in.sid, r->in.rights);
2461 lsa_RemoveAccountRights
2463 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2464 TALLOC_CTX *mem_ctx,
2465 struct lsa_RemoveAccountRights *r)
2467 struct dcesrv_handle *h;
2468 struct lsa_policy_state *state;
2470 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2474 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2475 LDB_FLAG_MOD_DELETE,
2476 r->in.sid, r->in.rights);
2481 lsa_StorePrivateData
2483 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2484 struct lsa_StorePrivateData *r)
2486 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2491 lsa_RetrievePrivateData
2493 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2494 struct lsa_RetrievePrivateData *r)
2496 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2503 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2504 struct lsa_GetUserName *r)
2506 NTSTATUS status = NT_STATUS_OK;
2507 const char *account_name;
2508 const char *authority_name;
2509 struct lsa_String *_account_name;
2510 struct lsa_StringPointer *_authority_name = NULL;
2512 /* this is what w2k3 does */
2513 r->out.account_name = r->in.account_name;
2514 r->out.authority_name = r->in.authority_name;
2516 if (r->in.account_name && r->in.account_name->string) {
2517 return NT_STATUS_INVALID_PARAMETER;
2520 if (r->in.authority_name &&
2521 r->in.authority_name->string &&
2522 r->in.authority_name->string->string) {
2523 return NT_STATUS_INVALID_PARAMETER;
2526 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2527 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2529 _account_name = talloc(mem_ctx, struct lsa_String);
2530 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2531 _account_name->string = account_name;
2533 if (r->in.authority_name) {
2534 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2535 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2536 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2537 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2538 _authority_name->string->string = authority_name;
2541 r->out.account_name = _account_name;
2542 r->out.authority_name = _authority_name;
2550 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2551 TALLOC_CTX *mem_ctx,
2552 struct lsa_SetInfoPolicy2 *r)
2554 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2558 lsa_QueryDomainInformationPolicy
2560 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2561 TALLOC_CTX *mem_ctx,
2562 struct lsa_QueryDomainInformationPolicy *r)
2564 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2568 lsa_SetDomInfoPolicy
2570 static NTSTATUS lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2571 TALLOC_CTX *mem_ctx,
2572 struct lsa_SetDomainInformationPolicy *r)
2574 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2580 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
2581 TALLOC_CTX *mem_ctx,
2582 struct lsa_TestCall *r)
2584 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2588 lookup a SID for 1 name
2590 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
2591 const char *name, struct dom_sid **sid, uint32_t *atype)
2594 struct ldb_message **res;
2595 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
2598 p = strchr_m(name, '\\');
2600 /* TODO: properly parse the domain prefix here, and use it to
2605 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", ldb_binary_encode_string(mem_ctx, name));
2607 *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
2609 return NT_STATUS_INVALID_SID;
2612 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
2614 return NT_STATUS_OK;
2617 /* need to add a call into sidmap to check for a allocated sid */
2619 return NT_STATUS_INVALID_SID;
2626 static NTSTATUS lsa_LookupNames4(struct dcesrv_call_state *dce_call,
2627 TALLOC_CTX *mem_ctx,
2628 struct lsa_LookupNames4 *r)
2630 struct lsa_policy_state *state;
2632 NTSTATUS status = NT_STATUS_OK;
2634 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
2635 if (!NT_STATUS_IS_OK(status)) {
2639 r->out.domains = NULL;
2641 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
2642 if (r->out.domains == NULL) {
2643 return NT_STATUS_NO_MEMORY;
2646 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
2647 if (r->out.sids == NULL) {
2648 return NT_STATUS_NO_MEMORY;
2653 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3,
2655 if (r->out.sids->sids == NULL) {
2656 return NT_STATUS_NO_MEMORY;
2659 for (i=0;i<r->in.num_names;i++) {
2660 const char *name = r->in.names[i].string;
2661 struct dom_sid *sid;
2662 uint32_t atype, rtype, sid_index;
2665 r->out.sids->count++;
2668 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
2669 r->out.sids->sids[i].sid = NULL;
2670 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
2671 r->out.sids->sids[i].unknown = 0;
2673 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
2674 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
2675 status = STATUS_SOME_UNMAPPED;
2679 rtype = samdb_atype_map(atype);
2680 if (rtype == SID_NAME_UNKNOWN) {
2681 status = STATUS_SOME_UNMAPPED;
2685 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
2686 if (!NT_STATUS_IS_OK(status2)) {
2690 r->out.sids->sids[i].sid_type = rtype;
2691 r->out.sids->sids[i].sid = sid;
2692 r->out.sids->sids[i].sid_index = sid_index;
2693 r->out.sids->sids[i].unknown = 0;
2702 static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2703 struct lsa_LookupNames3 *r)
2705 struct lsa_LookupNames4 r2;
2707 struct dcesrv_handle *h;
2708 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2710 r2.in.num_names = r->in.num_names;
2711 r2.in.names = r->in.names;
2712 r2.in.sids = r->in.sids;
2713 r2.in.count = r->in.count;
2714 r2.in.unknown1 = r->in.unknown1;
2715 r2.in.unknown2 = r->in.unknown2;
2716 r2.out.domains = r->out.domains;
2717 r2.out.sids = r->out.sids;
2718 r2.out.count = r->out.count;
2720 status = lsa_LookupNames4(dce_call, mem_ctx, &r2);
2721 if (dce_call->fault_code != 0) {
2725 r->out.domains = r2.out.domains;
2726 r->out.sids = r2.out.sids;
2727 r->out.count = r2.out.count;
2734 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
2735 TALLOC_CTX *mem_ctx,
2736 struct lsa_LookupNames2 *r)
2738 struct lsa_policy_state *state;
2739 struct dcesrv_handle *h;
2741 NTSTATUS status = NT_STATUS_OK;
2743 r->out.domains = NULL;
2745 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2749 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
2750 if (r->out.domains == NULL) {
2751 return NT_STATUS_NO_MEMORY;
2754 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray2);
2755 if (r->out.sids == NULL) {
2756 return NT_STATUS_NO_MEMORY;
2761 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2,
2763 if (r->out.sids->sids == NULL) {
2764 return NT_STATUS_NO_MEMORY;
2767 for (i=0;i<r->in.num_names;i++) {
2768 const char *name = r->in.names[i].string;
2769 struct dom_sid *sid;
2770 uint32_t atype, rtype, sid_index;
2773 r->out.sids->count++;
2776 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
2777 r->out.sids->sids[i].rid = 0xFFFFFFFF;
2778 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
2779 r->out.sids->sids[i].unknown = 0;
2781 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
2782 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
2783 status = STATUS_SOME_UNMAPPED;
2787 rtype = samdb_atype_map(atype);
2788 if (rtype == SID_NAME_UNKNOWN) {
2789 status = STATUS_SOME_UNMAPPED;
2793 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
2794 if (!NT_STATUS_IS_OK(status2)) {
2798 r->out.sids->sids[i].sid_type = rtype;
2799 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
2800 r->out.sids->sids[i].sid_index = sid_index;
2801 r->out.sids->sids[i].unknown = 0;
2810 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2811 struct lsa_LookupNames *r)
2813 struct lsa_LookupNames2 r2;
2817 r2.in.handle = r->in.handle;
2818 r2.in.num_names = r->in.num_names;
2819 r2.in.names = r->in.names;
2821 r2.in.level = r->in.level;
2822 r2.in.count = r->in.count;
2825 r2.out.count = r->out.count;
2827 status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
2828 if (dce_call->fault_code != 0) {
2832 r->out.domains = r2.out.domains;
2833 r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
2834 if (r->out.sids == NULL) {
2835 return NT_STATUS_NO_MEMORY;
2837 r->out.sids->count = r2.out.sids->count;
2838 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid,
2839 r->out.sids->count);
2840 if (r->out.sids->sids == NULL) {
2841 return NT_STATUS_NO_MEMORY;
2843 for (i=0;i<r->out.sids->count;i++) {
2844 r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type;
2845 r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid;
2846 r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index;
2855 static NTSTATUS lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2856 struct lsa_CREDRWRITE *r)
2858 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2865 static NTSTATUS lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2866 struct lsa_CREDRREAD *r)
2868 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2875 static NTSTATUS lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2876 struct lsa_CREDRENUMERATE *r)
2878 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2883 lsa_CREDRWRITEDOMAINCREDENTIALS
2885 static NTSTATUS lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2886 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2888 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2893 lsa_CREDRREADDOMAINCREDENTIALS
2895 static NTSTATUS lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2896 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2898 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2905 static NTSTATUS lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2906 struct lsa_CREDRDELETE *r)
2908 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2913 lsa_CREDRGETTARGETINFO
2915 static NTSTATUS lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2916 struct lsa_CREDRGETTARGETINFO *r)
2918 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2923 lsa_CREDRPROFILELOADED
2925 static NTSTATUS lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2926 struct lsa_CREDRPROFILELOADED *r)
2928 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2933 lsa_CREDRGETSESSIONTYPES
2935 static NTSTATUS lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2936 struct lsa_CREDRGETSESSIONTYPES *r)
2938 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2943 lsa_LSARREGISTERAUDITEVENT
2945 static NTSTATUS lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2946 struct lsa_LSARREGISTERAUDITEVENT *r)
2948 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2953 lsa_LSARGENAUDITEVENT
2955 static NTSTATUS lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2956 struct lsa_LSARGENAUDITEVENT *r)
2958 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2963 lsa_LSARUNREGISTERAUDITEVENT
2965 static NTSTATUS lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2966 struct lsa_LSARUNREGISTERAUDITEVENT *r)
2968 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2973 lsa_LSARQUERYFORESTTRUSTINFORMATION
2975 static NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2976 struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
2978 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2983 lsa_LSARSETFORESTTRUSTINFORMATION
2985 static NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2986 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2988 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2995 static NTSTATUS lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2996 struct lsa_CREDRRENAME *r)
2998 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3004 lsa_LSAROPENPOLICYSCE
3006 static NTSTATUS lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3007 struct lsa_LSAROPENPOLICYSCE *r)
3009 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3014 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3016 static NTSTATUS lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3017 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3019 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3024 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3026 static NTSTATUS lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3027 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3029 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3034 lsa_LSARADTREPORTSECURITYEVENT
3036 static NTSTATUS lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3037 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3039 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3043 /* include the generated boilerplate */
3044 #include "librpc/gen_ndr/ndr_lsa_s.c"