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_string(res[0], "sAMAccountName", NULL);
1172 *name = ldb_msg_find_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;
1772 const char *attrs[] = {
1780 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1781 ZERO_STRUCTP(r->out.sec_handle);
1783 policy_state = policy_handle->data;
1785 if (!r->in.name.string) {
1786 return NT_STATUS_INVALID_PARAMETER;
1789 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1790 if (!secret_state) {
1791 return NT_STATUS_NO_MEMORY;
1793 secret_state->policy = policy_state;
1795 msg = ldb_msg_new(mem_ctx);
1797 return NT_STATUS_NO_MEMORY;
1800 if (strncmp("G$", r->in.name.string, 2) == 0) {
1802 name = &r->in.name.string[2];
1803 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1804 secret_state->global = True;
1806 if (strlen(name) < 1) {
1807 return NT_STATUS_INVALID_PARAMETER;
1810 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
1811 /* search for the secret record */
1812 ret = gendb_search(secret_state->sam_ldb,
1813 mem_ctx, policy_state->system_dn, &msgs, attrs,
1814 "(&(cn=%s)(objectclass=secret))",
1817 return NT_STATUS_OBJECT_NAME_COLLISION;
1821 DEBUG(0,("Failure searching for CN=%s: %s\n",
1822 name2, ldb_errstring(secret_state->sam_ldb)));
1823 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1826 msg->dn = ldb_dn_build_child(mem_ctx, "cn", name2, policy_state->system_dn);
1827 if (!name2 || !msg->dn) {
1828 return NT_STATUS_NO_MEMORY;
1831 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
1834 secret_state->global = False;
1836 name = r->in.name.string;
1837 if (strlen(name) < 1) {
1838 return NT_STATUS_INVALID_PARAMETER;
1841 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1842 /* search for the secret record */
1843 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1844 ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
1846 "(&(cn=%s)(objectclass=secret))",
1847 ldb_binary_encode_string(mem_ctx, name));
1849 return NT_STATUS_OBJECT_NAME_COLLISION;
1853 DEBUG(0,("Failure searching for CN=%s: %s\n",
1854 name, ldb_errstring(secret_state->sam_ldb)));
1855 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1858 msg->dn = ldb_dn_string_compose(mem_ctx, NULL, "cn=%s,cn=LSA Secrets", name);
1859 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
1862 /* pull in all the template attributes. Note this is always from the global samdb */
1863 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
1864 "(&(cn=TemplateSecret)(objectclass=secretTemplate))");
1866 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
1867 ldb_errstring(secret_state->policy->sam_ldb)));
1868 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1871 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
1873 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1875 /* create the secret */
1876 ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
1878 DEBUG(0,("Failed to create secret record %s: %s\n",
1879 ldb_dn_linearize(mem_ctx, msg->dn),
1880 ldb_errstring(secret_state->sam_ldb)));
1881 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1884 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1886 return NT_STATUS_NO_MEMORY;
1889 handle->data = talloc_steal(handle, secret_state);
1891 secret_state->access_mask = r->in.access_mask;
1892 secret_state->policy = talloc_reference(secret_state, policy_state);
1894 *r->out.sec_handle = handle->wire_handle;
1896 return NT_STATUS_OK;
1903 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1904 struct lsa_OpenSecret *r)
1906 struct dcesrv_handle *policy_handle;
1908 struct lsa_policy_state *policy_state;
1909 struct lsa_secret_state *secret_state;
1910 struct dcesrv_handle *handle;
1911 struct ldb_message **msgs;
1912 const char *attrs[] = {
1920 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1921 ZERO_STRUCTP(r->out.sec_handle);
1922 policy_state = policy_handle->data;
1924 if (!r->in.name.string) {
1925 return NT_STATUS_INVALID_PARAMETER;
1928 secret_state = talloc(mem_ctx, struct lsa_secret_state);
1929 if (!secret_state) {
1930 return NT_STATUS_NO_MEMORY;
1932 secret_state->policy = policy_state;
1934 if (strncmp("G$", r->in.name.string, 2) == 0) {
1935 name = &r->in.name.string[2];
1936 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1937 secret_state->global = True;
1939 if (strlen(name) < 1) {
1940 return NT_STATUS_INVALID_PARAMETER;
1943 /* search for the secret record */
1944 ret = gendb_search(secret_state->sam_ldb,
1945 mem_ctx, policy_state->system_dn, &msgs, attrs,
1946 "(&(cn=%s Secret)(objectclass=secret))",
1947 ldb_binary_encode_string(mem_ctx, name));
1949 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1953 DEBUG(0,("Found %d records matching DN %s\n", ret,
1954 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
1955 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1959 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1961 secret_state->global = False;
1962 name = r->in.name.string;
1963 if (strlen(name) < 1) {
1964 return NT_STATUS_INVALID_PARAMETER;
1967 /* search for the secret record */
1968 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1969 ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
1971 "(&(cn=%s)(objectclass=secret))",
1972 ldb_binary_encode_string(mem_ctx, name));
1974 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1978 DEBUG(0,("Found %d records matching DN %s\n", ret,
1979 ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
1980 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1984 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1986 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1988 return NT_STATUS_NO_MEMORY;
1991 handle->data = talloc_steal(handle, secret_state);
1993 secret_state->access_mask = r->in.access_mask;
1994 secret_state->policy = talloc_reference(secret_state, policy_state);
1996 *r->out.sec_handle = handle->wire_handle;
1998 return NT_STATUS_OK;
2005 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2006 struct lsa_SetSecret *r)
2009 struct dcesrv_handle *h;
2010 struct lsa_secret_state *secret_state;
2011 struct ldb_message *msg;
2012 DATA_BLOB session_key;
2013 DATA_BLOB crypt_secret, secret;
2016 NTSTATUS status = NT_STATUS_OK;
2018 struct timeval now = timeval_current();
2019 NTTIME nt_now = timeval_to_nttime(&now);
2021 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2023 secret_state = h->data;
2025 msg = ldb_msg_new(mem_ctx);
2027 return NT_STATUS_NO_MEMORY;
2030 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2032 return NT_STATUS_NO_MEMORY;
2034 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2035 if (!NT_STATUS_IS_OK(status)) {
2039 if (r->in.old_val) {
2041 crypt_secret.data = r->in.old_val->data;
2042 crypt_secret.length = r->in.old_val->size;
2044 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2045 if (!NT_STATUS_IS_OK(status)) {
2049 val.data = secret.data;
2050 val.length = secret.length;
2053 if (samdb_msg_add_value(secret_state->sam_ldb,
2054 mem_ctx, msg, "priorSecret", &val) != 0) {
2055 return NT_STATUS_NO_MEMORY;
2058 /* set old value mtime */
2059 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2060 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2061 return NT_STATUS_NO_MEMORY;
2064 if (!r->in.new_val) {
2065 /* This behaviour varies depending of if this is a local, or a global secret... */
2066 if (secret_state->global) {
2067 /* set old value mtime */
2068 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2069 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2070 return NT_STATUS_NO_MEMORY;
2073 if (samdb_msg_add_delete(secret_state->sam_ldb,
2074 mem_ctx, msg, "secret")) {
2075 return NT_STATUS_NO_MEMORY;
2077 if (samdb_msg_add_delete(secret_state->sam_ldb,
2078 mem_ctx, msg, "lastSetTime")) {
2079 return NT_STATUS_NO_MEMORY;
2085 if (r->in.new_val) {
2087 crypt_secret.data = r->in.new_val->data;
2088 crypt_secret.length = r->in.new_val->size;
2090 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2091 if (!NT_STATUS_IS_OK(status)) {
2095 val.data = secret.data;
2096 val.length = secret.length;
2099 if (samdb_msg_add_value(secret_state->sam_ldb,
2100 mem_ctx, msg, "secret", &val) != 0) {
2101 return NT_STATUS_NO_MEMORY;
2104 /* set new value mtime */
2105 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2106 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2107 return NT_STATUS_NO_MEMORY;
2110 /* If the old value is not set, then migrate the
2111 * current value to the old value */
2112 if (!r->in.old_val) {
2113 const struct ldb_val *new_val;
2114 NTTIME last_set_time;
2115 struct ldb_message **res;
2116 const char *attrs[] = {
2122 /* search for the secret record */
2123 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2124 secret_state->secret_dn, &res, attrs);
2126 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2130 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2131 ldb_dn_linearize(mem_ctx, secret_state->secret_dn)));
2132 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2135 new_val = ldb_msg_find_ldb_val(res[0], "secret");
2136 last_set_time = ldb_msg_find_uint64(res[0], "lastSetTime", 0);
2140 if (samdb_msg_add_value(secret_state->sam_ldb,
2141 mem_ctx, msg, "priorSecret",
2143 return NT_STATUS_NO_MEMORY;
2147 /* set new value mtime */
2148 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2149 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2150 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2151 return NT_STATUS_NO_MEMORY;
2157 /* modify the samdb record */
2158 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2160 /* we really need samdb.c to return NTSTATUS */
2161 return NT_STATUS_UNSUCCESSFUL;
2164 return NT_STATUS_OK;
2171 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2172 struct lsa_QuerySecret *r)
2174 struct dcesrv_handle *h;
2175 struct lsa_secret_state *secret_state;
2176 struct ldb_message *msg;
2177 DATA_BLOB session_key;
2178 DATA_BLOB crypt_secret, secret;
2180 struct ldb_message **res;
2181 const char *attrs[] = {
2191 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2193 secret_state = h->data;
2195 /* pull all the user attributes */
2196 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2197 secret_state->secret_dn, &res, attrs);
2199 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2203 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2204 if (!NT_STATUS_IS_OK(nt_status)) {
2208 if (r->in.old_val) {
2209 const struct ldb_val *prior_val;
2210 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2211 if (!r->out.old_val) {
2212 return NT_STATUS_NO_MEMORY;
2215 prior_val = ldb_msg_find_ldb_val(res[0], "priorSecret");
2217 if (prior_val && prior_val->length) {
2218 secret.data = prior_val->data;
2219 secret.length = prior_val->length;
2221 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2222 if (!crypt_secret.length) {
2223 return NT_STATUS_NO_MEMORY;
2225 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2226 if (!r->out.old_val->buf) {
2227 return NT_STATUS_NO_MEMORY;
2229 r->out.old_val->buf->size = crypt_secret.length;
2230 r->out.old_val->buf->length = crypt_secret.length;
2231 r->out.old_val->buf->data = crypt_secret.data;
2235 if (r->in.old_mtime) {
2236 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2237 if (!r->out.old_mtime) {
2238 return NT_STATUS_NO_MEMORY;
2240 *r->out.old_mtime = ldb_msg_find_uint64(res[0], "priorSetTime", 0);
2243 if (r->in.new_val) {
2244 const struct ldb_val *new_val;
2245 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2246 if (!r->out.new_val) {
2247 return NT_STATUS_NO_MEMORY;
2251 new_val = ldb_msg_find_ldb_val(res[0], "secret");
2253 if (new_val && new_val->length) {
2254 secret.data = new_val->data;
2255 secret.length = new_val->length;
2257 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2258 if (!crypt_secret.length) {
2259 return NT_STATUS_NO_MEMORY;
2261 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2262 if (!r->out.new_val->buf) {
2263 return NT_STATUS_NO_MEMORY;
2265 r->out.new_val->buf->length = crypt_secret.length;
2266 r->out.new_val->buf->size = crypt_secret.length;
2267 r->out.new_val->buf->data = crypt_secret.data;
2271 if (r->in.new_mtime) {
2272 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2273 if (!r->out.new_mtime) {
2274 return NT_STATUS_NO_MEMORY;
2276 *r->out.new_mtime = ldb_msg_find_uint64(res[0], "lastSetTime", 0);
2279 return NT_STATUS_OK;
2286 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2287 TALLOC_CTX *mem_ctx,
2288 struct lsa_LookupPrivValue *r)
2290 struct dcesrv_handle *h;
2291 struct lsa_policy_state *state;
2294 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2298 id = sec_privilege_id(r->in.name->string);
2300 return NT_STATUS_NO_SUCH_PRIVILEGE;
2303 r->out.luid->low = id;
2304 r->out.luid->high = 0;
2306 return NT_STATUS_OK;
2313 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2314 TALLOC_CTX *mem_ctx,
2315 struct lsa_LookupPrivName *r)
2317 struct dcesrv_handle *h;
2318 struct lsa_policy_state *state;
2319 const char *privname;
2321 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2325 if (r->in.luid->high != 0) {
2326 return NT_STATUS_NO_SUCH_PRIVILEGE;
2329 privname = sec_privilege_name(r->in.luid->low);
2330 if (privname == NULL) {
2331 return NT_STATUS_NO_SUCH_PRIVILEGE;
2334 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2335 if (r->out.name == NULL) {
2336 return NT_STATUS_NO_MEMORY;
2338 r->out.name->string = privname;
2340 return NT_STATUS_OK;
2345 lsa_LookupPrivDisplayName
2347 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2348 TALLOC_CTX *mem_ctx,
2349 struct lsa_LookupPrivDisplayName *r)
2351 struct dcesrv_handle *h;
2352 struct lsa_policy_state *state;
2355 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2359 id = sec_privilege_id(r->in.name->string);
2361 return NT_STATUS_NO_SUCH_PRIVILEGE;
2364 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2365 if (r->out.disp_name == NULL) {
2366 return NT_STATUS_NO_MEMORY;
2369 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2370 if (r->out.disp_name->string == NULL) {
2371 return NT_STATUS_INTERNAL_ERROR;
2374 return NT_STATUS_OK;
2381 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2382 struct lsa_DeleteObject *r)
2384 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2389 lsa_EnumAccountsWithUserRight
2391 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2392 TALLOC_CTX *mem_ctx,
2393 struct lsa_EnumAccountsWithUserRight *r)
2395 struct dcesrv_handle *h;
2396 struct lsa_policy_state *state;
2398 struct ldb_message **res;
2399 const char * const attrs[] = { "objectSid", NULL};
2400 const char *privname;
2402 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2406 if (r->in.name == NULL) {
2407 return NT_STATUS_NO_SUCH_PRIVILEGE;
2410 privname = r->in.name->string;
2411 if (sec_privilege_id(privname) == -1) {
2412 return NT_STATUS_NO_SUCH_PRIVILEGE;
2415 ret = gendb_search(state->sam_ldb, mem_ctx, samdb_base_dn(mem_ctx), &res, attrs,
2416 "privilege=%s", privname);
2418 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2421 return NT_STATUS_NO_MORE_ENTRIES;
2424 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2425 if (r->out.sids->sids == NULL) {
2426 return NT_STATUS_NO_MEMORY;
2428 for (i=0;i<ret;i++) {
2429 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2430 res[i], "objectSid");
2431 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2433 r->out.sids->num_sids = ret;
2435 return NT_STATUS_OK;
2440 lsa_AddAccountRights
2442 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2443 TALLOC_CTX *mem_ctx,
2444 struct lsa_AddAccountRights *r)
2446 struct dcesrv_handle *h;
2447 struct lsa_policy_state *state;
2449 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2453 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2455 r->in.sid, r->in.rights);
2460 lsa_RemoveAccountRights
2462 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2463 TALLOC_CTX *mem_ctx,
2464 struct lsa_RemoveAccountRights *r)
2466 struct dcesrv_handle *h;
2467 struct lsa_policy_state *state;
2469 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2473 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2474 LDB_FLAG_MOD_DELETE,
2475 r->in.sid, r->in.rights);
2480 lsa_StorePrivateData
2482 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2483 struct lsa_StorePrivateData *r)
2485 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2490 lsa_RetrievePrivateData
2492 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2493 struct lsa_RetrievePrivateData *r)
2495 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2502 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2503 struct lsa_GetUserName *r)
2505 NTSTATUS status = NT_STATUS_OK;
2506 const char *account_name;
2507 const char *authority_name;
2508 struct lsa_String *_account_name;
2509 struct lsa_StringPointer *_authority_name = NULL;
2511 /* this is what w2k3 does */
2512 r->out.account_name = r->in.account_name;
2513 r->out.authority_name = r->in.authority_name;
2515 if (r->in.account_name && r->in.account_name->string) {
2516 return NT_STATUS_INVALID_PARAMETER;
2519 if (r->in.authority_name &&
2520 r->in.authority_name->string &&
2521 r->in.authority_name->string->string) {
2522 return NT_STATUS_INVALID_PARAMETER;
2525 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2526 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2528 _account_name = talloc(mem_ctx, struct lsa_String);
2529 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2530 _account_name->string = account_name;
2532 if (r->in.authority_name) {
2533 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2534 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2535 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2536 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2537 _authority_name->string->string = authority_name;
2540 r->out.account_name = _account_name;
2541 r->out.authority_name = _authority_name;
2549 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2550 TALLOC_CTX *mem_ctx,
2551 struct lsa_SetInfoPolicy2 *r)
2553 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2557 lsa_QueryDomainInformationPolicy
2559 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2560 TALLOC_CTX *mem_ctx,
2561 struct lsa_QueryDomainInformationPolicy *r)
2563 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2567 lsa_SetDomInfoPolicy
2569 static NTSTATUS lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2570 TALLOC_CTX *mem_ctx,
2571 struct lsa_SetDomainInformationPolicy *r)
2573 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2579 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
2580 TALLOC_CTX *mem_ctx,
2581 struct lsa_TestCall *r)
2583 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2587 lookup a SID for 1 name
2589 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
2590 const char *name, struct dom_sid **sid, uint32_t *atype)
2593 struct ldb_message **res;
2594 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
2597 p = strchr_m(name, '\\');
2599 /* TODO: properly parse the domain prefix here, and use it to
2604 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", ldb_binary_encode_string(mem_ctx, name));
2606 *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
2608 return NT_STATUS_INVALID_SID;
2611 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
2613 return NT_STATUS_OK;
2616 /* need to add a call into sidmap to check for a allocated sid */
2618 return NT_STATUS_INVALID_SID;
2625 static NTSTATUS lsa_LookupNames4(struct dcesrv_call_state *dce_call,
2626 TALLOC_CTX *mem_ctx,
2627 struct lsa_LookupNames4 *r)
2629 struct lsa_policy_state *state;
2631 NTSTATUS status = NT_STATUS_OK;
2633 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
2634 if (!NT_STATUS_IS_OK(status)) {
2638 r->out.domains = NULL;
2640 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
2641 if (r->out.domains == NULL) {
2642 return NT_STATUS_NO_MEMORY;
2645 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
2646 if (r->out.sids == NULL) {
2647 return NT_STATUS_NO_MEMORY;
2652 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3,
2654 if (r->out.sids->sids == NULL) {
2655 return NT_STATUS_NO_MEMORY;
2658 for (i=0;i<r->in.num_names;i++) {
2659 const char *name = r->in.names[i].string;
2660 struct dom_sid *sid;
2661 uint32_t atype, rtype, sid_index;
2664 r->out.sids->count++;
2667 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
2668 r->out.sids->sids[i].sid = NULL;
2669 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
2670 r->out.sids->sids[i].unknown = 0;
2672 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
2673 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
2674 status = STATUS_SOME_UNMAPPED;
2678 rtype = samdb_atype_map(atype);
2679 if (rtype == SID_NAME_UNKNOWN) {
2680 status = STATUS_SOME_UNMAPPED;
2684 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
2685 if (!NT_STATUS_IS_OK(status2)) {
2689 r->out.sids->sids[i].sid_type = rtype;
2690 r->out.sids->sids[i].sid = sid;
2691 r->out.sids->sids[i].sid_index = sid_index;
2692 r->out.sids->sids[i].unknown = 0;
2701 static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2702 struct lsa_LookupNames3 *r)
2704 struct lsa_LookupNames4 r2;
2706 struct dcesrv_handle *h;
2707 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2709 r2.in.num_names = r->in.num_names;
2710 r2.in.names = r->in.names;
2711 r2.in.sids = r->in.sids;
2712 r2.in.count = r->in.count;
2713 r2.in.unknown1 = r->in.unknown1;
2714 r2.in.unknown2 = r->in.unknown2;
2715 r2.out.domains = r->out.domains;
2716 r2.out.sids = r->out.sids;
2717 r2.out.count = r->out.count;
2719 status = lsa_LookupNames4(dce_call, mem_ctx, &r2);
2720 if (dce_call->fault_code != 0) {
2724 r->out.domains = r2.out.domains;
2725 r->out.sids = r2.out.sids;
2726 r->out.count = r2.out.count;
2733 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
2734 TALLOC_CTX *mem_ctx,
2735 struct lsa_LookupNames2 *r)
2737 struct lsa_policy_state *state;
2738 struct dcesrv_handle *h;
2740 NTSTATUS status = NT_STATUS_OK;
2742 r->out.domains = NULL;
2744 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2748 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
2749 if (r->out.domains == NULL) {
2750 return NT_STATUS_NO_MEMORY;
2753 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray2);
2754 if (r->out.sids == NULL) {
2755 return NT_STATUS_NO_MEMORY;
2760 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2,
2762 if (r->out.sids->sids == NULL) {
2763 return NT_STATUS_NO_MEMORY;
2766 for (i=0;i<r->in.num_names;i++) {
2767 const char *name = r->in.names[i].string;
2768 struct dom_sid *sid;
2769 uint32_t atype, rtype, sid_index;
2772 r->out.sids->count++;
2775 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
2776 r->out.sids->sids[i].rid = 0xFFFFFFFF;
2777 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
2778 r->out.sids->sids[i].unknown = 0;
2780 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
2781 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
2782 status = STATUS_SOME_UNMAPPED;
2786 rtype = samdb_atype_map(atype);
2787 if (rtype == SID_NAME_UNKNOWN) {
2788 status = STATUS_SOME_UNMAPPED;
2792 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
2793 if (!NT_STATUS_IS_OK(status2)) {
2797 r->out.sids->sids[i].sid_type = rtype;
2798 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
2799 r->out.sids->sids[i].sid_index = sid_index;
2800 r->out.sids->sids[i].unknown = 0;
2809 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2810 struct lsa_LookupNames *r)
2812 struct lsa_LookupNames2 r2;
2816 r2.in.handle = r->in.handle;
2817 r2.in.num_names = r->in.num_names;
2818 r2.in.names = r->in.names;
2820 r2.in.level = r->in.level;
2821 r2.in.count = r->in.count;
2824 r2.out.count = r->out.count;
2826 status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
2827 if (dce_call->fault_code != 0) {
2831 r->out.domains = r2.out.domains;
2832 r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
2833 if (r->out.sids == NULL) {
2834 return NT_STATUS_NO_MEMORY;
2836 r->out.sids->count = r2.out.sids->count;
2837 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid,
2838 r->out.sids->count);
2839 if (r->out.sids->sids == NULL) {
2840 return NT_STATUS_NO_MEMORY;
2842 for (i=0;i<r->out.sids->count;i++) {
2843 r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type;
2844 r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid;
2845 r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index;
2854 static NTSTATUS lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2855 struct lsa_CREDRWRITE *r)
2857 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2864 static NTSTATUS lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2865 struct lsa_CREDRREAD *r)
2867 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2874 static NTSTATUS lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2875 struct lsa_CREDRENUMERATE *r)
2877 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2882 lsa_CREDRWRITEDOMAINCREDENTIALS
2884 static NTSTATUS lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2885 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2887 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2892 lsa_CREDRREADDOMAINCREDENTIALS
2894 static NTSTATUS lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2895 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2897 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2904 static NTSTATUS lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2905 struct lsa_CREDRDELETE *r)
2907 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2912 lsa_CREDRGETTARGETINFO
2914 static NTSTATUS lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2915 struct lsa_CREDRGETTARGETINFO *r)
2917 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2922 lsa_CREDRPROFILELOADED
2924 static NTSTATUS lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2925 struct lsa_CREDRPROFILELOADED *r)
2927 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2932 lsa_CREDRGETSESSIONTYPES
2934 static NTSTATUS lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2935 struct lsa_CREDRGETSESSIONTYPES *r)
2937 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2942 lsa_LSARREGISTERAUDITEVENT
2944 static NTSTATUS lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2945 struct lsa_LSARREGISTERAUDITEVENT *r)
2947 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2952 lsa_LSARGENAUDITEVENT
2954 static NTSTATUS lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2955 struct lsa_LSARGENAUDITEVENT *r)
2957 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2962 lsa_LSARUNREGISTERAUDITEVENT
2964 static NTSTATUS lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2965 struct lsa_LSARUNREGISTERAUDITEVENT *r)
2967 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2972 lsa_LSARQUERYFORESTTRUSTINFORMATION
2974 static NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2975 struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
2977 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2982 lsa_LSARSETFORESTTRUSTINFORMATION
2984 static NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2985 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2987 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2994 static NTSTATUS lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2995 struct lsa_CREDRRENAME *r)
2997 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3003 lsa_LSAROPENPOLICYSCE
3005 static NTSTATUS lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3006 struct lsa_LSAROPENPOLICYSCE *r)
3008 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3013 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3015 static NTSTATUS lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3016 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3018 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3023 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3025 static NTSTATUS lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3026 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3028 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3033 lsa_LSARADTREPORTSECURITYEVENT
3035 static NTSTATUS lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3036 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3038 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3042 /* include the generated boilerplate */
3043 #include "librpc/gen_ndr/ndr_lsa_s.c"